|
|
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.