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.