This is InfoD.m in view mode; [Download] [Up]
/*$Copyright: * Copyright (C) 1992.5.22. Recruit Co.,Ltd. * Institute for Supercomputing Research * All rights reserved. * NewsBase by ISR, Kazuto MIYAI, Gary ARAKAKI, Katsunori SUZUKI, Kok-meng Lue * * You may freely copy, distribute and reuse the code in this program under * following conditions. * - to include this notice in the source code, if it is to be distributed * with source code. * - to add the file named "COPYING" within the code, which shall include * GNU GENERAL PUBLIC LICENSE(*). * - to display an acknowledgement in binary code as follows: "This product * includes software developed by Recruit Co.,Ltd., ISR." * - to display a notice which shall state that the users may freely copy, * distribute and reuse the code in this program under GNU GENERAL PUBLIC * LICENSE(*) * - to indicate the way to access the copy of GNU GENERAL PUBLIC LICENSE(*) * * (*)GNU GENERAL PUBLIC LICENSE is stored in the file named COPYING * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. $*/ /* InfoD.m */ #import "InfoD.h" #import <appkit/Panel.h> #import <objc/NXStringTable.h> #import <objc/objc.h> #import <objc/hashtable.h> #import <string.h> #import <libc.h> #import <ctype.h> #import <streams/streams.h> #import "data_types.h" #import "errdebug.h" #define DEF_STRT_SIZE 16 #define DEF_INTT_SIZE 16 #define STRING_BUF_MAX 256 @implementation InfoD static NXAtom fileExtension; + initialize { fileExtension = NXUniqueStringNoCopy("tbl"); return(self); } + (NXAtom)rtfControlWord { return(NULL); } + (NXAtom)fileExtension { return(fileExtension); } + (NXAtom)pasteboardType { return(NULL); } - initWithKey:(const char *)theKey strCapacity:(int)kstr_num intCapacity:(int)kint_num { [super initKeyDesc:"*" valueDesc:"!" capacity:kstr_num + kint_num]; key = NXCopyStringBufferFromZone(theKey, [self zone]); zone = [self zone]; return(self); } - initWithKey:(const char *)theKey { [self initWithKey:theKey strCapacity:DEF_STRT_SIZE intCapacity:DEF_INTT_SIZE]; return self; } - init { [self initWithKey:"" strCapacity:DEF_STRT_SIZE intCapacity:DEF_INTT_SIZE]; return self; } - (const char *)key { return(key); } - addInfo:(char *)kvalue key:(char *)theKey { return([self addInfoString:kvalue key:theKey]); } - addInfoString:(const char *)theValue key:(const char *)theKey { char *copyOfValue; char *copyOfKey; // save type of value in 4 byte prefix to key copyOfKey = NXZoneMalloc(zone, strlen(theKey) + 5); *copyOfKey = '*'; copyOfKey += 4; strcpy(copyOfKey, theKey); copyOfValue = NXCopyStringBufferFromZone(theValue, zone); [super insertKey:(const void *)copyOfKey value:(void *)copyOfValue]; return(self); } - addInfoInt:(int)theValue key:(char *)theKey { char *copyOfKey; // save type of value in 4 byte prefix to key copyOfKey = NXZoneMalloc(zone, strlen(theKey) + 5); *copyOfKey = 'i'; copyOfKey += 4; strcpy(copyOfKey, theKey); [super insertKey:(const void *)copyOfKey value:(void *)theValue]; return(self); } - setHeaderInfo:(char *)kheader { NXStream *stream; char theKey[STRING_BUF_MAX], value[STRING_BUF_MAX]; stream = NXOpenMemory( NULL, 0, NX_READWRITE ); NXWrite( stream, (const void *)kheader, strlen(kheader) ); NXSeek( stream, 0, NX_FROMSTART ); while( NXGetc(stream) != (-1) ){ NXUngetc( stream ); NXScanf( stream, "%[^: ]", theKey ); NXGetc( stream ); /* ':' */ NXGetc( stream ); /* ' ' */ NXScanf( stream, "%[^\r\n]", value ); NXGetc( stream ); /* '\r' */ NXGetc( stream ); /* '\n' */ [self addInfoString:value key:theKey]; } return self; } - (void *)infoForKey:(const char *)theKey { return([super valueForKey:theKey]); } - (BOOL)nextState:(NXHashState *)aState key:(const void **)aKey value:(void **)aValue { BOOL status; static char value[16]; status = [super nextState:aState key:aKey value:aValue]; if (status == YES) { // always return string use prefix to determine type if (*(*(const char **)aKey - 4) == 'i') { sprintf(value, "%d", *aValue); *aValue = value; } } return(status); } /* readFromStream: initializes self from stream. The stream must be in the format specified by RFC822. readFromStream: returns YES if successful. Otherwise readFromStream: returns NO. Failures occur if the stream is not in RFC822 format or there is insufficient space in the buffers. Lines may not be longer than 512 characters. modified to accept lf in place of cr/lf. */ #define KEY_MAX_SIZE 256 #define VALUE_MAX_SIZE 2048 - (BOOL)readFromStream:(NXStream *)stream { char theKey[KEY_MAX_SIZE]; char value[VALUE_MAX_SIZE], *valueEnd; char *ptr; int nextChar; int isNumber; BOOL eos; while ((eos = NXAtEOS(stream)) == FALSE && (nextChar = NXGetc(stream)) != '\r' && nextChar != '\n') { NXUngetc(stream); if ((NXScanf(stream, "%255[^:]: %511[^\r\n]", theKey, value)) != 2) { return(NO); } // consume either cr/lf or lf as line terminator if ((nextChar = NXGetc(stream)) != '\n') { if (nextChar != '\r' || NXGetc(stream) != '\n') { return(NO); } } // read continuation lines if any while ((nextChar = NXGetc(stream)) == ' ' || nextChar == '\t') { valueEnd = index(value, '\0'); *valueEnd++ = ' '; if (valueEnd + 511 > value + VALUE_MAX_SIZE) { return(NO); } NXScanf(stream, " %511[^\r\n]", valueEnd); // consume either cr/lf or lf as line terminator if ((nextChar = NXGetc(stream)) != '\n') { if (nextChar != '\r' || NXGetc(stream) != '\n') { return(NO); } } } NXUngetc(stream); DBG(1, fprintf(stderr, "%s %s", theKey, value);); isNumber = 1; for (ptr = value; *ptr != '\0'; ++ptr) { if ((isNumber = isdigit(*ptr)) == 0) { break; } } if (isNumber != 0) { [self addInfoInt:atoi(value) key:theKey]; } else { [self addInfoString:value key:theKey]; } } if (eos == FALSE && nextChar == '\r' && NXGetc(stream) != '\n') { return(NO); } return(YES); } - (BOOL)readFromTarStream:(NXStream *)stream { return([self readFromStream:stream]); } - (BOOL)readFromFile:(const char *)pathName { NXStream *stream; BOOL status; if ((stream = NXMapFile(pathName, NX_READONLY)) != NULL) { status = [self readFromStream:stream]; NXCloseMemory(stream, NX_FREEBUFFER); return(status); } else { return(NO); } } - (void)writeToStream:(NXStream *)stream { NXHashState state; char *theKey, *value; state = [self initState]; while ([super nextState: &state key:(const void**)&theKey value:(void **)&value]) { if (*(theKey - 4) == '*') { NXPrintf(stream, "%s: %s\r\n", theKey, value); } else if (*(theKey - 4) == 'i') { NXPrintf(stream, "%s: %d\r\n", theKey, value); } } NXPutc(stream, '\r'); NXPutc(stream, '\n'); } - (void)writeToTarStream:(NXStream *)stream { [self writeToStream:stream]; } - free { NXHashState state; char *theKey, *value; state = [self initState]; while ([super nextState: &state key:(const void**)&theKey value:(void **)&value]) { if (*(theKey - 4) == '*') { NXZoneFree(zone, theKey - 4); NXZoneFree(zone, value); } else if (*(theKey - 4) == 'i') { NXZoneFree(zone, theKey - 4); } } NXZoneFree(zone, key); return([super free]); } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.