Ruby  3.1.0dev(2021-09-10revisionb76ad15ed0da636161de0243c547ee1e6fc95681)
conversions.c
Go to the documentation of this file.
1 #include <fiddle.h>
2 
3 VALUE
5 {
6  VALUE original_type = type;
7 
8  if (!RB_SYMBOL_P(type)) {
9  VALUE type_string = rb_check_string_type(type);
10  if (!NIL_P(type_string)) {
11  type = rb_to_symbol(type_string);
12  }
13  }
14 
15  if (RB_SYMBOL_P(type)) {
16  ID type_id = rb_sym2id(type);
17  ID void_id;
18  ID voidp_id;
19  ID char_id;
20  ID short_id;
21  ID int_id;
22  ID long_id;
23 #ifdef TYPE_LONG_LONG
24  ID long_long_id;
25 #endif
26 #ifdef TYPE_INT8_T
27  ID int8_t_id;
28 #endif
29 #ifdef TYPE_INT16_T
30  ID int16_t_id;
31 #endif
32 #ifdef TYPE_INT32_T
33  ID int32_t_id;
34 #endif
35 #ifdef TYPE_INT64_T
36  ID int64_t_id;
37 #endif
38  ID float_id;
39  ID double_id;
40  ID variadic_id;
41  ID const_string_id;
42  ID size_t_id;
43  ID ssize_t_id;
44  ID ptrdiff_t_id;
45  ID intptr_t_id;
46  ID uintptr_t_id;
47  RUBY_CONST_ID(void_id, "void");
48  RUBY_CONST_ID(voidp_id, "voidp");
49  RUBY_CONST_ID(char_id, "char");
50  RUBY_CONST_ID(short_id, "short");
51  RUBY_CONST_ID(int_id, "int");
52  RUBY_CONST_ID(long_id, "long");
53 #ifdef TYPE_LONG_LONG
54  RUBY_CONST_ID(long_long_id, "long_long");
55 #endif
56 #ifdef TYPE_INT8_T
57  RUBY_CONST_ID(int8_t_id, "int8_t");
58 #endif
59 #ifdef TYPE_INT16_T
60  RUBY_CONST_ID(int16_t_id, "int16_t");
61 #endif
62 #ifdef TYPE_INT32_T
63  RUBY_CONST_ID(int32_t_id, "int32_t");
64 #endif
65 #ifdef TYPE_INT64_T
66  RUBY_CONST_ID(int64_t_id, "int64_t");
67 #endif
68  RUBY_CONST_ID(float_id, "float");
69  RUBY_CONST_ID(double_id, "double");
70  RUBY_CONST_ID(variadic_id, "variadic");
71  RUBY_CONST_ID(const_string_id, "const_string");
72  RUBY_CONST_ID(size_t_id, "size_t");
73  RUBY_CONST_ID(ssize_t_id, "ssize_t");
74  RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
75  RUBY_CONST_ID(intptr_t_id, "intptr_t");
76  RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
77  if (type_id == void_id) {
78  return INT2NUM(TYPE_VOID);
79  }
80  else if (type_id == voidp_id) {
81  return INT2NUM(TYPE_VOIDP);
82  }
83  else if (type_id == char_id) {
84  return INT2NUM(TYPE_CHAR);
85  }
86  else if (type_id == short_id) {
87  return INT2NUM(TYPE_SHORT);
88  }
89  else if (type_id == int_id) {
90  return INT2NUM(TYPE_INT);
91  }
92  else if (type_id == long_id) {
93  return INT2NUM(TYPE_LONG);
94  }
95 #ifdef TYPE_LONG_LONG
96  else if (type_id == long_long_id) {
97  return INT2NUM(TYPE_LONG_LONG);
98  }
99 #endif
100 #ifdef TYPE_INT8_T
101  else if (type_id == int8_t_id) {
102  return INT2NUM(TYPE_INT8_T);
103  }
104 #endif
105 #ifdef TYPE_INT16_T
106  else if (type_id == int16_t_id) {
107  return INT2NUM(TYPE_INT16_T);
108  }
109 #endif
110 #ifdef TYPE_INT32_T
111  else if (type_id == int32_t_id) {
112  return INT2NUM(TYPE_INT32_T);
113  }
114 #endif
115 #ifdef TYPE_INT64_T
116  else if (type_id == int64_t_id) {
117  return INT2NUM(TYPE_INT64_T);
118  }
119 #endif
120  else if (type_id == float_id) {
121  return INT2NUM(TYPE_FLOAT);
122  }
123  else if (type_id == double_id) {
124  return INT2NUM(TYPE_DOUBLE);
125  }
126  else if (type_id == variadic_id) {
127  return INT2NUM(TYPE_VARIADIC);
128  }
129  else if (type_id == const_string_id) {
130  return INT2NUM(TYPE_CONST_STRING);
131  }
132  else if (type_id == size_t_id) {
133  return INT2NUM(TYPE_SIZE_T);
134  }
135  else if (type_id == ssize_t_id) {
136  return INT2NUM(TYPE_SSIZE_T);
137  }
138  else if (type_id == ptrdiff_t_id) {
139  return INT2NUM(TYPE_PTRDIFF_T);
140  }
141  else if (type_id == intptr_t_id) {
142  return INT2NUM(TYPE_INTPTR_T);
143  }
144  else if (type_id == uintptr_t_id) {
145  return INT2NUM(TYPE_UINTPTR_T);
146  }
147  else {
148  type = original_type;
149  }
150  }
151 
152  return rb_to_int(type);
153 }
154 
155 ffi_type *
157 {
158  int signed_p = 1;
159 
160  if (type < 0) {
161  type = -1 * type;
162  signed_p = 0;
163  }
164 
165 #define rb_ffi_type_of(t) (signed_p ? &ffi_type_s##t : &ffi_type_u##t)
166 
167  switch (type) {
168  case TYPE_VOID:
169  return &ffi_type_void;
170  case TYPE_VOIDP:
171  return &ffi_type_pointer;
172  case TYPE_CHAR:
173  return rb_ffi_type_of(char);
174  case TYPE_SHORT:
175  return rb_ffi_type_of(short);
176  case TYPE_INT:
177  return rb_ffi_type_of(int);
178  case TYPE_LONG:
179  return rb_ffi_type_of(long);
180 #if HAVE_LONG_LONG
181  case TYPE_LONG_LONG:
182  return rb_ffi_type_of(long_long);
183 #endif
184  case TYPE_FLOAT:
185  return &ffi_type_float;
186  case TYPE_DOUBLE:
187  return &ffi_type_double;
188  case TYPE_CONST_STRING:
189  return &ffi_type_pointer;
190  default:
191  rb_raise(rb_eRuntimeError, "unknown type %d", type);
192  }
193  return &ffi_type_pointer;
194 }
195 
196 ffi_type *
198 {
200 }
201 
202 void
204 {
205  switch (type) {
206  case TYPE_VOID:
207  break;
208  case TYPE_VOIDP:
209  dst->pointer = NUM2PTR(rb_Integer(*src));
210  break;
211  case TYPE_CHAR:
212  dst->schar = (signed char)NUM2INT(*src);
213  break;
214  case -TYPE_CHAR:
215  dst->uchar = (unsigned char)NUM2UINT(*src);
216  break;
217  case TYPE_SHORT:
218  dst->sshort = (unsigned short)NUM2INT(*src);
219  break;
220  case -TYPE_SHORT:
221  dst->sshort = (signed short)NUM2UINT(*src);
222  break;
223  case TYPE_INT:
224  dst->sint = NUM2INT(*src);
225  break;
226  case -TYPE_INT:
227  dst->uint = NUM2UINT(*src);
228  break;
229  case TYPE_LONG:
230  dst->slong = NUM2LONG(*src);
231  break;
232  case -TYPE_LONG:
233  dst->ulong = NUM2ULONG(*src);
234  break;
235 #if HAVE_LONG_LONG
236  case TYPE_LONG_LONG:
237  dst->slong_long = NUM2LL(*src);
238  break;
239  case -TYPE_LONG_LONG:
240  dst->ulong_long = NUM2ULL(*src);
241  break;
242 #endif
243  case TYPE_FLOAT:
244  dst->ffloat = (float)NUM2DBL(*src);
245  break;
246  case TYPE_DOUBLE:
247  dst->ddouble = NUM2DBL(*src);
248  break;
249  case TYPE_CONST_STRING:
250  if (NIL_P(*src)) {
251  dst->pointer = NULL;
252  }
253  else {
254  dst->pointer = rb_string_value_cstr(src);
255  }
256  break;
257  default:
258  rb_raise(rb_eRuntimeError, "unknown type %d", type);
259  }
260 }
261 
262 void
264 {
265  /* src isn't safe from GC when type is TYPE_CONST_STRING and src
266  * isn't String. */
267  rb_fiddle_value_to_generic(type, &src, dst);
268 }
269 
270 VALUE
272 {
273  int type = NUM2INT(rettype);
274  VALUE cPointer;
275 
276  cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
277 
278  switch (type) {
279  case TYPE_VOID:
280  return Qnil;
281  case TYPE_VOIDP:
282  return rb_funcall(cPointer, rb_intern("[]"), 1,
283  PTR2NUM((void *)retval.pointer));
284  case TYPE_CHAR:
285  return INT2NUM((signed char)retval.fffi_sarg);
286  case -TYPE_CHAR:
287  return INT2NUM((unsigned char)retval.fffi_arg);
288  case TYPE_SHORT:
289  return INT2NUM((signed short)retval.fffi_sarg);
290  case -TYPE_SHORT:
291  return INT2NUM((unsigned short)retval.fffi_arg);
292  case TYPE_INT:
293  return INT2NUM((signed int)retval.fffi_sarg);
294  case -TYPE_INT:
295  return UINT2NUM((unsigned int)retval.fffi_arg);
296  case TYPE_LONG:
297  return LONG2NUM(retval.slong);
298  case -TYPE_LONG:
299  return ULONG2NUM(retval.ulong);
300 #if HAVE_LONG_LONG
301  case TYPE_LONG_LONG:
302  return LL2NUM(retval.slong_long);
303  case -TYPE_LONG_LONG:
304  return ULL2NUM(retval.ulong_long);
305 #endif
306  case TYPE_FLOAT:
307  return rb_float_new(retval.ffloat);
308  case TYPE_DOUBLE:
309  return rb_float_new(retval.ddouble);
310  case TYPE_CONST_STRING:
311  if (retval.pointer) {
312  return rb_str_new_cstr(retval.pointer);
313  }
314  else {
315  return Qnil;
316  }
317  default:
318  rb_raise(rb_eRuntimeError, "unknown type %d", type);
319  }
320 
321  UNREACHABLE;
322 }
323 
324 VALUE
326 {
327  return rb_fiddle_generic_to_value(rettype, retval);
328 }
329 
330 /* vim: set noet sw=4 sts=4 */
rb_const_get
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2645
TYPE_VOIDP
#define TYPE_VOIDP
Definition: fiddle.h:112
TYPE_DOUBLE
#define TYPE_DOUBLE
Definition: fiddle.h:121
ULL2NUM
#define ULL2NUM
Definition: long_long.h:31
TYPE_LONG
#define TYPE_LONG
Definition: fiddle.h:116
fiddle_generic::ulong
unsigned long ulong
Definition: conversions.h:16
generic_to_value
VALUE generic_to_value(VALUE rettype, fiddle_generic retval)
Definition: conversions.c:325
mFiddle
VALUE mFiddle
Definition: fiddle.c:3
TYPE_VARIADIC
#define TYPE_VARIADIC
Definition: fiddle.h:122
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:784
fiddle_generic::uchar
unsigned char uchar
Definition: conversions.h:10
value_to_generic
void value_to_generic(int type, VALUE src, fiddle_generic *dst)
Definition: conversions.c:263
fiddle.h
fiddle_generic::slong
signed long slong
Definition: conversions.h:17
NUM2DBL
#define NUM2DBL
Definition: double.h:27
LONG2NUM
#define LONG2NUM
Definition: long.h:50
TYPE_SHORT
#define TYPE_SHORT
Definition: fiddle.h:114
ID
unsigned long ID
Definition: value.h:39
NUM2ULL
#define NUM2ULL
Definition: long_long.h:35
TYPE_SSIZE_T
#define TYPE_SSIZE_T
Definition: fiddle.h:148
TYPE_INT
#define TYPE_INT
Definition: fiddle.h:115
rb_sym2id
ID rb_sym2id(VALUE)
Definition: symbol.c:884
rb_Integer
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
Definition: object.c:3150
NUM2INT
#define NUM2INT
Definition: int.h:44
NUM2UINT
#define NUM2UINT
Definition: int.h:45
fiddle_generic
Definition: conversions.h:6
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:3022
rb_to_symbol
VALUE rb_to_symbol(VALUE name)
Definition: string.c:11499
fiddle_generic::uint
unsigned int uint
Definition: conversions.h:14
NIL_P
#define NIL_P
Definition: special_consts.h:46
int_to_ffi_type
ffi_type * int_to_ffi_type(int type)
Definition: conversions.c:197
RUBY_CONST_ID
#define RUBY_CONST_ID(var, str)
Definition: symbol.h:96
INT2NUM
#define INT2NUM
Definition: int.h:43
fiddle_generic::pointer
void * pointer
Definition: conversions.h:24
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2453
TYPE_SIZE_T
#define TYPE_SIZE_T
Definition: fiddle.h:155
ULONG2NUM
#define ULONG2NUM
Definition: long.h:60
TYPE_CHAR
#define TYPE_CHAR
Definition: fiddle.h:113
LL2NUM
#define LL2NUM
Definition: long_long.h:30
fiddle_generic::ddouble
double ddouble
Definition: conversions.h:19
rb_string_value_cstr
char * rb_string_value_cstr(volatile VALUE *)
Definition: string.c:2430
UNREACHABLE
#define UNREACHABLE
Definition: missing.h:46
Qnil
#define Qnil
Definition: special_consts.h:51
NUM2PTR
#define NUM2PTR(x)
Definition: conversions.h:46
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:1091
rb_fiddle_int_to_ffi_type
ffi_type * rb_fiddle_int_to_ffi_type(int type)
Definition: conversions.c:156
NULL
#define NULL
Definition: regenc.h:69
fiddle_generic::sshort
signed short sshort
Definition: conversions.h:13
rb_fiddle_value_to_generic
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
Definition: conversions.c:203
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3063
TYPE_VOID
#define TYPE_VOID
Definition: fiddle.h:111
TYPE_INT8_T
#define TYPE_INT8_T
Definition: fiddle.h:125
VALUE
unsigned long VALUE
Definition: value.h:38
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1113
rb_ffi_type_of
#define rb_ffi_type_of(t)
TYPE_UINTPTR_T
#define TYPE_UINTPTR_T
Definition: fiddle.h:176
NUM2LONG
#define NUM2LONG
Definition: long.h:51
rb_float_new
#define rb_float_new
Definition: numeric.h:96
PTR2NUM
#define PTR2NUM(x)
Definition: conversions.h:45
UINT2NUM
#define UINT2NUM
Definition: int.h:46
TYPE_FLOAT
#define TYPE_FLOAT
Definition: fiddle.h:120
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: string.h:219
NUM2ULONG
#define NUM2ULONG
Definition: long.h:52
fiddle_generic::fffi_arg
ffi_arg fffi_arg
Definition: conversions.h:8
rb_fiddle_type_ensure
VALUE rb_fiddle_type_ensure(VALUE type)
Definition: conversions.c:4
fiddle_generic::schar
signed char schar
Definition: conversions.h:11
TYPE_PTRDIFF_T
#define TYPE_PTRDIFF_T
Definition: fiddle.h:159
NUM2LL
#define NUM2LL
Definition: long_long.h:34
fiddle_generic::fffi_sarg
ffi_sarg fffi_sarg
Definition: conversions.h:9
fiddle_generic::ffloat
float ffloat
Definition: conversions.h:18
TYPE_CONST_STRING
#define TYPE_CONST_STRING
Definition: fiddle.h:123
TYPE_INTPTR_T
#define TYPE_INTPTR_T
Definition: fiddle.h:169
fiddle_generic::sint
signed int sint
Definition: conversions.h:15
rb_fiddle_generic_to_value
VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
Definition: conversions.c:271
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56