|
|
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.