Fix mutable copy of 8bit string ... hope this doesnt break anything, it passes

the testsuite and my apps saeem to run.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22920 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2006-05-12 17:46:32 +00:00
parent a9c025da57
commit 849e0b2af3
2 changed files with 173 additions and 101 deletions

View file

@ -2681,7 +2681,9 @@ transmute(GSStr self, NSString *aString)
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0,
NSDefaultMallocZone());
obj = [obj initWithCString: (char*)_contents.c length: _count];
obj = [obj initWithBytes: (char*)_contents.c
length: _count
encoding: intEnc];
return obj;
}
@ -3562,6 +3564,158 @@ agree, create a new GSUnicodeInlineString otherwise.
return [self initWithCapacity: 0];
}
- (id) initWithBytes: (const void*)bytes
length: (unsigned int)length
encoding: (NSStringEncoding)encoding
{
void *chars = NSZoneMalloc(NSDefaultMallocZone(), length);
memcpy(chars, bytes, length);
return [self initWithBytesNoCopy: chars
length: length
encoding: encoding
freeWhenDone: YES];
}
- (id) initWithBytesNoCopy: (const void*)bytes
length: (unsigned int)length
encoding: (NSStringEncoding)encoding
freeWhenDone: (BOOL)flag
{
BOOL isASCII = NO;
BOOL isLatin1 = NO;
if (encoding != intEnc && GSIsByteEncoding(encoding) == YES)
{
unsigned i;
for (i = 0; i < length; i++)
{
if (((unsigned char*)bytes)[i] > 127)
{
if (encoding == NSASCIIStringEncoding)
{
RELEASE(self);
if (flag == YES && bytes != 0)
{
NSZoneFree(NSZoneFromPointer(bytes), bytes);
}
return nil; // Invalid data
}
break;
}
}
if (i == length)
{
/*
* This is actually ASCII data ... so we can just stor it as if
* in the internal 8bit encoding scheme.
*/
encoding = intEnc;
}
}
if (encoding == intEnc)
{
_count = length;
_capacity = length;
_contents.c = bytes;
_flags.wide = 0;
_flags.free = flag;
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSZoneFromPointer(bytes);
#endif
return self;
}
/*
* Any remaining encoding needs to be converted to UTF-16.
*/
if (encoding != NSUnicodeStringEncoding)
{
unichar *u = 0;
unsigned l = 0;
if (GSToUnicode(&u, &l, (unsigned char*)bytes, length, encoding,
GSObjCZone(self), 0) == NO)
{
RELEASE(self);
if (flag == YES && bytes != 0)
{
NSZoneFree(NSZoneFromPointer(bytes), bytes);
}
return nil; // Invalid data
}
if (flag == YES && bytes != 0)
{
NSZoneFree(NSZoneFromPointer(bytes), bytes);
}
bytes = u;
length = l * sizeof(unichar);
flag = YES;
}
length /= sizeof(unichar);
if (GSUnicode(bytes, length, &isASCII, &isLatin1) != length)
{
RELEASE(self);
if (flag == YES && bytes != 0)
{
NSZoneFree(NSZoneFromPointer(bytes), bytes);
}
return nil; // Invalid data
}
if (isASCII == YES
|| (intEnc == NSISOLatin1StringEncoding && isLatin1 == YES))
{
unsigned char *buf;
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSDefaultMallocZone();
#endif
buf = NSZoneMalloc(_zone, length);
_count = length;
_capacity = length;
_contents.c = buf;
_flags.wide = 0;
_flags.free = 1;
while (length-- > 0)
{
buf[length] = ((unichar*)bytes)[length];
}
if (flag == YES && bytes != 0)
{
NSZoneFree(NSZoneFromPointer(bytes), bytes);
}
}
else
{
_count = length;
_capacity = length;
_contents.u = bytes;
_flags.wide = 1;
if (flag == YES && bytes != 0)
{
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSZoneFromPointer(bytes);
#endif
_flags.free = 1;
}
else
{
_zone = 0;
}
}
return self;
}
- (id) initWithCapacity: (unsigned)capacity
{
if (capacity < 2)
@ -3585,110 +3739,20 @@ agree, create a new GSUnicodeInlineString otherwise.
length: (unsigned int)length
freeWhenDone: (BOOL)flag
{
BOOL isASCII;
BOOL isLatin1;
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
{
RELEASE(self);
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return nil; // Invalid data
}
if (isASCII == YES
|| (intEnc == NSISOLatin1StringEncoding && isLatin1 == YES))
{
unsigned char *buf;
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSDefaultMallocZone();
#endif
buf = NSZoneMalloc(_zone, length);
_count = length;
_capacity = length;
_contents.c = buf;
_flags.wide = 0;
_flags.free = 1;
while (length-- > 0)
{
buf[length] = (unsigned char)chars[length];
}
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
}
else
{
_count = length;
_capacity = length;
_contents.u = chars;
_flags.wide = 1;
if (flag == YES && chars != 0)
{
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSZoneFromPointer(chars);
#endif
_flags.free = 1;
}
else
{
_zone = 0;
}
}
return self;
return [self initWithBytesNoCopy: (void*)chars
length: length*sizeof(unichar)
encoding: NSUnicodeStringEncoding
freeWhenDone: flag];
}
- (id) initWithCStringNoCopy: (char*)chars
length: (unsigned int)length
freeWhenDone: (BOOL)flag
{
if (defEnc != intEnc)
{
unichar *u = 0;
unsigned l = 0;
if (GSToUnicode(&u, &l, (unsigned char*)chars, length, defEnc,
GSObjCZone(self), 0) == NO)
{
DESTROY(self);
}
else
{
self = [self initWithCharactersNoCopy: u length: l freeWhenDone: YES];
}
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return self;
}
if (flag == YES && chars != 0)
{
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSZoneFromPointer(chars);
#endif
_flags.free = 1;
}
else
{
_zone = 0;
}
_count = length;
_capacity = length;
_contents.c = (unsigned char*)chars;
_flags.wide = 0;
return self;
return [self initWithBytesNoCopy: (void*)chars
length: length
encoding: defEnc
freeWhenDone: flag];
}
- (id) initWithFormat: (NSString*)format
@ -3795,7 +3859,9 @@ agree, create a new GSUnicodeInlineString otherwise.
if (_flags.wide == 1)
obj = [obj initWithCharacters: _contents.u length: _count];
else
obj = [obj initWithCString: (char*)_contents.c length: _count];
obj = [obj initWithBytes: (char*)_contents.c
length: _count
encoding: intEnc];
return obj;
}
@ -3808,7 +3874,9 @@ agree, create a new GSUnicodeInlineString otherwise.
if (_flags.wide == 1)
obj = [obj initWithCharacters: _contents.u length: _count];
else
obj = [obj initWithCString: (char*)_contents.c length: _count];
obj = [obj initWithBytes: (char*)_contents.c
length: _count
encoding: intEnc];
return obj;
}