This is StringStorage.m in view mode; [Download] [Up]
/* ** StringStorage.m,v 1.5 1992/09/24 03:34:31 nwc Exp ** ** Copyright (c) 1991 Ronin Consulting, Inc. */ #import "StringStorage.h" #import <limits.h> #import <string.h> #import <stdlib.h> #import<appkit/nextstd.h> static char EOS = (char)0; @implementation StringStorage - init { [super init]; [self initCount: 0 elementSize: sizeof(char) description: "c"]; [self setStringValue: ""]; return self; } - init: (const char *) str { [super init]; [self initCount: 0 elementSize: sizeof(char) description: "c"]; [self setStringValue: str]; return self; } - setStringValue: (const char *) str; { int len; if(!str) str = ""; /* avoid nil strings */ len = strlen(str); /* get length - no reason to do it twice */ [self setNumSlots: len + 1]; /* use setNumSlots vs setAvailCapacity since it sets count */ /* bcopy is far faster than strcpy if the length is known */ bcopy(str, (char *)dataPtr, len); [self replaceElementAt: len with: (char *)&EOS]; return self; } - setFStringValue: (const char *)format,... { NXStream *stream; long len; va_list params; va_start(params,format); stream = NXOpenMemory(NULL, 0, NX_READWRITE); NXVPrintf(stream, format, params); va_end(params); NXFlush(stream); NXSeek(stream, 0, NX_FROMEND); len = NXTell(stream); NXSeek(stream, 0, NX_FROMSTART); [self setNumSlots: len + 1]; NXRead(stream, (char *)dataPtr, len); [self replaceElementAt: len with: (char *)&EOS]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } - setVStringValue: (const char *)format valist: (va_list) params { NXStream *stream; long len; stream = NXOpenMemory(NULL, 0, NX_READWRITE); NXVPrintf(stream, format, params); NXFlush(stream); NXSeek(stream, 0, NX_FROMEND); len = NXTell(stream); NXSeek(stream, 0, NX_FROMSTART); [self setNumSlots: len + 1]; NXRead(stream, (char *)dataPtr, len); [self replaceElementAt: len with: (char *)&EOS]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } - (const char *) stringValue { return dataPtr; } - appendStringValue: (const char *)str { int oldCount = [self count]; int len; if(!str || !*str) /* nothing to append */ return self; len = strlen(str); [self setNumSlots: oldCount + len]; bcopy(str, (char *)[self elementAt: oldCount - 1], len); [self replaceElementAt: oldCount + len - 1 with: (char *)&EOS ]; return self; } - appendFStringValue: (const char *)format,... { int oldCount = [self count]; NXStream *stream; long len; va_list params; va_start(params,format); stream = NXOpenMemory(NULL, 0, NX_READWRITE); NXVPrintf(stream, format, params); va_end(params); NXFlush(stream); NXSeek(stream, 0, NX_FROMEND); len = NXTell(stream); NXSeek(stream, 0, NX_FROMSTART); [self setNumSlots: oldCount + len]; NXRead(stream, ((char *)dataPtr) + (oldCount - 1), len); [self replaceElementAt: oldCount + len - 1 with: (char *)&EOS ]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } - appendVStringValue: (const char *)format valist: (va_list) params { int oldCount = [self count]; NXStream *stream; long len; stream = NXOpenMemory(NULL, 0, NX_READWRITE); NXVPrintf(stream, format, params); NXFlush(stream); NXSeek(stream, 0, NX_FROMEND); len = NXTell(stream); NXSeek(stream, 0, NX_FROMSTART); [self setNumSlots: oldCount + len]; NXRead(stream, ((char *)dataPtr) + (oldCount - 1), len); [self replaceElementAt: oldCount + len - 1 with: (char *)&EOS ]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } - appendCharValue: (char) c { char buf[2]; buf[0] = c; buf[1] = (char)0; [self appendStringValue: buf]; return self; } - empty /* override to ensure null termination */ { [super empty]; [self setStringValue: ""]; return self; } - (int) strlen /* just (count - 1)...but nicer */ { return [self count] - 1; } - (int) matchSubstring: (const char *)str { int x, cnt; if(!str) return -1; for (x = 0, cnt = [self strlen]; x < cnt; x++) if(((char *)dataPtr)[x] == *str && !strncmp(str,(char *)dataPtr + x, strlen(str))) return x; return -1; } - (char *) getSubstring: (const char *)str { int offset; offset = [self matchSubstring: str]; if(offset != -1) return dataPtr + offset; else return (char*)0; } - replaceSubstring: (const char *)str with: (const char *)str2 { int offset, len1, len2; char *buf; if(!(str && str2)) return nil; offset = [self matchSubstring: str]; if(offset == -1) return nil; len1 = strlen(str); len2 = strlen(str2); NX_MALLOC(buf,char,([self count] + len2)); buf[[self count] + len2 - len1 - 1] = (char)0; bcopy((char *)dataPtr, buf, offset); bcopy(str2, buf + offset, len2); bcopy(((char *)dataPtr) + offset + len1, buf + offset + len2, [self count] - offset - len1 - 1); [self setStringValue: buf]; NX_FREE(buf); return self; } - (unsigned int)hash { unsigned int x = 0; int y, cnt; for(y = 0, cnt = [self strlen]; y < cnt; y++) x += ((char *)(dataPtr))[y]; return x; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.