This is DictManager.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "DictManager.h" #import <strings.h> #import <stdlib.h> #import <appkit/Panel.h> #import <appkit/NXBrowser.h> #import <appkit/NXBrowserCell.h> #import <appkit/Text.h> #import <objc/HashTable.h> #define DICTKNT 3 /* number of dictionaries implemented */ const char *dictType[DICTKNT] = {"@","i","*"} ; id dict[DICTKNT] ; #define CHUNK 127 char **addString(const char *string, int length, char **list, int count) // Adds the specified string to a list of strings. It allocates // more memory in chunks as needed. Robbed and hacked from // the BusyBox app. { if(!list) list = (char **)malloc(CHUNK*sizeof(char *)); list[count] = (char *)malloc((length+1)*sizeof(char)); strcpy(list[count], string); count++; if(!(count% CHUNK)) list = (char **)realloc(list,(((count/CHUNK)+1)*CHUNK)*sizeof(char *)); list[count] = NULL; return list; } void freeList(char **list) // Frees the array of strings { char **strings; if(list) { strings = list; while (*strings) free(*strings++); free(list); } } char * copy(aStr) char *aStr ; { // mallocs memory for a copy of aStr, returns pointer // to copy char *newStr ; newStr = (char *) malloc(strlen(aStr) + 1) ; strcpy(newStr, aStr) ; return newStr ; } @implementation DictManager + initialize ; { // set up the global dictionaries int i ; for(i = 0 ; i < DICTKNT ; i++) { dict[i] = [HashTable new] ; [dict[i] initKeyDesc: "*" valueDesc: dictType[i]] ; } return self ; } + insertKey: (char *) aKey value: (void *) data type: (char *) aType ; { // insert aKey<->data pair into the dictionary indicated by aType; int i ; if(!strcmp(aType,"*")) // handle strings as special case { if([dict[2] isKey: aKey]) // free up old data free([dict[2] insertKey:(const void *) copy(aKey) value:(void *) copy(data)]) ; else [dict[2] insertKey: (const void *) copy(aKey) value:(void *) copy(data)] ; } else { for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ; if([dict[i] isKey: aKey]) // already exists... [dict[i] insertKey: (const void *) copy(aKey) value: (void *) data] ; else [dict[i] insertKey: (const void *) copy(aKey) value: (void *) data] ; } return self ; } + removeKey: (char *) aKey type: (char *) aType ; { // insert aKey<->data pair into the dictionary indicated by aType; int i ; if(!strcmp(aType,"*")) // handle strings as special case { if([dict[2] isKey: aKey]) // free up old data { free([dict[2] valueForKey: aKey]) ; [dict[2] removeKey: aKey] ; } } else { for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ; [dict[i] removeKey: (const void *) aKey] ; } return self ; } + (void *) valueForKey: (char *) aKey type: (char *) aType ; { int i ; for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ; if(i == DICTKNT) { NXRunAlertPanel("CB","Unknown data type: \"%s\"",NULL,NULL,NULL,aType) ; return (void *) 0 ; } else return [dict[i] valueForKey: aKey] ; } - (int)browser:sender fillMatrix:matrix inColumn:(int)column ; { if(column == 0) return DICTKNT ; else { char typeBuf[24] ; int i,j ; const void *key; void *value; NXHashState state ; id table ; char **aList = NULL ; strcpy(typeBuf, [[[browserView matrixInColumn: 0] selectedCell] stringValue]) ; for(i = 0 ; i < DICTKNT && strcmp(typeBuf,dictType[i]) ; i++) ; table = dict[i] ; state = [table initState]; j = 0 ; while ([table nextState: &state key: &key value: &value]) aList = addString((const char *) key, strlen(key), aList, j++) ; freeList(browserList) ; browserList = aList ; return j ; } } - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column ; { if(column == 0) { [cell setStringValue: dictType[row]] ; [cell setLeaf: NO] ; } else { [cell setStringValue: browserList[row]] ; [cell setLeaf:YES] ; } return self ; } - browserHit:sender ; { char path[128] ; char type[2], *key[128] ; if([browserView selectedColumn] != 1) return self ; [browserView setPathSeparator: ' '] ; [browserView getPath: path toColumn: 2] ; sscanf(path,"%s %s",&type,&key) ; if(!strcmp(type,"@")) { id anId = (id) [dict[0] valueForKey:key] ; [textView setText: [anId name]] ; return self ; } if(!strcmp(type,"i")) { char buf[128] ; int i = (int) [dict[1] valueForKey:key] ; sprintf(buf,"%d", i) ; [textView setText: buf] ; return self ; } if(!strcmp(type,"*")) { [textView setText: [dict[2] valueForKey:key]] ; return self ; } return self ; } - delete: sender ; { char path[128] ; char type[2], *key[128] ; int i = 0; // delete the selected dictionary entry if([browserView selectedColumn] != 1) return self ; [browserView setPathSeparator: ' '] ; [browserView getPath: path toColumn: 2] ; sscanf(path,"%s %s",&type,&key) ; if(!strcmp(type,"@")) i = 0 ; else if(!strcmp(type,"i")) i = 1 ; else if(!strcmp(type,"*")) i = 2 ; [dict[i] removeKey:key] ; sprintf(path," %s",&type) ; [browserView loadColumnZero] ; [browserView setPath: path] ; [textView setText: ""] ; return self ; } - makeKeyAndOrderFront: sender ; { [browserView loadColumnZero] ; return [super makeKeyAndOrderFront: sender] ; } - newValue: sender ; { char path[128] ; char type[2], key[128], *theText ; int textLen ; if([browserView selectedColumn] != 1) return self ; [browserView setPathSeparator: ' '] ; [browserView getPath: path toColumn: 2] ; sscanf(path,"%s %s",&type,&key) ; if(!strcmp(type,"@")) { [textView setText: "Sorry: cannot change value of an id"] ; return self ; } textLen = [textView textLength] ; theText = (char *) malloc(textLen + 1) ; [textView getSubstring: theText start:0 length: textLen] ; if(!strcmp(type,"i")) { int i ; sscanf(theText,"%d",&i) ; [DictManager insertKey: key value: (void *) i type: "i"] ; } else if(!strcmp(type,"*")) [DictManager insertKey: key value: (void *) theText type: "*"] ; free(theText) ; return self ; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.