This is HashFile.m in view mode; [Download] [Up]
/* File: HashFile.m - db(3) to HashTable bridge * * By: Christopher Lane * Symbolic Systems Resources Group * Knowledge Systems Laboratory * Stanford University * * Date: 6 August 1990 * * Copyright: 1990 by The Leland Stanford Junior University. This program * may be distributed without restriction for non-commercial use. */ #import <c.h> #import <libc.h> #import <string.h> #import <assert.h> #import "HashFile.h" #define NXRewind(stream) NXSeek(stream, 0L, NX_FROMSTART) @implementation HashFile + newFromFile:(const char *) name { return [HashFile newFromFile:name keyDesc:"@" valueDesc:"@"]; } + newFromFile:(const char *) name keyDesc:(const char *) aKeyDesc { return [HashFile newFromFile:name keyDesc:aKeyDesc valueDesc:"@"]; } + newFromFile:(const char *) name keyDesc:(const char *) aKeyDesc valueDesc:(const char *) aValueDesc { NXTypedStream *typedStream; self = [super newKeyDesc:aKeyDesc valueDesc:aValueDesc]; if((db = dbOpen(filename = (char *) name)) == NULL) { [self free]; return nil; } readOnly = (BOOL) ((db->flag & (dbFlagReadOnly | dbFlagCompressed)) != 0); assert(d.k.s = (char *) malloc((size_t) LEAFSIZE)); assert(d.c.s = (char *) malloc((size_t) LEAFSIZE)); d.k.n = malloc_size(d.k.s); d.c.n = malloc_size(d.c.s); assert(stream = NXOpenMemory(NULL, 0, NX_READWRITE)); assert(typedStream = NXOpenTypedStream(stream, NX_WRITEONLY)); offset = NXTell(stream); NXCloseTypedStream(typedStream); return self; } + (BOOL) isHashFile:(const char *) name { return dbExists((char *) name); } - free { free(d.k.s); free(d.c.s); NXCloseMemory(stream, NX_FREEBUFFER); assert(dbClose(db)); return [super free]; } - empty { if(!readOnly && dbClose(db) && dbCreate(filename) && (db = dbInit(filename)) != NULL) return [super empty]; return nil; } - (unsigned) count { unsigned i = 0; if(dbFirst(db, &d)) do { ++i; } while(dbNext(db, &d)); assert(i >= count); return i; } - (BOOL) isKey:(const void *) aKey { if([super isKey:aKey]) return YES; [self _keyCvtIn:aKey]; return((BOOL) dbFind(db, &d)); } - (void *) valueForKey:(const void *) aKey { void *value = (void *) nil; if([super isKey:aKey]) return [super valueForKey:aKey]; [self _keyCvtIn:aKey]; if(dbFetch(db, &d)) [super insertKey:aKey value:(value = [self _valueCvtOut])]; return value; } - (void *) insertKey:(const void *) aKey value:(void *) aValue { if(readOnly) return (void *) nil; [self _keyCvtIn:aKey]; [self _valueCvtIn:aValue]; if(!dbStore(db, &d)) return (void *) nil; return [super insertKey:aKey value:aValue]; } - (void *) removeKey:(const void *) aKey; { if(readOnly) return (void *) nil; [self _keyCvtIn:aKey]; if(!dbDelete(db, &d)) return (void *) nil; return([super removeKey:aKey]); } - (NXHashState) initState { NXHashState state = [super initState]; if(state.i = dbFirst(db, &d)) { state.i = d.k.n; state.j = d.c.n; } return state; } - (BOOL) nextState:(NXHashState *) aState key:(const void **) aKey value:(void **) aValue { if(aState->i == FALSE) return NO; d.k.n = aState->i; d.c.n = aState->j; if(dbGet(db, &d)) { *aKey = [self _keyCvtOut]; *aValue = [self _valueCvtOut]; } else return NO; if(aState->i = dbNext(db, &d)) { aState->i = d.k.n; aState->j = d.c.n; } return YES; } - (void) _keyCvtIn:(const void *) aKey { [self _datumCvtIn:&d.k from:aKey using:keyDesc]; } - (void) _valueCvtIn:(const void *) aValue { [self _datumCvtIn:&d.c from:aValue using:valueDesc]; } - (void) _datumCvtIn:(Datum *) aDatum from:(const void *) aBuffer using:(const char *) aDesc { NXTypedStream *typedStream; NXRewind(stream); assert(typedStream = NXOpenTypedStream(stream, NX_WRITEONLY)); offset = NXTell(stream); NXWriteType(typedStream, aDesc, &aBuffer); aDatum->n = NXTell(stream) - offset; NXCloseTypedStream(typedStream); NXSeek(stream, offset, NX_FROMSTART); NXRead(stream, (void *) aDatum->s, aDatum->n); } - (void *) _keyCvtOut { return [self _datumCvtOut:&d.k using:keyDesc]; } - (void *) _valueCvtOut { return [self _datumCvtOut:&d.c using:valueDesc]; } - (void *) _datumCvtOut:(Datum *) aDatum using:(const char *) aDesc { NXTypedStream *typedStream; void *buffer; assert(buffer = (void *) malloc((size_t) aDatum->n)); NXSeek(stream, offset, NX_FROMSTART); NXWrite(stream, (void *) aDatum->s, aDatum->n); NXRewind(stream); assert(typedStream = NXOpenTypedStream(stream, NX_READONLY)); NXReadType(typedStream, aDesc, &buffer); NXCloseTypedStream(typedStream); return buffer; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.