|
|
1.1 ! root 1: /* ! 2: * JFTableVectorConfiguration ! 3: * Written by Joe Freeman, NeXT Systems Engineering ! 4: * ! 5: * A list of these configuration objects is fed to a JFTableViewLoader ! 6: * to tell it what ivars and titles map into a DBTableView ! 7: */ ! 8: ! 9: #import "JFTableVectorConfiguration.h" ! 10: #import <ansi/ctype.h> ! 11: #import <objc/objc-runtime.h> ! 12: ! 13: @interface JFTableVectorConfiguration(Private) ! 14: ! 15: - buildCachedInfo:sender; ! 16: ! 17: @end ! 18: ! 19: @implementation JFTableVectorConfiguration(Private) ! 20: ! 21: /*====================================================================== ! 22: * Private Methods ! 23: *======================================================================*/ ! 24: ! 25: /* rebuild the selector and slot number stuff for performance reasons */ ! 26: - buildCachedInfo:sender ! 27: { ! 28: char tmpName[80]; ! 29: ! 30: if (ivarName && *ivarName && template){ ! 31: /* support either - ivarName or - getIvarName methods on get */ ! 32: ivarInfo = class_getInstanceVariable(template, ivarName); ! 33: getMethod = sel_getUid(ivarName); ! 34: if (!getMethod){ ! 35: strcpy(tmpName,"get"); ! 36: strcat(tmpName,ivarName); ! 37: tmpName[3] = toupper(tmpName[3]); ! 38: getMethod = sel_getUid(tmpName); ! 39: } ! 40: /* now try and figure out the setMethod name ! 41: * try -setIvarName: or -ivarName: ! 42: */ ! 43: strcpy(tmpName,"set"); ! 44: strcat(tmpName,ivarName); ! 45: strcat(tmpName,":"); ! 46: tmpName[3] = toupper(tmpName[3]); ! 47: setMethod = sel_getUid(tmpName) ; ! 48: if (!setMethod){ ! 49: strcpy(tmpName,ivarName); ! 50: strcat(tmpName,":"); ! 51: setMethod = sel_getUid(tmpName); ! 52: } ! 53: } ! 54: return self; ! 55: } ! 56: @end ! 57: ! 58: @implementation JFTableVectorConfiguration ! 59: ! 60: ! 61: /*====================================================================== ! 62: * designated initializer ! 63: *======================================================================*/ ! 64: ! 65: - init ! 66: { ! 67: [super init]; ! 68: kindOfStringTable = NO; ! 69: return self; ! 70: } ! 71: ! 72: - initDataClassName:(const char *)aString ! 73: titleName:(const char *)newTitle ! 74: ivarName:(const char *)newIvar ! 75: { ! 76: [self init]; ! 77: [self setDataClassName:aString]; ! 78: [self setTitle:newTitle]; ! 79: [self setIvarName:newIvar]; ! 80: return self; ! 81: } ! 82: ! 83: /*====================================================================== ! 84: * set up methods for this configuration object ! 85: *======================================================================*/ ! 86: ! 87: - setDataClassName:(const char *)aString ! 88: { ! 89: if (!aString) ! 90: templateName = NXUniqueString(""); ! 91: else ! 92: templateName = NXUniqueString(aString); ! 93: if (objc_lookUpClass(aString)){ ! 94: template = objc_lookUpClass(aString); ! 95: kindOfStringTable = [template isKindOfClassNamed:"NXStringTable"]; ! 96: [self buildCachedInfo:self]; ! 97: } ! 98: return self; ! 99: } ! 100: ! 101: - setTitle:(const char *)newTitle ! 102: { ! 103: if (newTitle) ! 104: title = NXUniqueString(newTitle); ! 105: else ! 106: title = ""; ! 107: return self; ! 108: } ! 109: ! 110: - setIvarName:(const char *)newIvar ! 111: { ! 112: if (newIvar) ! 113: ivarName = NXUniqueString(newIvar); ! 114: else ! 115: ivarName = ""; ! 116: [self buildCachedInfo:self]; ! 117: return self; ! 118: } ! 119: ! 120: - (const char *)dataClassName; ! 121: { ! 122: return templateName; ! 123: } ! 124: ! 125: ! 126: - (const char *)title ! 127: { ! 128: return title; ! 129: } ! 130: ! 131: - (const char *)ivarName ! 132: { ! 133: return ivarName; ! 134: } ! 135: ! 136: ! 137: /*====================================================================== ! 138: * archiving support (for the palette!) ! 139: *======================================================================*/ ! 140: ! 141: - awake ! 142: { ! 143: [self setDataClassName: templateName]; /* force cache rebuild */ ! 144: return self; ! 145: } ! 146: ! 147: - read:(NXTypedStream *)typedStream ! 148: { ! 149: [super read:typedStream]; ! 150: ! 151: NXReadType(typedStream,"%",&templateName); ! 152: NXReadType(typedStream,"%",&title); ! 153: NXReadType(typedStream,"%",&ivarName); ! 154: ! 155: return self; ! 156: } ! 157: - write:(NXTypedStream *)typedStream ! 158: { ! 159: [super write:typedStream]; ! 160: ! 161: NXWriteType(typedStream,"%",&templateName); ! 162: NXWriteType(typedStream,"%",&title); ! 163: NXWriteType(typedStream,"%",&ivarName); ! 164: ! 165: return self; ! 166: } ! 167: ! 168: ! 169: ! 170: /*====================================================================== ! 171: * use this thing to transfer data from dbvalues to datastore objects ! 172: *======================================================================*/ ! 173: ! 174: /* ! 175: * Load up the DBValue object (aValue) from the portion of the ! 176: * dataObject specified by this configuration object ! 177: */ ! 178: - getValueFromObject:dataObject into:aValue ! 179: { ! 180: /* we may have dynamicly loaded the data class after we init'd */ ! 181: if (!template) ! 182: [self setDataClassName:templateName]; ! 183: ! 184: if (kindOfStringTable) ! 185: [aValue setStringValue:(char*)[dataObject valueForStringKey:ivarName]]; ! 186: else if (!ivarInfo || !getMethod) ! 187: [aValue setStringValue:"???"]; ! 188: /* Get that run time religion */ ! 189: else if (ivarInfo->ivar_type[0] == 'f') ! 190: [aValue setFloatValue: ( (float (*)(id, SEL)) ! 191: [dataObject methodFor:getMethod] )(dataObject, getMethod)]; ! 192: else if (ivarInfo->ivar_type[0] == 'd') ! 193: [aValue setDoubleValue: ( (double (*)(id, SEL)) ! 194: [dataObject methodFor:getMethod] )(dataObject, getMethod)]; ! 195: else if (ivarInfo->ivar_type[0] == 'i') ! 196: [aValue setIntValue: ( (int (*)(id, SEL)) ! 197: [dataObject methodFor:getMethod] )(dataObject, getMethod)]; ! 198: else if (ivarInfo->ivar_type[0] == '*') ! 199: [aValue setStringValue: (char *)[dataObject perform: getMethod]]; ! 200: else if (ivarInfo->ivar_type[0] == '[' && ! 201: ivarInfo->ivar_type[strlen(ivarInfo->ivar_type)-2] == 'c') ! 202: [aValue setStringValue: (char *)[dataObject perform: getMethod]]; ! 203: else ! 204: [aValue setStringValue:""]; ! 205: return self; ! 206: } ! 207: ! 208: /* ! 209: * save the dbvalue object into the portion of the data object specified by ! 210: * this configuration object ! 211: */ ! 212: - setValueForObject:dataObject from:aValue ! 213: { ! 214: id (* fConvert)(id, SEL, float); ! 215: id (* dConvert)(id, SEL, double); ! 216: id (* iConvert)(id, SEL, int); ! 217: char *oldString; ! 218: ! 219: /* we may have dynamicly loaded the data class after we init'd */ ! 220: if (!template) ! 221: [self setDataClassName:templateName]; ! 222: ! 223: if (kindOfStringTable) { ! 224: oldString = [dataObject insertKey:(const void *)ivarName ! 225: value:(void *)NXCopyStringBuffer([aValue stringValue])]; ! 226: /// if (malloc_size(oldString)>0) ! 227: /// NXFree(oldString); ! 228: } else if (!ivarInfo || !setMethod) ! 229: return nil; ! 230: /* Get that run time religion */ ! 231: else if (ivarInfo->ivar_type[0] == 'f') { ! 232: fConvert = (id (*)(id, SEL, float))[dataObject methodFor: setMethod]; ! 233: fConvert(dataObject,setMethod,[aValue floatValue]); ! 234: } else if (ivarInfo->ivar_type[0] == 'd') { ! 235: dConvert = (id (*)(id, SEL, double))[dataObject methodFor: setMethod]; ! 236: dConvert(dataObject,setMethod,[aValue doubleValue]); ! 237: } else if (ivarInfo->ivar_type[0] == 'i') { ! 238: iConvert = (id (*)(id, SEL, int))[dataObject methodFor: setMethod]; ! 239: iConvert(dataObject,setMethod,[aValue intValue]); ! 240: } else if (ivarInfo->ivar_type[0] == '*') ! 241: [dataObject perform:setMethod with:(id)[aValue stringValue]]; ! 242: else if (ivarInfo->ivar_type[0] == '[' && ! 243: ivarInfo->ivar_type[strlen(ivarInfo->ivar_type)-2] == 'c') ! 244: [dataObject perform:setMethod with:(id)[aValue stringValue]]; ! 245: return self; ! 246: } ! 247: ! 248: ! 249: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.