* Source/GSPrivate.h (GSCharPtr): New union type to handle

alignment issues.
	(GSString): Use it.
	* Source/GSString.m
	([-initWithBytesNoCopy:length:encoding:freeWhenDone:]): Use GSCharPtr
	instead of casts to avoid alignment issues.  Fix typo's.

	* Source/NSString.m
	([-initWithBytesNoCopy:length:encoding:freeWhenDone:]): Correct grammar
	in comment.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23009 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ayers 2006-05-30 11:19:44 +00:00
parent 7a07d80acc
commit b3c9994d61
4 changed files with 51 additions and 25 deletions

View file

@ -1,3 +1,16 @@
2006-05-30 David Ayers <d.ayers@inode.at>
* Source/GSPrivate.h (GSCharPtr): New union type to handle
alignment issues.
(GSString): Use it.
* Source/GSString.m
([-initWithBytesNoCopy:length:encoding:freeWhenDone:]): Use GSCharPtr
instead of casts to avoid alignment issues. Fix typo's.
* Source/NSString.m
([-initWithBytesNoCopy:length:encoding:freeWhenDone:]): Correct grammar
in comment.
2006-05-30 Richard Frith-Macdonald <rfm@gnu.org> 2006-05-30 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/Unicode.m: Use 'goto' to jump to 'done' label on * Source/Additions/Unicode.m: Use 'goto' to jump to 'done' label on

View file

@ -111,6 +111,15 @@ GS_EXPORT NSString *GSEncodingName(NSStringEncoding encoding);
*/ */
GS_EXPORT BOOL GSIsByteEncoding(NSStringEncoding encoding); GS_EXPORT BOOL GSIsByteEncoding(NSStringEncoding encoding);
/*
* Type to hold either UTF-16 (unichar) or 8-bit encodings,
* while satisfying alignment constraints.
*/
typedef union {
unichar *u; // 16-bit unicode characters.
unsigned char *c; // 8-bit characters.
} GSCharPtr;
/* /*
* Private concrete string classes. * Private concrete string classes.
* NB. All these concrete string classes MUST have the same initial ivar * NB. All these concrete string classes MUST have the same initial ivar
@ -121,10 +130,7 @@ GS_EXPORT BOOL GSIsByteEncoding(NSStringEncoding encoding);
*/ */
@interface GSString : NSString @interface GSString : NSString
{ {
union { GSCharPtr _contents;
unichar *u; // 16-bit unicode characters.
unsigned char *c; // 8-bit characters.
} _contents;
unsigned int _count; unsigned int _count;
struct { struct {
unsigned int wide: 1; // 16-bit characters in string? unsigned int wide: 1; // 16-bit characters in string?

View file

@ -470,7 +470,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
freeWhenDone: (BOOL)flag freeWhenDone: (BOOL)flag
{ {
extern BOOL GSEncodingSupported(NSStringEncoding enc); extern BOOL GSEncodingSupported(NSStringEncoding enc);
unsigned char *chars = 0; GSCharPtr chars = { .u = 0 };
BOOL isASCII = NO; BOOL isASCII = NO;
BOOL isLatin1 = NO; BOOL isLatin1 = NO;
GSStr me; GSStr me;
@ -487,7 +487,14 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
if (length > 0) if (length > 0)
{ {
fixBOM((unsigned char**)&bytes, &length, &flag, encoding); fixBOM((unsigned char**)&bytes, &length, &flag, encoding);
chars = (unsigned char*)bytes; if (encoding == NSUnicodeStringEncoding)
{
chars.u = bytes;
}
else
{
chars.c = bytes;
}
} }
if (encoding != internalEncoding && GSIsByteEncoding(encoding) == YES) if (encoding != internalEncoding && GSIsByteEncoding(encoding) == YES)
@ -496,13 +503,13 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
if (((unsigned char*)chars)[i] > 127) if ((chars.c)[i] > 127)
{ {
if (encoding == NSASCIIStringEncoding) if (encoding == NSASCIIStringEncoding)
{ {
if (flag == YES && chars != 0) if (flag == YES && chars.c != 0)
{ {
NSZoneFree(NSZoneFromPointer(chars), chars); NSZoneFree(NSZoneFromPointer(chars.c), chars.c);
} }
return nil; // Invalid data return nil; // Invalid data
} }
@ -512,7 +519,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
if (i == length) if (i == length)
{ {
/* /*
* This is actually ASCII data ... so we can just stor it as if * This is actually ASCII data ... so we can just store it as if
* in the internal 8bit encoding scheme. * in the internal 8bit encoding scheme.
*/ */
encoding = internalEncoding; encoding = internalEncoding;
@ -522,7 +529,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
if (encoding == internalEncoding) if (encoding == internalEncoding)
{ {
me = (GSStr)NSAllocateObject(GSCBufferStringClass, 0, GSObjCZone(self)); me = (GSStr)NSAllocateObject(GSCBufferStringClass, 0, GSObjCZone(self));
me->_contents.c = (unsigned char*)chars; me->_contents.c = chars.c;
me->_count = length; me->_count = length;
me->_flags.wide = 0; me->_flags.wide = 0;
me->_flags.free = flag; me->_flags.free = flag;
@ -537,30 +544,30 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
unichar *u = 0; unichar *u = 0;
unsigned l = 0; unsigned l = 0;
if (GSToUnicode(&u, &l, (unsigned char*)chars, length, encoding, if (GSToUnicode(&u, &l, chars.c, length, encoding,
GSObjCZone(self), 0) == NO) GSObjCZone(self), 0) == NO)
{ {
if (flag == YES && chars != 0) if (flag == YES && chars.c != 0)
{ {
NSZoneFree(NSZoneFromPointer(chars), chars); NSZoneFree(NSZoneFromPointer(chars.c), chars.c);
} }
return nil; // Invalid data return nil; // Invalid data
} }
if (flag == YES && chars != 0) if (flag == YES && chars.c != 0)
{ {
NSZoneFree(NSZoneFromPointer(chars), chars); NSZoneFree(NSZoneFromPointer(chars.c), chars.c);
} }
chars = (unsigned char*)u; chars.u = u;
length = l * sizeof(unichar); length = l * sizeof(unichar);
flag = YES; flag = YES;
} }
length /= sizeof(unichar); length /= sizeof(unichar);
if (GSUnicode((unichar*)chars, length, &isASCII, &isLatin1) != length) if (GSUnicode(chars.u, length, &isASCII, &isLatin1) != length)
{ {
if (flag == YES && chars != 0) if (flag == YES && chars.u != 0)
{ {
NSZoneFree(NSZoneFromPointer(chars), chars); NSZoneFree(NSZoneFromPointer(chars.u), chars.u);
} }
return nil; // Invalid data return nil; // Invalid data
} }
@ -576,18 +583,18 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
while (length-- > 0) while (length-- > 0)
{ {
me->_contents.c[length] = ((unichar*)chars)[length]; me->_contents.c[length] = chars.u[length];
} }
if (flag == YES && chars != 0) if (flag == YES && chars.u != 0)
{ {
NSZoneFree(NSZoneFromPointer(chars), chars); NSZoneFree(NSZoneFromPointer(chars.u), chars.u);
} }
} }
else else
{ {
me = (GSStr)NSAllocateObject(GSUnicodeBufferStringClass, me = (GSStr)NSAllocateObject(GSUnicodeBufferStringClass,
0, GSObjCZone(self)); 0, GSObjCZone(self));
me->_contents.u = (unichar*)chars; me->_contents.u = chars.u;
me->_count = length; me->_count = length;
me->_flags.wide = 1; me->_flags.wide = 1;
me->_flags.free = flag; me->_flags.free = flag;

View file

@ -894,7 +894,7 @@ handle_printf_atsign (FILE *stream,
* is released and nil is returned. * is released and nil is returned.
* <p>Note, this is the most basic initialiser for strings. * <p>Note, this is the most basic initialiser for strings.
* In the GNUstep implementation, your subclasses may override * In the GNUstep implementation, your subclasses may override
* this initialiser in order to have all others function.</p> * this initialiser in order to have all other functionality.</p>
*/ */
- (id) initWithBytesNoCopy: (void*)bytes - (id) initWithBytesNoCopy: (void*)bytes
length: (unsigned int)length length: (unsigned int)length