Removed all code that uses OpenGL from Image.
[io/quag.git] / addons / CFFI / source / IoCFFIDataType.c
blob55f79ac81c960a298233603169c4cd044a0e5fdf
1 /* CFFI - An Io interface to C
2 Copyright (c) 2006 Trevor Fancher. All rights reserved.
3 All code licensed under the New BSD license.
4 */
6 #include "IoCFFIDataType.h"
7 #include "IoCFFIPointer.h"
8 //#include "IoCFFIStructure.h"
9 #include "IoSeq.h"
10 #include "IoNumber.h"
11 #include "IoObject.h"
12 #include "IoState.h"
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ffi.h>
17 #define DATA(self) ((IoCFFIDataTypeData *)(IoObject_dataPointer(self)))
19 void *IoCFFIDataType_null = NULL;
21 IoTag *IoCFFIDataType_newTag(void *state)
23 IoTag *tag = IoTag_newWithName_("DataType");
24 IoTag_state_(tag, state);
25 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoCFFIDataType_free);
26 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoCFFIDataType_rawClone);
27 return tag;
30 IoCFFIDataType *IoCFFIDataType_proto(void *state)
32 IoObject *self = IoObject_new(state);
33 IoObject_tag_(self, IoCFFIDataType_newTag(state));
35 IoObject_setDataPointer_(self, calloc(1, sizeof(IoCFFIDataTypeData)));
36 DATA(self)->needToFreeStr = 0;
38 IoState_registerProtoWithFunc_(state, self, IoCFFIDataType_proto);
41 IoMethodTable methodTable[] = {
42 {"value", IoCFFIDataType_value},
43 {"setValue", IoCFFIDataType_setValue},
44 {NULL, NULL},
46 IoObject_addMethodTable_(self, methodTable);
49 return self;
52 IoCFFIDataType *IoCFFIDataType_rawClone(IoCFFIDataType *proto)
54 IoObject *self = IoObject_rawClonePrimitive(proto);
55 IoObject_setDataPointer_(self, calloc(1, sizeof(IoCFFIDataTypeData)));
56 return self;
59 IoCFFIDataType *IoCFFIDataType_new(void *state)
61 IoObject *proto = IoState_protoWithInitFunction_(state, IoCFFIDataType_proto);
62 return IOCLONE(proto);
65 void IoCFFIDataType_free(IoCFFIDataType *self)
67 IoCFFIDataTypeData *data;
69 data = DATA(self);
70 if (data->needToFreeStr)
72 free(data->type.str);
73 data->needToFreeStr = 0;
75 free(DATA(self));
78 /* ---------------------------------------------------------------- */
80 void *IoCFFIDataType_ValuePointerFromObject_(IoObject *o)
82 IoObject *self, *number;
84 // this is a hack so macros relying on self will work
85 self = o;
87 if (ISNUMBER(o))
89 number = IoState_doCString_(IoObject_state(o), "CFFI Types Double clone");
90 DATA(number)->type.d = o->data.d;
92 return IoCFFIDataType_ValuePointerFromObject_(number);
94 else if (ISSEQ(o))
96 return (char **)IoObject_dataPointer(o);
98 else if (ISNIL(o))
100 return &IoCFFIDataType_null;
102 else if(ISCFFIDataType(o))
104 return IoCFFIDataType_valuePointer(o);
106 else if(ISCFFIPointer(o))
108 return IoCFFIPointer_valuePointer(o);
110 else
111 return NULL;
114 IoCFFIDataType *IoCFFIDataType_value(IoCFFIDataType *self, IoObject *locals, IoMessage *m)
116 return IoCFFIDataType_objectFromData_(self, &(DATA(self)->type));
119 IoCFFIDataType *IoCFFIDataType_setValue(IoCFFIDataType *self, IoObject *locals, IoMessage *m)
121 char c, *cp;
122 IoCFFIDataTypeData *data;
123 void *value;
125 data = DATA(self);
126 if (data->needToFreeStr)
128 free(data->type.str);
129 data->needToFreeStr = 0;
132 value = IoCFFIDataType_ValuePointerFromObject_(IoMessage_locals_valueArgAt_(m, locals, 0));
133 switch (c = CSTRING(IoState_on_doCString_withLabel_(IOSTATE, self, "typeString", "IoCFFIDataType_setValue"))[0])
135 case 'c':
136 data->type.C = **((char **)value); break;
137 case 'C':
138 data->type.C = (unsigned char)**((char **)value); break;
139 case 's':
140 data->type.s = (short)(*(double *)value); break;
141 case 'S':
142 data->type.S = (unsigned short)(*(double *)value); break;
143 case 'i':
144 data->type.i = (int)(*(double *)value); break;
145 case 'I':
146 data->type.I = (unsigned int)(*(double *)value); break;
147 case 'l':
148 data->type.l = (long)(*(double *)value); break;
149 case 'L':
150 data->type.L = (unsigned long)(*(double *)value); break;
151 case 'f':
152 data->type.f = (float)(*(double *)value); break;
153 case 'd':
154 data->type.d = *(double *)value; break;
155 case '*':
156 cp = *(char **)value;
157 data->type.str = malloc(strlen(cp) + 1);
158 data->needToFreeStr = 1;
159 strcpy(data->type.str, cp);
160 break;
162 case 'v':
163 IoState_error_(IOSTATE, NULL, "attempt to setValue on void DataType");
164 return IONIL(self);
166 default:
167 IoState_error_(IOSTATE, NULL, "unknown character '%c' in typeString", c);
168 return IONIL(self);
170 return self;
173 IoObject *IoCFFIDataType_objectFromData_(IoCFFIDataType *self, void *data)
175 char *typeString, c;
176 IoCFFIPointer *pointer;
178 typeString = CSTRING(IoState_on_doCString_withLabel_(IOSTATE, self, "typeString", "IoCFFIDataType_objectFromData_"));
179 switch (c = typeString[0])
181 case 'c':
182 case 'C':
183 return IoSeq_newWithCString_length_(IOSTATE, (char *)data, 1);
184 case 's':
185 return IONUMBER(((double)(*((short *)data))));
186 case 'S':
187 return IONUMBER(((double)(*((unsigned short *)data))));
188 case 'i':
189 return IONUMBER(((double)(*((int *)data))));
190 case 'I':
191 return IONUMBER(((double)(*((unsigned int *)data))));
192 case 'l':
193 return IONUMBER(((double)(*((long *)data))));
194 case 'L':
195 return IONUMBER(((double)(*((unsigned long *)data))));
196 case 'f':
197 return IONUMBER(((double)(*((float *)data))));
198 case 'd':
199 return IONUMBER((*((double *)data)));
200 case 'v':
201 return IONIL(self);
203 case '*':
204 if (*(char **)data)
206 return IoSeq_newWithCString_(IOSTATE, *(char **)data);
208 else
210 return IoSeq_new(IOSTATE);
213 case '^':
214 pointer = IOCLONE(self);
215 ((IoCFFIPointerData *)(IoObject_dataPointer(pointer)))->ptr = *(void **)data;
216 return pointer;
218 case '{':
219 case '(':
220 IoState_error_(IOSTATE, NULL, "structs and unions are not yet supported by CFFI");
221 return IONIL(self);
223 default:
224 IoState_error_(IOSTATE, NULL, "unknown character '%c' in typeString", c);
225 return IONIL(self);
229 ffi_type *IoCFFIDataType_ffiType(IoCFFIDataType *self)
231 char *typeString, c;
233 typeString = CSTRING(IoState_on_doCString_withLabel_(IOSTATE, self, "typeString", "IoCFFIDataType_ffiType"));
235 if (strlen(typeString) < 1)
237 return NULL;
240 switch (c = typeString[0])
242 case 'c':
243 return &ffi_type_schar;
244 case 'C':
245 return &ffi_type_uchar;
246 case 's':
247 return &ffi_type_sshort;
248 case 'S':
249 return &ffi_type_ushort;
250 case 'i':
251 return &ffi_type_sint;
252 case 'I':
253 return &ffi_type_uint;
254 case 'l':
255 return &ffi_type_slong;
256 case 'L':
257 return &ffi_type_ulong;
258 case 'f':
259 return &ffi_type_float;
260 case 'd':
261 return &ffi_type_double;
262 case 'v':
263 return &ffi_type_void;
265 case '*':
266 case '^':
267 return &ffi_type_pointer;
269 //case '{':
270 // return IoCFFIStructure_ffiType(self);
272 case '(':
273 IoState_error_(IOSTATE, NULL, "unions are not yet supported by CFFI");
274 return NULL;
276 default:
277 IoState_error_(IOSTATE, NULL, "unknown character '%c' in typeString", c);
278 return NULL;
282 void *IoCFFIDataType_valuePointer(IoCFFIDataType *self)
284 char c, *typeString;
285 IoCFFIDataTypeData *data;
287 typeString = CSTRING(IoState_on_doCString_withLabel_(IOSTATE, self, "typeString", "IoCFFIDataType_valuePointer"));
288 data = DATA(self);
290 switch (c = typeString[0])
292 case 'c': return &(data->type.c);
293 case 'C': return &(data->type.C);
294 case 's': return &(data->type.s);
295 case 'S': return &(data->type.S);
296 case 'i': return &(data->type.i);
297 case 'I': return &(data->type.I);
298 case 'l': return &(data->type.l);
299 case 'L': return &(data->type.L);
300 case 'f': return &(data->type.f);
301 case 'd': return &(data->type.d);
302 case '*': return &(data->type.str);
304 case 'v':
305 IoState_error_(IOSTATE, NULL, "atempt to get data pointer from Void type");
306 return NULL;
308 default:
309 IoState_error_(IOSTATE, NULL, "unknown character '%c' in typeString", c);
310 return NULL;
315 switch (c)
317 case 'c':
318 case 'C':
319 case 's':
320 case 'S':
321 case 'i':
322 case 'I':
323 case 'l':
324 case 'L':
325 case 'f':
326 case 'd':
327 case 'v':
328 case '*':
329 case '^':
330 case '{':
331 case '(':
333 default:
334 IoState_error_(IOSTATE, NULL, "unknown character '%c' in typeString", c);
335 return NULL;