This is NSConcreteString.m in view mode; [Download] [Up]
/* NSConcreteString.m Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. All rights reserved. Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro> This file is part of libFoundation. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. We disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness, in no event shall we be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. */ #include <config.h> #include <ctype.h> #include <Foundation/common.h> #include <Foundation/NSArray.h> #include <Foundation/NSDictionary.h> #include <Foundation/NSData.h> #include <Foundation/NSCoder.h> #include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSException.h> #include <Foundation/exceptions/StringExceptions.h> #include <Foundation/exceptions/GeneralExceptions.h> #include <Foundation/NSCharacterSet.h> #include <Foundation/NSString.h> #include <Foundation/NSConcreteString.h> #include <extensions/objc-runtime.h> /* * Abstract classes for 8 bit strings in the default encoding */ @implementation NS8BitString /* Accessing characters */ - (void)getCharacters:(unichar*)buffer range:(NSRange)aRange { if (aRange.location + aRange.length > [self cStringLength]) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, [self cStringLength]]); { int i = 0; char* bytes = [self __compact8BitBytes]; for (i = 0; i < aRange.length; i++) buffer[i] = bytes[i]; } } /* Dividing strings */ - (NSString*)substringWithRange:(NSRange)aRange { [self subclassResponsibility:_cmd]; return nil; } /* Finding characters and substrings */ - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet*)aSet options:(unsigned int)mask range:(NSRange)aRange { // ENCODINGS - this code applies to the system's default encoding int i = 0; NSRange range = {0, 0}; IMP imp = [aSet methodForSelector:@selector(characterIsMember:)]; char* bytes = [self __compact8BitBytes]; if (aRange.location + aRange.length > [self cStringLength]) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, [self cStringLength]]); if (mask & NSBackwardsSearch) { for (i = aRange.length - 1; i >= 0; i--) { unichar c = bytes[i]; if ((*imp)(aSet, @selector(characterIsMember:), c) || ((mask & NSCaseInsensitiveSearch) && ((islower(c) && (*imp)(aSet, @selector(characterIsMember:), toupper(c))) || (isupper(c) && (*imp)(aSet, @selector(characterIsMember:), tolower(c)))) )) { range.location = aRange.location + i; range.length = 1; return range; } } } else { for (i = 0; i < aRange.length; i++) { unichar c = bytes[i]; if ((*imp)(aSet, @selector(characterIsMember:), c) || ((mask & NSCaseInsensitiveSearch) && ((islower(c) && (*imp)(aSet, @selector(characterIsMember:), toupper(c))) || (isupper(c) && (*imp)(aSet, @selector(characterIsMember:), tolower(c)))) )) { range.location = aRange.location + i; range.length = 1; return range; } } } return range; } - (NSRange)rangeOfString:(NSString*)aString options:(unsigned int)mask range:(NSRange)aRange { // ENCODINGS - this code applies to the system's default encoding NSRange range; char* mbytes; char* abytes; int i, n, a; if (![aString isKindOfClass:[NS8BitString class]] && ![aString isKindOfClass:[NSMutable8BitString class]]) return [super rangeOfString:aString options:mask range:aRange]; if (aRange.location + aRange.length > [self cStringLength]) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, [self cStringLength]]); mbytes = [self __compact8BitBytes] + aRange.location; abytes = [(id)aString __compact8BitBytes]; a = [aString cStringLength]; if (!a || aRange.length < a) { return NSMakeRange(0,0); } if (mask & NSAnchoredSearch) { range.location = aRange.location + ((mask & NSBackwardsSearch) ? aRange.length - a : 0); range.length = a; if ([self compare:aString options:mask range:range] == NSOrderedSame) return range; else return NSMakeRange(0,0); } if (mask & NSBackwardsSearch) { if (mask & NSCaseInsensitiveSearch) { // Backward case insensitive char cf = islower(abytes[0]) ? toupper(abytes[0]) : abytes[0]; for (n = aRange.length-a; n >= 0; n--) { char cm = islower(mbytes[n]) ? toupper(mbytes[n]) : mbytes[n]; char ca = cf; if (cm != ca) continue; for (i = 1; i < a; i++) { cm = islower(mbytes[n+i]) ? toupper(mbytes[n+i]) : mbytes[n+i]; ca = islower(abytes[i]) ? toupper(abytes[i]) : abytes[i]; if (cm != ca) break; } if (i == a) { range.location = aRange.location + n; range.length = a; return range; } } } else { // Backward case sensitive for (n = aRange.length-a; n >= 0; n--) { if (mbytes[n] != abytes[0]) continue; for (i = 1; i < a; i++) if (mbytes[n+i] != abytes[i]) break; if (i == a) { range.location = aRange.location + n; range.length = a; return range; } } } } else { if (mask & NSCaseInsensitiveSearch) { // Forward case insensitive char cf = islower(abytes[0]) ? toupper(abytes[0]) : abytes[0]; for (n = 0; n + a <= aRange.length; n++) { char cm = islower(mbytes[n]) ? toupper(mbytes[n]) : mbytes[n]; char ca = cf; if (cm != ca) continue; for (i = 1; i < a; i++) { cm = islower(mbytes[n+i]) ? toupper(mbytes[n+i]) : mbytes[n+i]; ca = islower(abytes[i]) ? toupper(abytes[i]) : abytes[i]; if (cm != ca) break; } if (i == a) { range.location = aRange.location + n; range.length = a; return range; } } } else { // Forward case sensitive for (n = 0; n + a <= aRange.length; n++) { if (mbytes[n] != abytes[0]) continue; for (i = 1; i < a; i++) if (mbytes[n+i] != abytes[i]) break; if (i == a) { range.location = aRange.location + n; range.length = a; return range; } } } } range.location = range.length = 0; return range; } - (NSComparisonResult)compare:(NSString*)aString options:(unsigned int)mask range:(NSRange)aRange { // ENCODINGS - this code applies to the system's default encoding char* mbytes; char* abytes; int i, n, a; if (![aString isKindOfClass:[NS8BitString class]] && ![aString isKindOfClass:[NSMutable8BitString class]]) return [super compare:aString options:mask range:aRange]; if (aRange.location + aRange.length > [self cStringLength]) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, [self cStringLength]]); mbytes = [self __compact8BitBytes] + aRange.location; abytes = [(id)aString __compact8BitBytes]; a = [aString cStringLength]; n = MIN(a, aRange.length); if (mask & NSCaseInsensitiveSearch) { for (i = 0; i < n; i++) { char cm = islower(mbytes[i]) ? toupper(mbytes[i]) : mbytes[i]; char ca = islower(abytes[i]) ? toupper(abytes[i]) : abytes[i]; if (cm < ca) return NSOrderedAscending; if (cm > ca) return NSOrderedDescending; } } else { for (i = 0; i < n; i++) { if (mbytes[i] < abytes[i]) return NSOrderedAscending; if (mbytes[i] > abytes[i]) return NSOrderedDescending; } } if (aRange.length < a) return NSOrderedAscending; if (aRange.length > a) return NSOrderedDescending; return NSOrderedSame; } - (unsigned int)hash { char* bytes = [self __compact8BitBytes]; unsigned hash = 0, hash2; int i, n = [self cStringLength]; for(i=0; i < n; i++) { hash <<= 4; // UNICODE - must use a for independent of composed characters hash += bytes[i]; if((hash2 = hash & 0xf0000000)) hash ^= (hash2 >> 24) ^ hash2; } return hash; } /* Getting a shared prefix */ - (NSString*)commonPrefixWithString:(NSString*)aString options:(unsigned int)mask { // ENCODINGS - this code applies to the system's default encoding NSRange range = {0, 0}; char* mbytes; char* abytes; int mLen; int aLen; int i; if (![aString isKindOfClass:[NS8BitString class]] && ![aString isKindOfClass:[NSMutable8BitString class]]) return [super commonPrefixWithString:aString options:mask]; mLen = [self cStringLength]; aLen = [aString length]; mbytes = [self __compact8BitBytes]; abytes = [self __compact8BitBytes]; for (i = 0; i < mLen && i < aLen; i++) { char c1 = mbytes[i]; char c2 = abytes[i]; if ((c1 != c2) && ((mask & NSCaseInsensitiveSearch) && ( (islower(c1) && (toupper(c1) != c2)) && (islower(c2) && (toupper(c2) != c1))))) break; } range.length = i; return [self substringWithRange:range]; } /* Changing case */ - (NSString*)capitalizedString { // ENCODINGS - this code applies to the system's default encoding int i; BOOL f = YES; int length = [self cStringLength]; char* bytes = [self __compact8BitBytes]; char* chars = Malloc(sizeof(unichar)*(length+1)); for (i = 0; i < length; i++) { char c = bytes[i]; if (isspace(c)) f = YES; if (f) { chars[i] = islower(c) ? toupper(c) : c; f = NO; } else chars[i] = isupper(c) ? tolower(c) : c; } chars[i] = 0; return [[[NSOwned8BitString alloc] initWithCString:chars length:length copy:NO] autorelease]; } - (NSString*)lowercaseString { // ENCODINGS - this code applies to the system's default encoding int i; int length = [self cStringLength]; char* bytes = [self __compact8BitBytes]; char* chars = Malloc(sizeof(unichar)*(length+1)); for (i = 0; i < length; i++) { char c = bytes[i]; chars[i] = isupper(c) ? tolower(c) : c; } chars[i] = 0; return [[[NSOwned8BitString alloc] initWithCString:chars length:length copy:NO] autorelease]; } - (NSString*)uppercaseString { // ENCODINGS - this code applies to the system's default encoding int i; int length = [self cStringLength]; char* bytes = [self __compact8BitBytes]; char* chars = Malloc(sizeof(unichar)*(length+1)); for (i = 0; i < length; i++) { char c = bytes[i]; chars[i] = islower(c) ? toupper(c) : c; } chars[i] = 0; return [[[NSOwned8BitString alloc] initWithCString:chars length:length copy:NO] autorelease]; } /* Working with C strings */ - (void)getCString:(char*)buffer maxLength:(unsigned int)maxLength range:(NSRange)aRange remainingRange:(NSRange*)leftoverRange { char* bytes = [self __compact8BitBytes]; unsigned int toMove = MIN(maxLength, aRange.length); unsigned int cLength = [self cStringLength]; if (aRange.location + aRange.length > cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, cLength]); if (leftoverRange) { leftoverRange->location = aRange.location + toMove; leftoverRange->length = cLength - leftoverRange->location; } memcpy(buffer, bytes+aRange.location, toMove); } - (BOOL)writeToFile:(NSString*)path atomically:(BOOL)flag { // UNICODE - remove this NSData* data = [NSData dataWithBytes:[self cString] length:[self cStringLength]]; return writeToFile(path, data, flag); } - (Class)classForCoder { return [NS8BitString class]; } - (void)encodeWithCoder:(NSCoder*)aCoder { const char* bytes = [self __compact8BitBytes]; int length = [self cStringLength]; [aCoder encodeValueOfObjCType:@encode(int) at:&length]; [aCoder encodeArrayOfObjCType:@encode(char) count:length at:bytes]; } - (id)initWithCoder:(NSCoder*)aDecoder { char* bytes; int length; [aDecoder decodeValueOfObjCType:@encode(int) at:&length]; bytes = Malloc (length); [aDecoder decodeArrayOfObjCType:@encode(char) count:length at:bytes]; return [[[NSOwned8BitString alloc] initWithCString:bytes length:length copy:NO] autorelease]; } static NSString* quoteString (NSString* string) { NSArray* components = [string componentsSeparatedByString:@"\""]; NSMutableString* result = [NSMutableString stringWithCString:"\""]; [result appendString:[components componentsJoinedByString:@"\\\""]]; [result appendString:@"\""]; return [[result copy] autorelease]; } - (NSString*)stringRepresentation { const char* cString = [self __compact8BitBytes]; int i, length = [self cStringLength]; if(!cString || (cString && *cString == 0)) return @"\"\""; /* Check if the string can be parsed as a STRING token by the property list parser. Otherwise we must enclose it in double quotes. */ if (!isalnum(cString[0]) && cString[0] != '_' && cString[0] != '@' && cString[0] != '#') return quoteString (self); for(i = 1; i < length; i++) if (!isalnum(cString[i]) && cString[i] != '_' && cString[i] != '@' && cString[i] != '#' && cString[i] != '$' && cString[i] != '.') return quoteString (self); return self; } - (id)copyWithZone:(NSZone*)zone { int length; if (NSShouldRetainWithZone(self, zone)) return [self retain]; length = [self cStringLength]; return [[NSInline8BitString allocForCapacity:length zone:zone] initWithCString:[self __compact8BitBytes] length:length]; } - (id)mutableCopyWithZone:(NSZone*)zone { return [[NSMutableSimple8BitString allocWithZone:zone] initWithCString:[self __compact8BitBytes] length:[self cStringLength] copy:YES]; } @end /* NS8BitString */ @implementation NSMutable8BitString + (void)initialize { static BOOL initialized = NO; if(!initialized) { // THREAD initialized = YES; class_add_behavior(self, [NS8BitString class]); } } - initWithString:(NSString*)aString { if (![aString isKindOfClass:[NS8BitString class]] && ![aString isKindOfClass:[NSMutable8BitString class]]) return [super initWithString:(NSString*)aString]; return [self initWithCString:[(id)aString __compact8BitBytes] length:[aString cStringLength] copy:YES]; } - initWithContentsOfFile:(NSString*)path { int fd = open([path cString], O_RDONLY); struct stat fstat_buf; char* bytes = NULL; if((fd == -1) || (fstat(fd, &fstat_buf) == -1)) return nil; bytes = NSZoneMalloc([self zone], fstat_buf.st_size + 1); if (read(fd, bytes, fstat_buf.st_size) != fstat_buf.st_size) { Free(bytes); return nil; } close(fd); bytes[fstat_buf.st_size]=0; [self initWithCString:bytes length:fstat_buf.st_size copy:NO]; return self; } - (id)copyWithZone:(NSZone*)zone { int length = [self cStringLength]; return [[NSInline8BitString allocForCapacity:length zone:zone] initWithCString:[self __compact8BitBytes] length:length]; } - (Class)classForCoder { return [NSMutable8BitString class]; } - (id)initWithCoder:(NSCoder*)aDecoder { char* bytes; int length; [aDecoder decodeValueOfObjCType:@encode(int) at:&length]; bytes = Malloc (length); [aDecoder decodeArrayOfObjCType:@encode(char) count:length at:bytes]; return [[[NSMutableSimple8BitString alloc] initWithCString:bytes length:length copy:NO] autorelease]; } @end /* NSMutable8BitString */ /* * Null terminated CString containing characters inline */ @implementation NSInline8BitString + allocForCapacity:(unsigned int)capacity zone:(NSZone*)zone { NSInline8BitString* str = NSAllocateObject(self, capacity, zone); str->cLength = -1; return str; } - init { if (cLength != -1) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cLength = 0; cString[0] = 0; return self; } - initWithCString:(const char*)byteString length:(unsigned int)length { if (cLength != -1) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cLength = length; memcpy(cString, byteString, length); cString[length] = 0; return self; } - (void)dealloc { [super dealloc]; } - (const char*)cString { return cString; } - (unsigned int)cStringLength { return (cLength == -1) ? 0 : cLength; } - (unsigned int)length { return (cLength == -1) ? 0 : cLength; } - (unichar)characterAtIndex:(unsigned int)index { if (cLength == -1 || index >= cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"index %d out of range in string %x of length %d", index, self, cLength]); // ENCODING return cString[index]; } - (NSString*)substringWithRange:(NSRange)aRange { if (aRange.location + aRange.length > cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, cLength]); if (aRange.length == 0) return @""; return [[[NSRange8BitString alloc] initWithString:self bytes:cString+aRange.location length:aRange.length] autorelease]; } - (char*)__compact8BitBytes { return cString; } @end /* NSInline8BitString */ /* * String containing non-owned, zero termintated c-string */ @implementation NSNonOwned8BitString - init { if (cLength || cString) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cLength = 0; cString = ""; return self; } - initWithCString:(char*)byteString length:(unsigned int)length copy:(BOOL)flag { if (cLength || cString) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); if (flag) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s with flag set to YES to %@ to instance", sel_get_name(_cmd), NSStringFromClass([self class])]); cLength = length; cString = byteString; return self; } - (const char*)cString { return cString; } - (unsigned int)cStringLength { return cLength; } - (unsigned int)length { return cLength; } - (unichar)characterAtIndex:(unsigned int)index { if (cLength == -1 || index >= cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"index %d out of range in string %x of length %d", index, self, cLength]); // ENCODING return cString[index]; } - (NSString*)substringWithRange:(NSRange)aRange { if (aRange.location + aRange.length > cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, cLength]); if (aRange.length == 0) return @""; return [[[NSRange8BitString alloc] initWithString:self bytes:cString+aRange.location length:aRange.length] autorelease]; } - (char*)__compact8BitBytes { return cString; } @end /* NSNonOwned8BitString */ @implementation NSOwned8BitString - init { if (cLength || cString) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cLength = 0; cString = NSZoneMalloc([self zone], sizeof(char)); cString[0] = 0; return self; } - initWithCString:(char*)byteString length:(unsigned int)length copy:(BOOL)flag { if (cLength || cString) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cLength = length; if (flag) { cString = NSZoneMalloc([self zone], sizeof(char)*(length+1)); memcpy(cString, byteString, length); cString[cLength] = 0; } else cString = byteString; return self; } - (void)dealloc { Free(cString); [super dealloc]; } @end /* NSOwned8BitString */ @implementation NXConstantString - (oneway void)release { } - retain { return self; } - (unsigned)retainCount { return 1; } - autorelease { return self; } - (void)dealloc { [self shouldNotImplement:_cmd]; } @end /* NXConstantString */ @implementation NSNonOwnedOpen8BitString - (const char*)cString { char* str = NSZoneMalloc([self zone], sizeof(char)*(cLength + 1)); memcpy(str, cString, cLength); str[cLength] = 0; [NSAutoreleasedPointer autoreleasePointer:str]; return str; } @end /* NSNonOwnedOpen8BitString */ @implementation NSOwnedOpen8BitString - initWithCString:(char*)byteString length:(unsigned int)length copy:(BOOL)flag { if (cLength || cString) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cLength = length; if (flag) { cString = NSZoneMalloc([self zone], sizeof(char)*(length)); memcpy(cString, byteString, length); } else cString = byteString; return self; } - (const char*)cString { char* str = Malloc(sizeof(char)*(cLength + 1)); memcpy(str, cString, cLength); str[cLength] = 0; [NSAutoreleasedPointer autoreleasePointer:str]; return str; } @end /* NSOwnedOpen8BitString */ @implementation NSRange8BitString - initWithString:(NSString*)aParent bytes:(char*)bytes length:(unsigned int)length { if (cLength || cString) THROW([[InvalidUseOfMethodException alloc] initWithFormat: @"cannot send %s to non-mutable instance", sel_get_name(_cmd)]); cString = bytes; cLength = length; parent = [aParent retain]; return self; } - (void)dealloc { [parent release]; [super dealloc]; } - (NSString*)substringWithRange:(NSRange)aRange { if (aRange.location + aRange.length > cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, cLength]); if (aRange.length == 0) return @""; return [[[NSRange8BitString alloc] initWithString:parent bytes:cString+aRange.location length:aRange.length] autorelease]; } @end /* NSRange8BitString */ @implementation NSMutableSimple8BitString - init { cLength = 0; return self; } - initWithCapacity:(unsigned int)capacity { cLength = 0; cCapacity = capacity; Free(cString); cString = NSZoneMalloc([self zone], sizeof(char)*capacity); return self; } - initWithCString:(char*)byteString length:(unsigned int)length copy:(BOOL)flag { if (flag) { if (cCapacity < length) { Free(cString); cString = NSZoneMalloc([self zone], sizeof(char)*length); cCapacity = length; } cLength = length; memcpy(cString, byteString, length); } else { Free(cString); cString = byteString; cLength = cCapacity = length; } return self; } - (void)dealloc { Free(cString); [super dealloc]; } - (const char*)cString { char* str = Malloc(sizeof(char)*(cLength + 1)); memcpy(str, cString, cLength); str[cLength] = 0; [NSAutoreleasedPointer autoreleasePointer:str]; return str; } - (unsigned int)cStringLength { return cLength; } - (unsigned int)length { return cLength; } - (unichar)characterAtIndex:(unsigned int)index { if (index >= cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"index %d out of range in string %x of length %d", index, self, cLength]); // ENCODING return cString[index]; } - (NSString*)substringWithRange:(NSRange)aRange { if (aRange.location + aRange.length > cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, cLength]); if (aRange.length == 0) return @""; return [[[NSInline8BitString allocForCapacity:aRange.length zone:NULL] initWithCString:cString+aRange.location length:aRange.length] autorelease]; } - (char*)__compact8BitBytes { return cString; } - (void)replaceCharactersInRange:(NSRange)aRange withString:(NSString*)aString { int strLength, i, iFrom, iTo, count; /* check range */ if (aRange.location + aRange.length > cLength) THROW([[IndexOutOfRangeException alloc] initWithFormat:@"range (%d,%d) in string %x of length %d", aRange.location, aRange.length, self, cLength]); strLength = [aString cStringLength]; /* if range is smaller than new string enough room */ if (aRange.length >= strLength) { iFrom = aRange.location + aRange.length; iTo = aRange.location + strLength; count = cLength - iFrom; if (iFrom != iTo) for (i = 0; i < count; i++) cString[iTo + i] = cString[iFrom + i]; cLength = cLength - aRange.length + strLength; } /* if range greater than new string */ else { /* is there enough free space */ if ((cCapacity - cLength) < (strLength - aRange.length)) { /* reallocation grow strategy */ cCapacity += MAX(cCapacity, (strLength - aRange.length) - (cCapacity - cLength)); cString = NSZoneRealloc( cString ? NSZoneFromPointer(cString) : [self zone], cString, sizeof(char)*cCapacity); } /* we have enough size */ count = cLength - aRange.location - aRange.length; iFrom = cLength - 1; iTo = cLength + strLength - aRange.length - 1; cLength += strLength - aRange.length; for (i = 0; i < count; i++) cString[iTo - i] = cString[iFrom - i]; } /* move string in its position */ if (strLength) { NSRange range = {0, strLength}; [aString getCString:cString + aRange.location maxLength:strLength range:range remainingRange:NULL]; } } @end /* NSMutableSimple8BitString */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.