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); }