Go to the documentation of this file.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(int64);
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 int signed_p = 1;
00046
00047 if (type < 0) {
00048 type = -1 * type;
00049 signed_p = 0;
00050 }
00051
00052 switch (type) {
00053 case TYPE_VOID:
00054 break;
00055 case TYPE_VOIDP:
00056 dst->pointer = NUM2PTR(rb_Integer(src));
00057 break;
00058 case TYPE_CHAR:
00059 case TYPE_SHORT:
00060 case TYPE_INT:
00061 dst->sint = NUM2INT(src);
00062 break;
00063 case TYPE_LONG:
00064 if (signed_p)
00065 dst->slong = NUM2LONG(src);
00066 else
00067 dst->ulong = NUM2LONG(src);
00068 break;
00069 #if HAVE_LONG_LONG
00070 case TYPE_LONG_LONG:
00071 dst->long_long = rb_big2ull(src);
00072 break;
00073 #endif
00074 case TYPE_FLOAT:
00075 dst->ffloat = (float)NUM2DBL(src);
00076 break;
00077 case TYPE_DOUBLE:
00078 dst->ddouble = NUM2DBL(src);
00079 break;
00080 default:
00081 rb_raise(rb_eRuntimeError, "unknown type %d", type);
00082 }
00083 }
00084
00085 VALUE
00086 generic_to_value(VALUE rettype, fiddle_generic retval)
00087 {
00088 int signed_p = 1;
00089 int type = NUM2INT(rettype);
00090 VALUE cPointer;
00091
00092 cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
00093
00094 if (type < 0) {
00095 type = -1 * type;
00096 signed_p = 0;
00097 }
00098
00099 switch (type) {
00100 case TYPE_VOID:
00101 return Qnil;
00102 case TYPE_VOIDP:
00103 return rb_funcall(cPointer, rb_intern("[]"), 1,
00104 PTR2NUM((void *)retval.pointer));
00105 case TYPE_CHAR:
00106 case TYPE_SHORT:
00107 case TYPE_INT:
00108 return INT2NUM(retval.sint);
00109 case TYPE_LONG:
00110 if (signed_p) return LONG2NUM(retval.slong);
00111 return ULONG2NUM(retval.ulong);
00112 #if HAVE_LONG_LONG
00113 case TYPE_LONG_LONG:
00114 return rb_ll2inum(retval.long_long);
00115 break;
00116 #endif
00117 case TYPE_FLOAT:
00118 return rb_float_new(retval.ffloat);
00119 case TYPE_DOUBLE:
00120 return rb_float_new(retval.ddouble);
00121 default:
00122 rb_raise(rb_eRuntimeError, "unknown type %d", type);
00123 }
00124 }
00125
00126
00127