IoObject *IoCFFIPointer_castTo(IoCFFIPointer *self, IoObject *locals, IoMessage *m) { IoObject *toType = IoMessage_locals_valueArgAt_(m, locals, 0); IoObject *o = IoState_on_doCString_withLabel_(IOSTATE, toType, "?typeString", "IoCFFIPointer_castTo"); if(!ISNIL(o)) { char *typeStr = CSTRING(o); switch(typeStr[0]) { case '^': toType = IOCLONE(toType); *(DATA(toType)->valuePointer) = *((void **)IoCFFIDataType_ValuePointerFromObject_(toType, self)); return toType; case '*': toType = IOCLONE(toType); IoCFFIDataType_rawSetValue(toType, self); return toType; default: IoState_error_(IOSTATE, m, "Wrong type to cast to."); break; } } else { // Mm... well, if the type to cast to does not have a typeString slot, // it should be an Io Object, so the address stored here is a pointer to an // Io Object. Simply cast the pointer and return it... dangerous but... IoObject *obj = (IoObject *)*(DATA(self)->valuePointer); if(ISOBJECT(obj)) return (IoObject *)*(DATA(self)->valuePointer); } return IONIL(self); }
IoCFFIArray *IoCFFIArray_atPut(IoCFFIArray *self, IoObject *locals, IoMessage *m) { int pos; IoObject *value, *arrayType, *d; char *ptr; pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0)); value = IoMessage_locals_valueArgAt_(m, locals, 1); if ( pos >= DATA(self)->arraySize ) { IoState_error_(IOSTATE, m, "index out of bounds"); return IONIL(self); } arrayType = IoObject_getSlot_(self, IOSYMBOL("arrayType")); ptr = ((char *)DATA(self)->buffer) + (DATA(self)->itemSize * pos); d = IOCLONE(arrayType); IoCFFIDataType_rawSetValue(d, value); memcpy(ptr, (void *)IoCFFIDataType_ValuePointerFromObject_(self, d), DATA(self)->itemSize); if ( DATA(self)->keepValuesRefs ) { DATA(self)->keepValuesRefs[pos] = IOREF(d); } return self; }
IoCFFIArray *IoCFFIArray_atPut(IoCFFIArray *self, IoObject *locals, IoMessage *m) { int pos; IoObject *value, *d; char *ptr; //TODO check limits and types pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0)); value = IoMessage_locals_valueArgAt_(m, locals, 1); ptr = ((char *)DATA(self)->buffer) + (DATA(self)->itemSize * pos); d = IOCLONE(IoObject_getSlot_(self, IOSYMBOL("arrayType"))); IoCFFIDataType_rawSetValue(d, value); memcpy(ptr, (void *)IoCFFIDataType_ValuePointerFromObject_(NULL, d), DATA(self)->itemSize); return self; }
IoObject *IoCFFIPointer_atPut(IoCFFIPointer *self, IoObject *locals, IoMessage *m) { int pos; IoObject *value, *pointedToType, *d; char *ptr; //TODO comprobar overrun y coincidencia de tipos pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0)); value = IoMessage_locals_valueArgAt_(m, locals, 1); pointedToType = IoObject_getSlot_(self, IOSYMBOL("pointedToType")); ptr = ((char *)*(DATA(self)->valuePointer)) + (IoCFFIDataType_ffiType(pointedToType)->size * pos); d = IOCLONE(pointedToType); IoCFFIDataType_rawSetValue(d, value); memcpy(ptr, (void *)IoCFFIDataType_ValuePointerFromObject_(NULL, d), IoCFFIDataType_ffiType(pointedToType)->size); return self; }