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.
6 #include "IoCFFIDataType.h"
7 #include "IoCFFIPointer.h"
8 //#include "IoCFFIStructure.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
);
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
},
46 IoObject_addMethodTable_(self
, methodTable
);
52 IoCFFIDataType
*IoCFFIDataType_rawClone(IoCFFIDataType
*proto
)
54 IoObject
*self
= IoObject_rawClonePrimitive(proto
);
55 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoCFFIDataTypeData
)));
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
;
70 if (data
->needToFreeStr
)
73 data
->needToFreeStr
= 0;
78 /* ---------------------------------------------------------------- */
80 void *IoCFFIDataType_ValuePointerFromObject_(IoObject
*o
)
82 IoObject
*self
, *number
;
84 // this is a hack so macros relying on self will work
89 number
= IoState_doCString_(IoObject_state(o
), "CFFI Types Double clone");
90 DATA(number
)->type
.d
= o
->data
.d
;
92 return IoCFFIDataType_ValuePointerFromObject_(number
);
96 return (char **)IoObject_dataPointer(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
);
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
)
122 IoCFFIDataTypeData
*data
;
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])
136 data
->type
.C
= **((char **)value
); break;
138 data
->type
.C
= (unsigned char)**((char **)value
); break;
140 data
->type
.s
= (short)(*(double *)value
); break;
142 data
->type
.S
= (unsigned short)(*(double *)value
); break;
144 data
->type
.i
= (int)(*(double *)value
); break;
146 data
->type
.I
= (unsigned int)(*(double *)value
); break;
148 data
->type
.l
= (long)(*(double *)value
); break;
150 data
->type
.L
= (unsigned long)(*(double *)value
); break;
152 data
->type
.f
= (float)(*(double *)value
); break;
154 data
->type
.d
= *(double *)value
; break;
156 cp
= *(char **)value
;
157 data
->type
.str
= malloc(strlen(cp
) + 1);
158 data
->needToFreeStr
= 1;
159 strcpy(data
->type
.str
, cp
);
163 IoState_error_(IOSTATE
, NULL
, "attempt to setValue on void DataType");
167 IoState_error_(IOSTATE
, NULL
, "unknown character '%c' in typeString", c
);
173 IoObject
*IoCFFIDataType_objectFromData_(IoCFFIDataType
*self
, void *data
)
176 IoCFFIPointer
*pointer
;
178 typeString
= CSTRING(IoState_on_doCString_withLabel_(IOSTATE
, self
, "typeString", "IoCFFIDataType_objectFromData_"));
179 switch (c
= typeString
[0])
183 return IoSeq_newWithCString_length_(IOSTATE
, (char *)data
, 1);
185 return IONUMBER(((double)(*((short *)data
))));
187 return IONUMBER(((double)(*((unsigned short *)data
))));
189 return IONUMBER(((double)(*((int *)data
))));
191 return IONUMBER(((double)(*((unsigned int *)data
))));
193 return IONUMBER(((double)(*((long *)data
))));
195 return IONUMBER(((double)(*((unsigned long *)data
))));
197 return IONUMBER(((double)(*((float *)data
))));
199 return IONUMBER((*((double *)data
)));
206 return IoSeq_newWithCString_(IOSTATE
, *(char **)data
);
210 return IoSeq_new(IOSTATE
);
214 pointer
= IOCLONE(self
);
215 ((IoCFFIPointerData
*)(IoObject_dataPointer(pointer
)))->ptr
= *(void **)data
;
220 IoState_error_(IOSTATE
, NULL
, "structs and unions are not yet supported by CFFI");
224 IoState_error_(IOSTATE
, NULL
, "unknown character '%c' in typeString", c
);
229 ffi_type
*IoCFFIDataType_ffiType(IoCFFIDataType
*self
)
233 typeString
= CSTRING(IoState_on_doCString_withLabel_(IOSTATE
, self
, "typeString", "IoCFFIDataType_ffiType"));
235 if (strlen(typeString
) < 1)
240 switch (c
= typeString
[0])
243 return &ffi_type_schar
;
245 return &ffi_type_uchar
;
247 return &ffi_type_sshort
;
249 return &ffi_type_ushort
;
251 return &ffi_type_sint
;
253 return &ffi_type_uint
;
255 return &ffi_type_slong
;
257 return &ffi_type_ulong
;
259 return &ffi_type_float
;
261 return &ffi_type_double
;
263 return &ffi_type_void
;
267 return &ffi_type_pointer
;
270 // return IoCFFIStructure_ffiType(self);
273 IoState_error_(IOSTATE
, NULL
, "unions are not yet supported by CFFI");
277 IoState_error_(IOSTATE
, NULL
, "unknown character '%c' in typeString", c
);
282 void *IoCFFIDataType_valuePointer(IoCFFIDataType
*self
)
285 IoCFFIDataTypeData
*data
;
287 typeString
= CSTRING(IoState_on_doCString_withLabel_(IOSTATE
, self
, "typeString", "IoCFFIDataType_valuePointer"));
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
);
305 IoState_error_(IOSTATE
, NULL
, "atempt to get data pointer from Void type");
309 IoState_error_(IOSTATE
, NULL
, "unknown character '%c' in typeString", c
);
334 IoState_error_(IOSTATE, NULL, "unknown character '%c' in typeString", c);