00001 #include <fiddle.h>
00002
00003 ffi_type *
00004 int_to_ffi_type(int type)
00005 {
00006 int signed_p = 1;
00007
00008 if (type < 0) {
00009 type = -1 * type;
00010 signed_p = 0;
00011 }
00012
00013 #define rb_ffi_type_of(t) (signed_p ? &ffi_type_s##t : &ffi_type_u##t)
00014
00015 switch (type) {
00016 case TYPE_VOID:
00017 return &ffi_type_void;
00018 case TYPE_VOIDP:
00019 return &ffi_type_pointer;
00020 case TYPE_CHAR:
00021 return rb_ffi_type_of(char);
00022 case TYPE_SHORT:
00023 return rb_ffi_type_of(short);
00024 case TYPE_INT:
00025 return rb_ffi_type_of(int);
00026 case TYPE_LONG:
00027 return rb_ffi_type_of(long);
00028 #if HAVE_LONG_LONG
00029 case TYPE_LONG_LONG:
00030 return rb_ffi_type_of(long_long);
00031 #endif
00032 case TYPE_FLOAT:
00033 return &ffi_type_float;
00034 case TYPE_DOUBLE:
00035 return &ffi_type_double;
00036 default:
00037 rb_raise(rb_eRuntimeError, "unknown type %d", type);
00038 }
00039 return &ffi_type_pointer;
00040 }
00041
00042 void
00043 value_to_generic(int type, VALUE src, fiddle_generic * dst)
00044 {
00045 switch (type) {
00046 case TYPE_VOID:
00047 break;
00048 case TYPE_VOIDP:
00049 dst->pointer = NUM2PTR(rb_Integer(src));
00050 break;
00051 case TYPE_CHAR:
00052 dst->schar = (signed char)NUM2INT(src);
00053 break;
00054 case -TYPE_CHAR:
00055 dst->uchar = (unsigned char)NUM2UINT(src);
00056 break;
00057 case TYPE_SHORT:
00058 dst->sshort = (unsigned short)NUM2INT(src);
00059 break;
00060 case -TYPE_SHORT:
00061 dst->sshort = (signed short)NUM2UINT(src);
00062 break;
00063 case TYPE_INT:
00064 dst->sint = NUM2INT(src);
00065 break;
00066 case -TYPE_INT:
00067 dst->uint = NUM2UINT(src);
00068 break;
00069 case TYPE_LONG:
00070 dst->slong = NUM2LONG(src);
00071 break;
00072 case -TYPE_LONG:
00073 dst->ulong = NUM2ULONG(src);
00074 break;
00075 #if HAVE_LONG_LONG
00076 case TYPE_LONG_LONG:
00077 dst->slong_long = NUM2LL(src);
00078 break;
00079 case -TYPE_LONG_LONG:
00080 dst->ulong_long = NUM2ULL(src);
00081 break;
00082 #endif
00083 case TYPE_FLOAT:
00084 dst->ffloat = (float)NUM2DBL(src);
00085 break;
00086 case TYPE_DOUBLE:
00087 dst->ddouble = NUM2DBL(src);
00088 break;
00089 default:
00090 rb_raise(rb_eRuntimeError, "unknown type %d", type);
00091 }
00092 }
00093
00094 VALUE
00095 generic_to_value(VALUE rettype, fiddle_generic retval)
00096 {
00097 int type = NUM2INT(rettype);
00098 VALUE cPointer;
00099
00100 cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
00101
00102 switch (type) {
00103 case TYPE_VOID:
00104 return Qnil;
00105 case TYPE_VOIDP:
00106 return rb_funcall(cPointer, rb_intern("[]"), 1,
00107 PTR2NUM((void *)retval.pointer));
00108 case TYPE_CHAR:
00109 return INT2NUM((signed char)retval.fffi_sarg);
00110 case -TYPE_CHAR:
00111 return INT2NUM((unsigned char)retval.fffi_arg);
00112 case TYPE_SHORT:
00113 return INT2NUM((signed short)retval.fffi_sarg);
00114 case -TYPE_SHORT:
00115 return INT2NUM((unsigned short)retval.fffi_arg);
00116 case TYPE_INT:
00117 return INT2NUM((signed int)retval.fffi_sarg);
00118 case -TYPE_INT:
00119 return UINT2NUM((unsigned int)retval.fffi_arg);
00120 case TYPE_LONG:
00121 return LONG2NUM(retval.slong);
00122 case -TYPE_LONG:
00123 return ULONG2NUM(retval.ulong);
00124 #if HAVE_LONG_LONG
00125 case TYPE_LONG_LONG:
00126 return LL2NUM(retval.slong_long);
00127 case -TYPE_LONG_LONG:
00128 return ULL2NUM(retval.ulong_long);
00129 #endif
00130 case TYPE_FLOAT:
00131 return rb_float_new(retval.ffloat);
00132 case TYPE_DOUBLE:
00133 return rb_float_new(retval.ddouble);
00134 default:
00135 rb_raise(rb_eRuntimeError, "unknown type %d", type);
00136 }
00137 }
00138
00139
00140