Annotation of objc/NXReadWriteString.m, revision 1.1.1.1

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:        NXReadWriteString.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 NXReadWriteString
                     38: 
                     39: #define actStr ((struct {@defs(NXReadOnlyString);} *)actualString)
                     40: 
                     41: - initFromCharactersNoCopy:(unichar *)chars length:(unsigned)len
                     42: {
                     43:     return [self initFromCharactersNoCopy:chars length:len freeWhenDone:YES];
                     44: }
                     45: 
                     46: // To allow for cheap creation of empty read/write strings (with init, say),
                     47: // we keep around an empty readonly string and hand out copies of it whenever
                     48: // necessary.  A mutex could be used in the code below to prevent the one-time leak
                     49: // of one or more NXReadOnlyStrings. However, the chances of the leak are so small 
                     50: // it's not clear we should bother.
                     51: 
                     52: - initFromCharactersNoCopy:(unichar *)chars length:(unsigned)len freeWhenDone:(BOOL)flag
                     53: {
                     54:     static NXReadOnlyString *emptyReadOnlyString = nil;
                     55:     [super initFromCharactersNoCopy:chars length:len];
                     56:     if (len == 0 && emptyReadOnlyString) {
                     57:        actualString = [emptyReadOnlyString copy];
                     58:     } else {
                     59:        actualString = [[NXReadOnlyString allocFromZone:[self zone]] initFromCharactersNoCopy:len ? chars : NULL length:len freeWhenDone:flag];
                     60:        if (len == 0 && !emptyReadOnlyString) {         // ??? mutex could be used to prevent possible leak
                     61:            emptyReadOnlyString = [actualString copy];
                     62:        }
                     63:     }
                     64:     return self;
                     65: }
                     66: 
                     67: - (unsigned)length
                     68: {
                     69:     return actStr->_length;
                     70: }
                     71: 
                     72: - (unichar)characterAt:(unsigned)loc
                     73: {
                     74:     if (loc >= actStr->_length) BOUNDSERROR;
                     75:     return actStr->characters[loc];
                     76: }
                     77: 
                     78: - (unichar *)allocateCharacterBuffer:(unsigned)nChars
                     79: {
                     80:     return NX_CHARALLOC(stringZone, nChars);
                     81: }
                     82: 
                     83: - (void)getCharacters:(unichar *)buffer range:(NXRange)range
                     84: {
                     85:     if (RNGLOC(range) + RNGLEN(range) > actStr->_length) BOUNDSERROR;
                     86:     NX_CHARCOPY(actStr->characters + RNGLOC(range), buffer, RNGLEN(range));
                     87: }
                     88: 
                     89: - (void)getCString:(char *)buffer maxLength:(unsigned)bytes range:(NXRange)range remainingRange:(NXRange *)leftover
                     90: {
                     91: #if CHARS_ARE_EIGHT_BIT
                     92:     NXRange desiredRange = range;
                     93:     unsigned cnt;
                     94:     if (RNGLOC(range) + RNGLEN(range) > actStr->_length) BOUNDSERROR;
                     95:     if (RNGLEN(range) > bytes) RNGLEN(range) = bytes;
                     96:     for (cnt = 0; cnt < RNGLEN(range); cnt++) {
                     97:         unichar ch = actStr->characters[RNGLOC(range) + cnt];
                     98:        buffer[cnt] = (ch > 0x0ff) ? NX_UNREPRESENTABLE_CHARACTER : ch;
                     99:     }
                    100:     buffer[RNGLEN(range)] = 0;
                    101:     if (leftover) {
                    102:        RNGLOC(*leftover) = RNGLOC(desiredRange) + RNGLEN(range);
                    103:        RNGLEN(*leftover) = RNGLEN(desiredRange) - RNGLEN(range);
                    104:     }
                    105: #else
                    106: #warning getCString:maxLength:range:remainingRange: not implemented for Unicode
                    107:     _NXStringErrorRaise (NXStringInternalError, "getCString:maxLength:range:remainingRange: not implemented for Unicode");
                    108: #endif
                    109: }
                    110: 
                    111: // ??? Most of these methods simply forward the message onto the actualString, so we
                    112: // might just want to use forwarding here...
                    113: 
                    114: - (NXComparisonResult)compare:string mask:(unsigned int)options table:(void *)table
                    115: {
                    116:     return [actualString compare:string mask:options table:table];
                    117: }
                    118: 
                    119: - (NXRange)findString:(NXString *)findStr range:(NXRange)fRange mask:(unsigned int)options table:(void *)table
                    120: {
                    121:     return [actualString findString:findStr range:fRange mask:options table:table];
                    122: }
                    123: 
                    124: - (unsigned)findCharacter:(unichar)ch range:(NXRange)fRange mask:(unsigned int)options table:(void *)table
                    125: {
                    126:     return [actualString findCharacter:ch range:fRange mask:options table:NULL];
                    127: }
                    128: 
                    129: - (unsigned)findOneOf:(NXCharacterSet *)set range:(NXRange)fRange mask:(unsigned int)options table:(void *)table
                    130: {
                    131:     return [actualString findOneOf:set range:fRange mask:options table:table];
                    132: }
                    133: 
                    134: - (unsigned)hash
                    135: {
                    136:     return [actualString hash];
                    137: }
                    138: 
                    139: - (void)replaceCharactersInRange:(NXRange)range withString:(NXString *)string
                    140: {
                    141:     unsigned int newLength, len = [self length], otherLength = [string length];
                    142:     unichar *newBuffer;
                    143:     NXRange strRange = {0, otherLength};
                    144: 
                    145:     if (RNGLOC(range) + RNGLEN(range) > len) BOUNDSERROR;   
                    146: 
                    147:     newLength = len + otherLength - RNGLEN(range);
                    148:     newBuffer = [self allocateCharacterBuffer:newLength];
                    149: 
                    150:     // Copy the three chunks into the new buffer
                    151: 
                    152:     NX_CHARCOPY (actStr->characters, newBuffer, RNGLOC(range));
                    153:     [string getCharacters:(newBuffer + RNGLOC(range)) range:strRange];
                    154:     NX_CHARCOPY (actStr->characters + (RNGLOC(range) + RNGLEN(range)), newBuffer + RNGLOC(range) + otherLength, (len - (RNGLOC(range) + RNGLEN(range))));
                    155: 
                    156:     // Now the new buffer is created. See what we do with the old one...
                    157: 
                    158:     if (actStr->_flags.refs > 1) {
                    159:         actStr->_flags.refs -= 1;
                    160:         actualString = [[NXReadOnlyString allocFromZone:[self zone]] initFromCharactersNoCopy:newBuffer length:newLength freeWhenDone:YES];
                    161:     } else {
                    162:         if (!actStr->_flags.notCopied) {
                    163:             free (actStr->characters);
                    164:         }
                    165:         actStr->_length = newLength;
                    166:         actStr->characters = newBuffer;
                    167:     }
                    168: }
                    169: 
                    170: - copyFromZone:(NXZone *)zone
                    171: {
                    172:     NXReadWriteString *newInstance = [super copyFromZone:zone];
                    173:     newInstance->actualString = [actualString copy];
                    174:     return newInstance;
                    175: }
                    176: 
                    177: - immutableCopyFromZone:(NXZone *)zone
                    178: {
                    179:     return [actualString copyFromZone:zone];
                    180: }
                    181: 
                    182: - free
                    183: {
                    184:     [actualString free];
                    185:     return [super free];
                    186: }
                    187: 
                    188: - write:(NXTypedStream *)s
                    189: {
                    190:     [super write:s];
                    191:     NXWriteObject (s, actualString);
                    192:     return self;
                    193: }
                    194: 
                    195: - read:(NXTypedStream *)s
                    196: {
                    197:     [super read:s];
                    198:     actualString = NXReadObject (s);
                    199:     return self;
                    200: }
                    201: 
                    202: // We want to make sure the object itself comes out of the string zone
                    203: // and not some random area which might be deallocated later...
                    204: 
                    205: - finishUnarchiving
                    206: {
                    207:     id actual = nil; 
                    208:     if ([self zone] != stringZone) {
                    209:         actual = object_copyFromZone (self, 0, stringZone);
                    210:         object_dispose(self);
                    211:     }
                    212:     return actual;
                    213: }
                    214: 
                    215: 
                    216: @end
                    217: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.