|
|
Sample Programs from NeXSTEP 3.3
/*
* JFTableVectorConfiguration
* Written by Joe Freeman, NeXT Systems Engineering
*
* A list of these configuration objects is fed to a JFTableViewLoader
* to tell it what ivars and titles map into a DBTableView
*/
#import "JFTableVectorConfiguration.h"
#import <ansi/ctype.h>
#import <objc/objc-runtime.h>
@interface JFTableVectorConfiguration(Private)
- buildCachedInfo:sender;
@end
@implementation JFTableVectorConfiguration(Private)
/*======================================================================
* Private Methods
*======================================================================*/
/* rebuild the selector and slot number stuff for performance reasons */
- buildCachedInfo:sender
{
char tmpName[80];
if (ivarName && *ivarName && template){
/* support either - ivarName or - getIvarName methods on get */
ivarInfo = class_getInstanceVariable(template, ivarName);
getMethod = sel_getUid(ivarName);
if (!getMethod){
strcpy(tmpName,"get");
strcat(tmpName,ivarName);
tmpName[3] = toupper(tmpName[3]);
getMethod = sel_getUid(tmpName);
}
/* now try and figure out the setMethod name
* try -setIvarName: or -ivarName:
*/
strcpy(tmpName,"set");
strcat(tmpName,ivarName);
strcat(tmpName,":");
tmpName[3] = toupper(tmpName[3]);
setMethod = sel_getUid(tmpName) ;
if (!setMethod){
strcpy(tmpName,ivarName);
strcat(tmpName,":");
setMethod = sel_getUid(tmpName);
}
}
return self;
}
@end
@implementation JFTableVectorConfiguration
/*======================================================================
* designated initializer
*======================================================================*/
- init
{
[super init];
kindOfStringTable = NO;
return self;
}
- initDataClassName:(const char *)aString
titleName:(const char *)newTitle
ivarName:(const char *)newIvar
{
[self init];
[self setDataClassName:aString];
[self setTitle:newTitle];
[self setIvarName:newIvar];
return self;
}
/*======================================================================
* set up methods for this configuration object
*======================================================================*/
- setDataClassName:(const char *)aString
{
if (!aString)
templateName = NXUniqueString("");
else
templateName = NXUniqueString(aString);
if (objc_lookUpClass(aString)){
template = objc_lookUpClass(aString);
kindOfStringTable = [template isKindOfClassNamed:"NXStringTable"];
[self buildCachedInfo:self];
}
return self;
}
- setTitle:(const char *)newTitle
{
if (newTitle)
title = NXUniqueString(newTitle);
else
title = "";
return self;
}
- setIvarName:(const char *)newIvar
{
if (newIvar)
ivarName = NXUniqueString(newIvar);
else
ivarName = "";
[self buildCachedInfo:self];
return self;
}
- (const char *)dataClassName;
{
return templateName;
}
- (const char *)title
{
return title;
}
- (const char *)ivarName
{
return ivarName;
}
/*======================================================================
* archiving support (for the palette!)
*======================================================================*/
- awake
{
[self setDataClassName: templateName]; /* force cache rebuild */
return self;
}
- read:(NXTypedStream *)typedStream
{
[super read:typedStream];
NXReadType(typedStream,"%",&templateName);
NXReadType(typedStream,"%",&title);
NXReadType(typedStream,"%",&ivarName);
return self;
}
- write:(NXTypedStream *)typedStream
{
[super write:typedStream];
NXWriteType(typedStream,"%",&templateName);
NXWriteType(typedStream,"%",&title);
NXWriteType(typedStream,"%",&ivarName);
return self;
}
/*======================================================================
* use this thing to transfer data from dbvalues to datastore objects
*======================================================================*/
/*
* Load up the DBValue object (aValue) from the portion of the
* dataObject specified by this configuration object
*/
- getValueFromObject:dataObject into:aValue
{
/* we may have dynamicly loaded the data class after we init'd */
if (!template)
[self setDataClassName:templateName];
if (kindOfStringTable)
[aValue setStringValue:(char*)[dataObject valueForStringKey:ivarName]];
else if (!ivarInfo || !getMethod)
[aValue setStringValue:"???"];
/* Get that run time religion */
else if (ivarInfo->ivar_type[0] == 'f')
[aValue setFloatValue: ( (float (*)(id, SEL))
[dataObject methodFor:getMethod] )(dataObject, getMethod)];
else if (ivarInfo->ivar_type[0] == 'd')
[aValue setDoubleValue: ( (double (*)(id, SEL))
[dataObject methodFor:getMethod] )(dataObject, getMethod)];
else if (ivarInfo->ivar_type[0] == 'i')
[aValue setIntValue: ( (int (*)(id, SEL))
[dataObject methodFor:getMethod] )(dataObject, getMethod)];
else if (ivarInfo->ivar_type[0] == '*')
[aValue setStringValue: (char *)[dataObject perform: getMethod]];
else if (ivarInfo->ivar_type[0] == '[' &&
ivarInfo->ivar_type[strlen(ivarInfo->ivar_type)-2] == 'c')
[aValue setStringValue: (char *)[dataObject perform: getMethod]];
else
[aValue setStringValue:""];
return self;
}
/*
* save the dbvalue object into the portion of the data object specified by
* this configuration object
*/
- setValueForObject:dataObject from:aValue
{
id (* fConvert)(id, SEL, float);
id (* dConvert)(id, SEL, double);
id (* iConvert)(id, SEL, int);
char *oldString;
/* we may have dynamicly loaded the data class after we init'd */
if (!template)
[self setDataClassName:templateName];
if (kindOfStringTable) {
oldString = [dataObject insertKey:(const void *)ivarName
value:(void *)NXCopyStringBuffer([aValue stringValue])];
/// if (malloc_size(oldString)>0)
/// NXFree(oldString);
} else if (!ivarInfo || !setMethod)
return nil;
/* Get that run time religion */
else if (ivarInfo->ivar_type[0] == 'f') {
fConvert = (id (*)(id, SEL, float))[dataObject methodFor: setMethod];
fConvert(dataObject,setMethod,[aValue floatValue]);
} else if (ivarInfo->ivar_type[0] == 'd') {
dConvert = (id (*)(id, SEL, double))[dataObject methodFor: setMethod];
dConvert(dataObject,setMethod,[aValue doubleValue]);
} else if (ivarInfo->ivar_type[0] == 'i') {
iConvert = (id (*)(id, SEL, int))[dataObject methodFor: setMethod];
iConvert(dataObject,setMethod,[aValue intValue]);
} else if (ivarInfo->ivar_type[0] == '*')
[dataObject perform:setMethod with:(id)[aValue stringValue]];
else if (ivarInfo->ivar_type[0] == '[' &&
ivarInfo->ivar_type[strlen(ivarInfo->ivar_type)-2] == 'c')
[dataObject perform:setMethod with:(id)[aValue stringValue]];
return self;
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.