ext/fiddle/conversions.c in fiddle-1.1.1 vs ext/fiddle/conversions.c in fiddle-1.1.2
- old
+ new
@@ -1,5 +1,7 @@
+#include <stdbool.h>
+
#include <fiddle.h>
VALUE
rb_fiddle_type_ensure(VALUE type)
{
@@ -42,10 +44,11 @@
ID size_t_id;
ID ssize_t_id;
ID ptrdiff_t_id;
ID intptr_t_id;
ID uintptr_t_id;
+ ID bool_id;
RUBY_CONST_ID(void_id, "void");
RUBY_CONST_ID(voidp_id, "voidp");
RUBY_CONST_ID(char_id, "char");
RUBY_CONST_ID(short_id, "short");
RUBY_CONST_ID(int_id, "int");
@@ -72,10 +75,11 @@
RUBY_CONST_ID(size_t_id, "size_t");
RUBY_CONST_ID(ssize_t_id, "ssize_t");
RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
RUBY_CONST_ID(intptr_t_id, "intptr_t");
RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
+ RUBY_CONST_ID(bool_id, "bool");
if (type_id == void_id) {
return INT2NUM(TYPE_VOID);
}
else if (type_id == voidp_id) {
return INT2NUM(TYPE_VOIDP);
@@ -142,10 +146,13 @@
return INT2NUM(TYPE_INTPTR_T);
}
else if (type_id == uintptr_t_id) {
return INT2NUM(TYPE_UINTPTR_T);
}
+ else if (type_id == bool_id) {
+ return INT2NUM(TYPE_BOOL);
+ }
else {
type = original_type;
}
}
@@ -185,10 +192,24 @@
return &ffi_type_float;
case TYPE_DOUBLE:
return &ffi_type_double;
case TYPE_CONST_STRING:
return &ffi_type_pointer;
+ case TYPE_BOOL:
+ signed_p = 0;
+ if (sizeof(bool) == sizeof(char)) {
+ return rb_ffi_type_of(char);
+ } else if (sizeof(bool) == sizeof(short)) {
+ return rb_ffi_type_of(short);
+ } else if (sizeof(bool) == sizeof(int)) {
+ return rb_ffi_type_of(int);
+ } else if (sizeof(bool) == sizeof(long)) {
+ return rb_ffi_type_of(long);
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
+ }
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
return &ffi_type_pointer;
}
@@ -207,11 +228,15 @@
break;
case TYPE_VOIDP:
dst->pointer = NUM2PTR(rb_Integer(*src));
break;
case TYPE_CHAR:
- dst->schar = (signed char)NUM2INT(*src);
+ if (RB_TYPE_P(*src, RUBY_T_STRING) && RSTRING_LEN(*src) == 1) {
+ dst->schar = RSTRING_PTR(*src)[0];
+ } else {
+ dst->schar = (signed char)NUM2INT(*src);
+ }
break;
case TYPE_UCHAR:
dst->uchar = (unsigned char)NUM2UINT(*src);
break;
case TYPE_SHORT:
@@ -252,12 +277,27 @@
}
else {
dst->pointer = rb_string_value_cstr(src);
}
break;
+ case TYPE_BOOL:
+ if (sizeof(bool) == sizeof(char)) {
+ dst->uchar = RB_TEST(*src);
+ } else if (sizeof(bool) == sizeof(short)) {
+ dst->ushort = RB_TEST(*src);
+ } else if (sizeof(bool) == sizeof(int)) {
+ dst->uint = RB_TEST(*src);
+ } else if (sizeof(bool) == sizeof(long)) {
+ dst->ulong = RB_TEST(*src);
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
+ }
+ break;
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
+ break;
}
}
void
value_to_generic(int type, VALUE src, fiddle_generic *dst)
@@ -311,9 +351,22 @@
if (retval.pointer) {
return rb_str_new_cstr(retval.pointer);
}
else {
return Qnil;
+ }
+ case TYPE_BOOL:
+ if (sizeof(bool) == sizeof(char)) {
+ return CBOOL2RBBOOL((unsigned char)retval.fffi_arg);
+ } else if (sizeof(bool) == sizeof(short)) {
+ return CBOOL2RBBOOL((unsigned short)retval.fffi_arg);
+ } else if (sizeof(bool) == sizeof(int)) {
+ return CBOOL2RBBOOL((unsigned int)retval.fffi_arg);
+ } else if (sizeof(bool) == sizeof(long)) {
+ return CBOOL2RBBOOL(retval.ulong);
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
}
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}