|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.0 (the 'License'). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License." ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* ! 25: NXSimpleReadOnlyString.m ! 26: Copyright 1991, NeXT, Inc. ! 27: Responsibility: ! 28: */ ! 29: ! 30: #ifndef KERNEL ! 31: #ifdef SHLIB ! 32: #import "shlib.h" ! 33: #endif SHLIB ! 34: ! 35: #import "NXStringPrivate.h" ! 36: ! 37: @implementation NXSimpleReadOnlyString ! 38: ! 39: - initFromCharactersNoCopy:(unichar *)chars length:(unsigned)len ! 40: { ! 41: [super initFromCharactersNoCopy:chars length:len]; ! 42: characters = (unichar *)chars; ! 43: _length = len; ! 44: return self; ! 45: } ! 46: ! 47: - (unichar)characterAt:(unsigned)loc ! 48: { ! 49: if (loc >= _length) BOUNDSERROR; ! 50: return characters[loc]; ! 51: } ! 52: ! 53: - (unsigned)length ! 54: { ! 55: return _length; ! 56: } ! 57: ! 58: - (void)getCharacters:(unichar *)buffer range:(NXRange)range ! 59: { ! 60: if (RNGLOC(range) + RNGLEN(range) > _length) BOUNDSERROR; ! 61: NX_CHARCOPY(characters + RNGLOC(range), buffer, RNGLEN(range)); ! 62: } ! 63: ! 64: - (void)getCString:(char *)buffer maxLength:(unsigned)bytes range:(NXRange)range remainingRange:(NXRange *)leftover ! 65: { ! 66: #if CHARS_ARE_EIGHT_BIT ! 67: NXRange desiredRange = range; ! 68: unsigned cnt; ! 69: if (RNGLOC(range) + RNGLEN(range) > _length) BOUNDSERROR; ! 70: if (RNGLEN(range) > bytes) RNGLEN(range) = bytes; ! 71: for (cnt = 0; cnt < RNGLEN(range); cnt++) { ! 72: unichar ch = characters[RNGLOC(range) + cnt]; ! 73: buffer[cnt] = (ch > 0x0ff) ? NX_UNREPRESENTABLE_CHARACTER : ch; ! 74: } ! 75: buffer[RNGLEN(range)] = 0; ! 76: if (leftover) { ! 77: RNGLOC(*leftover) = RNGLOC(desiredRange) + RNGLEN(range); ! 78: RNGLEN(*leftover) = RNGLEN(desiredRange) - RNGLEN(range); ! 79: } ! 80: #else ! 81: #warning getCString:maxLength:range:remainingRange: not implemented for Unicode ! 82: _NXStringErrorRaise (NXStringInternalError, "getCString:maxLength:range:remainingRange: not implemented for Unicode"); ! 83: #endif ! 84: } ! 85: ! 86: - (NXComparisonResult)compare:string mask:(unsigned int)options table:(void *)table ! 87: { ! 88: unsigned ownLength = [self length], otherLength = [string length]; ! 89: static Class simpleReadOnlyStringClass = Nil; ! 90: ! 91: if (simpleReadOnlyStringClass == Nil) simpleReadOnlyStringClass = [NXSimpleReadOnlyString class]; ! 92: ! 93: if ([string isKindOf:simpleReadOnlyStringClass]) { ! 94: return NXCompareCharacters(characters, ((NXSimpleReadOnlyString *)string)->characters, ownLength, otherLength, options, NULL); ! 95: } else { ! 96: unichar otherBuffer[COMPARELENGTH]; ! 97: NXRange ownRange = {0, 0}, otherRange = {0, 0}; ! 98: NXComparisonResult res = NX_OrderedSame; ! 99: while (1) { ! 100: RNGLEN(ownRange) = MIN(ownLength - RNGLOC(ownRange), COMPARELENGTH); ! 101: RNGLEN(otherRange) = MIN(otherLength - RNGLOC(otherRange), COMPARELENGTH); ! 102: if (RNGLEN(ownRange) == 0 && RNGLEN(otherRange) == 0) return NX_OrderedSame; ! 103: [string getCharacters:otherBuffer range:otherRange]; ! 104: if ((res = NXCompareCharacters(characters + RNGLOC(ownRange), otherBuffer, RNGLEN(ownRange), RNGLEN(otherRange), options, NULL)) != NX_OrderedSame) return res; ! 105: RNGLOC(ownRange) += RNGLEN(ownRange); ! 106: RNGLOC(otherRange) += RNGLEN(otherRange); ! 107: } ! 108: } ! 109: } ! 110: ! 111: - (NXRange)findString:(NXString *)findStr range:(NXRange)fRange mask:(unsigned int)options table:(void *)table ! 112: { ! 113: unsigned findStrLen = [findStr length]; // fromLoc and toLoc are inclusive ! 114: NXRange range = {NX_STRING_NOT_FOUND, 0}; ! 115: unichar tmpBuf[MAXTMPBUFFERLEN], *findBuf; ! 116: ! 117: if (RNGLOC(fRange) + RNGLEN(fRange) > _length) BOUNDSERROR; ! 118: ! 119: if (findStrLen > RNGLEN(fRange)) { // ??? This can't be here for correct Unicode compares ! 120: return range; ! 121: } ! 122: ! 123: findBuf = (findStrLen > MAXTMPBUFFERLEN) ? NX_CHARALLOC(NXDefaultMallocZone(), findStrLen) : tmpBuf; ! 124: [findStr getCharacters:findBuf]; ! 125: ! 126: range = NXFindCharacters (findBuf, characters + RNGLOC(fRange), findStrLen, RNGLEN(fRange), options, table); ! 127: ! 128: if (RNGLOC(range) != NX_STRING_NOT_FOUND) { ! 129: RNGLOC(range) += RNGLOC(fRange); ! 130: } ! 131: ! 132: if (findBuf != tmpBuf) { ! 133: free(findBuf); ! 134: } ! 135: ! 136: return range; ! 137: } ! 138: ! 139: - (unsigned)findCharacter:(unichar)ch range:(NXRange)fRange mask:(unsigned int)options table:(void *)table ! 140: { ! 141: NXRange range; ! 142: ! 143: if (RNGLOC(fRange) + RNGLEN(fRange) > _length) BOUNDSERROR; ! 144: ! 145: range = NXFindCharacters (&ch, characters + RNGLOC(fRange), 1, RNGLEN(fRange), options, table); ! 146: ! 147: return RNGLOC(range) + ((RNGLOC(range) != NX_STRING_NOT_FOUND) ? RNGLOC(fRange) : 0); ! 148: } ! 149: ! 150: - (unsigned)findOneOf:(NXCharacterSet *)set range:(NXRange)fRange mask:(unsigned int)options table:(void *)table ! 151: { ! 152: int step; ! 153: unsigned fromLoc, toLoc, cnt; // fromLoc and toLoc are inclusive ! 154: BOOL found = NO, done = NO; ! 155: ! 156: if (RNGLOC(fRange) + RNGLEN(fRange) > _length) BOUNDSERROR; ! 157: ! 158: if (options & NX_BACKWARDS_SEARCH) { ! 159: fromLoc = RNGLOC(fRange) + RNGLEN(fRange) - 1; ! 160: toLoc = RNGLOC(fRange); ! 161: } else { ! 162: fromLoc = RNGLOC(fRange); ! 163: toLoc = RNGLOC(fRange) + RNGLEN(fRange) - 1; ! 164: } ! 165: ! 166: step = (fromLoc <= toLoc) ? 1 : -1; ! 167: cnt = fromLoc; ! 168: ! 169: do { ! 170: if ([set characterIsMember:characters[cnt]]) { ! 171: done = found = YES; ! 172: } else if (cnt == toLoc) { ! 173: done = YES; ! 174: } else { ! 175: cnt += step; ! 176: } ! 177: } while (!done); ! 178: ! 179: return found ? cnt : NX_STRING_NOT_FOUND; ! 180: } ! 181: ! 182: - (NXString *)copySubstring:(NXRange)range fromZone:(NXZone *)zone ! 183: { ! 184: if (RNGLOC(range) + RNGLEN(range) > _length) BOUNDSERROR; ! 185: if (RNGLOC(range) == 0 && RNGLEN(range) == _length) { ! 186: return [[self class] copyFromZone:zone]; ! 187: } else { ! 188: return [[[self class] allocFromZone:zone] initFromCharacters:characters + RNGLOC(range) length:RNGLEN(range)]; ! 189: } ! 190: } ! 191: ! 192: - (unsigned)hash ! 193: { ! 194: return NXHashCharacters(characters, [self length]); ! 195: } ! 196: ! 197: - copyFromZone:(NXZone *)zone ! 198: { ! 199: NXSimpleReadOnlyString *newInstance = [super copyFromZone:zone]; ! 200: newInstance->_length = _length; ! 201: newInstance->characters = [newInstance allocateCharacterBuffer:_length]; ! 202: NX_CHARCOPY(characters, newInstance->characters, _length); ! 203: return newInstance; ! 204: } ! 205: ! 206: - free ! 207: { ! 208: if (characters) { ! 209: free (characters); ! 210: } ! 211: return [super free]; ! 212: } ! 213: ! 214: - write:(NXTypedStream *)s ! 215: { ! 216: [super write:s]; ! 217: NXWriteType (s, "i", &_length); ! 218: if (_length > 0) { ! 219: NXWriteArray (s, DATATYPEFORCHAR, _length, characters); ! 220: } ! 221: return self; ! 222: } ! 223: ! 224: - read:(NXTypedStream *)s ! 225: { ! 226: [super read:s]; ! 227: NXReadType (s, "i", &_length); ! 228: if (_length > 0) { ! 229: characters = [self allocateCharacterBuffer:_length]; ! 230: NXReadArray (s, DATATYPEFORCHAR, _length, characters); ! 231: } else { ! 232: characters = NULL; ! 233: } ! 234: return self; ! 235: } ! 236: ! 237: @end ! 238: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.