Annotation of objc/NXStringTable.m, revision 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:        NXStringTable.m
        !            26:        Copyright 1990 NeXT, Inc.
        !            27:        Written by Bertrand Serlet, Jan 89
        !            28:        Responsibility: Bertrand Serlet
        !            29: */
        !            30: 
        !            31: #ifndef KERNEL
        !            32: #ifdef SHLIB
        !            33: #import "shlib.h"
        !            34: #endif SHLIB
        !            35: 
        !            36: #import <stdlib.h>
        !            37: #import <stdio.h>
        !            38: #import <string.h>
        !            39: #import "NXStringTable.h"
        !            40: 
        !            41: @implementation NXStringTable
        !            42: + new {
        !            43:     return [self newKeyDesc:"%" valueDesc:"*"];
        !            44: }
        !            45: 
        !            46: - init {
        !            47:     return [self initKeyDesc:"%" valueDesc:"*"];
        !            48: }
        !            49: 
        !            50: static void noFree (void *item) {}
        !            51: static void freeString(void *string) { free(string);}
        !            52: - free {
        !            53:     [self freeKeys:noFree values:freeString];
        !            54:     return [super free];
        !            55: }
        !            56:     
        !            57: - (const char *)valueForStringKey:(const char *)aString {
        !            58:     return (const char *) [super valueForKey:NXUniqueString(aString)];
        !            59: }
        !            60: 
        !            61: static int skipSpace(NXStream *stream) {
        !            62:     /* return first significant character */
        !            63:     int        ch;
        !            64:     while ((ch = NXGetc(stream)) != EOF) {
        !            65:        if ((ch != ' ') && (ch != '\n') && (ch != '\t')) return ch;
        !            66:     }
        !            67:     return ch;
        !            68: }
        !            69: 
        !            70: static int parseWord(NXStream *stream, char *word) {
        !            71:     /* return '"', that is read, or EOF */
        !            72:     int        length = 0;
        !            73:     int        ch;
        !            74:     while (((ch = NXGetc(stream)) != EOF) && (ch != '"') && (length < MAX_NXSTRINGTABLE_LENGTH)) {
        !            75:        word[length++] = ch;
        !            76:        if (ch == '\\') {
        !            77:            switch (ch = NXGetc(stream)) {
        !            78:                case 'a':       word[length-1] = '\a'; break;
        !            79:                case 'b':       word[length-1] = '\b'; break;
        !            80:                case 'f':       word[length-1] = '\f'; break;
        !            81:                case 'n':       word[length-1] = '\n'; break;
        !            82:                case 'r':       word[length-1] = '\r'; break;
        !            83:                case 't':       word[length-1] = '\t'; break;
        !            84:                case 'v':       word[length-1] = '\v'; break;
        !            85:                case '"':       word[length-1] = '\"'; break;
        !            86:                case EOF:       break;
        !            87:                case '\'':      word[length-1] = '\''; break;
        !            88:                case '?':       word[length-1] = '?'; break;
        !            89:                case '\\':      word[length-1] = '\\'; break;
        !            90:                case 'x':
        !            91:                    {
        !            92:                      unsigned char c2 = 0;
        !            93:                      
        !            94:                      while (1)
        !            95:                        {
        !            96:                          ch = NXGetc (stream);
        !            97:                          
        !            98:                          if ('0' <= ch && ch <= '7')
        !            99:                            c2 = (16 * c2) + (ch - '0');
        !           100:                          else if ('a' <= ch && ch <= 'f')
        !           101:                            c2 = (16 * c2) + (ch - 'a' + 0xa);
        !           102:                          else if ('A' <= ch && ch <= 'F')
        !           103:                            c2 = (16 * c2) + (ch - 'A' + 0xa);
        !           104:                          else
        !           105:                            {
        !           106:                              NXUngetc (stream);
        !           107:                              break;
        !           108:                            }
        !           109:                        }
        !           110:                      
        !           111:                      word[length-1] = c2;
        !           112:                      break;
        !           113:                    }
        !           114:                  
        !           115:                default:
        !           116:                  if ('0' <= ch && ch <= '7')
        !           117:                    {
        !           118:                      unsigned char c2 = ch - '0';
        !           119:                      unsigned int i;
        !           120:                      
        !           121:                      for (i = 0; i < 2; i++)
        !           122:                        {
        !           123:                          ch = NXGetc (stream);
        !           124:                          
        !           125:                          if ('0' <= ch && ch <= '7')
        !           126:                            c2 = (8 * c2) + (ch - '0');
        !           127:                          else
        !           128:                            {
        !           129:                              NXUngetc (stream);
        !           130:                              break;
        !           131:                            }
        !           132:                        }
        !           133:                      
        !           134:                      word[length-1] = c2;
        !           135:                    }
        !           136:                  else
        !           137:                    /* unknown escape sequence */
        !           138:                    word[length-1] = ch;
        !           139:                  
        !           140:                  break;
        !           141:            }
        !           142:        }
        !           143:     }
        !           144:     word[length] = 0;
        !           145:     return ch;
        !           146: }
        !           147: 
        !           148: static void writeWord(NXStream *stream, const char *word) {
        !           149:     int        ch;
        !           150:     NXPutc(stream, '"');
        !           151:     while ((ch = *(word++))) {
        !           152:        switch (ch) {
        !           153:            case '\a':  NXPutc(stream, '\\'); NXPutc(stream, 'a'); break;
        !           154:            case '\b':  NXPutc(stream, '\\'); NXPutc(stream, 'b'); break;
        !           155:            case '\f':  NXPutc(stream, '\\'); NXPutc(stream, 'f'); break;
        !           156:            case '\n':  NXPutc(stream, '\\'); NXPutc(stream, 'n'); break;
        !           157:            case '\r':  NXPutc(stream, '\\'); NXPutc(stream, 'r'); break;
        !           158:            case '\t':  NXPutc(stream, '\\'); NXPutc(stream, 't'); break;
        !           159:            case '\v':  NXPutc(stream, '\\'); NXPutc(stream, 'v'); break;
        !           160:            case '\"':  NXPutc(stream, '\\'); NXPutc(stream, '"'); break;
        !           161:            case '\\':  NXPutc(stream, '\\'); NXPutc(stream, '\\'); break;
        !           162:            default: NXPutc(stream, ch);
        !           163:        }
        !           164:     }
        !           165:     NXPutc(stream, '"');
        !           166: }
        !           167: 
        !           168:     
        !           169: - readFromStream:(NXStream *)stream {
        !           170:     int        ch;
        !           171:     NXZone *zone = [self zone];
        !           172:     if (!stream) return nil;
        !           173:     while ((ch = skipSpace(stream)) != EOF) {
        !           174:        switch (ch) {
        !           175:            case '/':
        !           176:                ch = NXGetc(stream);
        !           177:                if (ch != '*') goto nope;
        !           178:                while ((ch = NXGetc(stream)) != EOF) {
        !           179:                    if (ch == '*') {
        !           180:                        ch = NXGetc(stream);
        !           181:                        if (ch == '/') break;
        !           182:                        NXUngetc(stream);
        !           183:                    }
        !           184:                }
        !           185:                if (ch == EOF) goto nope;
        !           186:                break;
        !           187:            case '"': {
        !           188:                char    key[MAX_NXSTRINGTABLE_LENGTH+1];
        !           189:                char    value[MAX_NXSTRINGTABLE_LENGTH+1];
        !           190:                ch = parseWord(stream, key);
        !           191:                if (ch != '"') goto nope;
        !           192:                ch = skipSpace(stream);
        !           193:                if (ch == '=') {
        !           194:                    ch = skipSpace(stream);
        !           195:                    if (ch != '"') goto nope;
        !           196:                    ch = parseWord(stream, value);
        !           197:                    if (ch != '"') goto nope;
        !           198:                    ch = skipSpace(stream);
        !           199:                } else {
        !           200:                    strcpy(value, key);
        !           201:                }
        !           202:                if (ch != ';') goto nope;
        !           203:                free([self insertKey:NXUniqueString(key) 
        !           204:                    value:NXCopyStringBufferFromZone(value, zone)]);
        !           205:                break;
        !           206:            }
        !           207:            default:    goto nope;
        !           208:        }
        !           209:     }
        !           210:     return self;
        !           211:   nope:
        !           212:     {
        !           213:         extern void _NXLogError(const char *format, ...);
        !           214:         if (ch == EOF)
        !           215:             _NXLogError ("NXStringTable: parse error before end of stream");
        !           216:         else
        !           217:             _NXLogError ("NXStringTable: parse error before '%c'", ch);
        !           218:         return nil;
        !           219:     }
        !           220: }
        !           221: 
        !           222: - readFromFile:(const char *)fileName {
        !           223:     NXStream   *stream = NXMapFile(fileName, NX_READONLY);
        !           224:     id retval = [self readFromStream:stream];
        !           225:     if (stream) NXCloseMemory(stream, NX_FREEBUFFER);
        !           226:     return retval;
        !           227: }
        !           228: 
        !           229: + newFromStream:(NXStream *)stream {
        !           230:     id table;
        !           231:     if (! stream) return nil;
        !           232:     table = [self new];
        !           233:     if (![table readFromStream:stream])
        !           234:        table = [table free];
        !           235:     return table;
        !           236: }
        !           237:     
        !           238: + newFromFile:(const char *)fileName {
        !           239:     id table;
        !           240:     table = [self new];
        !           241:     if (![table readFromFile:fileName])
        !           242:        table = [table free];
        !           243:     return table;
        !           244: }
        !           245: 
        !           246: - writeToStream:(NXStream *)stream {
        !           247:     NXHashState                state = [self initState];
        !           248:     NXAtom             key;
        !           249:     const char         *value;
        !           250:     while ([self nextState:&state key:(const void **)&key value:(void **)&value]) {
        !           251:        writeWord(stream, key);
        !           252:        if (strcmp(key, value)) {
        !           253:            NXPrintf(stream, "\t= ");
        !           254:            writeWord(stream, value);
        !           255:        }
        !           256:        NXPrintf(stream, ";\n");
        !           257:     }
        !           258:     return self;
        !           259: }
        !           260:     
        !           261: - writeToFile:(const char *)fileName {
        !           262:     NXStream   *stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
        !           263:     int                res;
        !           264:     [self writeToStream:stream];
        !           265:     res = NXSaveToFile(stream, fileName);
        !           266:     NXCloseMemory(stream, NX_FREEBUFFER);
        !           267:     return (res) ? nil : self;
        !           268: }
        !           269: 
        !           270: @end
        !           271: #endif /* KERNEL */

unix.superglobalmegacorp.com

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