Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
conversions.c
Go to the documentation of this file.
1#include <fiddle.h>
2
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) {
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
155ffi_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;
189 return &ffi_type_pointer;
190 default:
191 rb_raise(rb_eRuntimeError, "unknown type %d", type);
192 }
193 return &ffi_type_pointer;
194}
195
196ffi_type *
198{
200}
201
202void
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;
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
262void
264{
265 /* src isn't safe from GC when type is TYPE_CONST_STRING and src
266 * isn't String. */
268}
269
270VALUE
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);
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
322}
323
324VALUE
326{
327 return rb_fiddle_generic_to_value(rettype, retval);
328}
329
330/* vim: set noet sw=4 sts=4 */
#define UNREACHABLE
Definition: assume.h:30
ffi_type * int_to_ffi_type(int type)
Definition: conversions.c:197
VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
Definition: conversions.c:271
ffi_type * rb_fiddle_int_to_ffi_type(int type)
Definition: conversions.c:156
VALUE rb_fiddle_type_ensure(VALUE type)
Definition: conversions.c:4
#define rb_ffi_type_of(t)
void value_to_generic(int type, VALUE src, fiddle_generic *dst)
Definition: conversions.c:263
VALUE generic_to_value(VALUE rettype, fiddle_generic retval)
Definition: conversions.c:325
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
Definition: conversions.c:203
#define NUM2PTR(x)
Definition: conversions.h:46
#define PTR2NUM(x)
Definition: conversions.h:45
#define NUM2DBL
Definition: double.h:27
VALUE mFiddle
Definition: fiddle.c:3
#define TYPE_VARIADIC
Definition: fiddle.h:118
#define TYPE_CONST_STRING
Definition: fiddle.h:119
#define TYPE_FLOAT
Definition: fiddle.h:116
#define TYPE_PTRDIFF_T
Definition: fiddle.h:155
#define TYPE_CHAR
Definition: fiddle.h:109
#define TYPE_VOID
Definition: fiddle.h:107
#define TYPE_INT
Definition: fiddle.h:111
#define TYPE_LONG
Definition: fiddle.h:112
#define TYPE_SIZE_T
Definition: fiddle.h:151
#define TYPE_VOIDP
Definition: fiddle.h:108
#define TYPE_INTPTR_T
Definition: fiddle.h:165
#define TYPE_SSIZE_T
Definition: fiddle.h:144
#define TYPE_DOUBLE
Definition: fiddle.h:117
#define TYPE_SHORT
Definition: fiddle.h:110
#define TYPE_UINTPTR_T
Definition: fiddle.h:172
#define TYPE_INT8_T
Definition: fiddle.h:121
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
VALUE rb_eRuntimeError
Definition: error.c:1055
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
Definition: object.c:3138
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3051
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
VALUE rb_check_string_type(VALUE)
Definition: string.c:2462
#define rb_str_new_cstr(str)
Definition: string.h:219
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2624
ID rb_intern(const char *)
Definition: symbol.c:785
ID rb_sym2id(VALUE)
Definition: symbol.c:885
VALUE rb_to_symbol(VALUE name)
Definition: string.c:11511
#define RUBY_CONST_ID(var, str)
Definition: symbol.h:96
#define NUM2UINT
Definition: int.h:45
#define NUM2INT
Definition: int.h:44
#define INT2NUM
Definition: int.h:43
#define UINT2NUM
Definition: int.h:46
#define NUM2LL
Definition: long_long.h:34
#define LL2NUM
Definition: long_long.h:30
#define ULL2NUM
Definition: long_long.h:31
#define NUM2ULL
Definition: long_long.h:35
#define rb_float_new
Definition: numeric.h:95
#define NUM2ULONG
Definition: long.h:52
#define ULONG2NUM
Definition: long.h:60
#define LONG2NUM
Definition: long.h:50
#define NUM2LONG
Definition: long.h:51
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
#define NULL
Definition: regenc.h:69
char * rb_string_value_cstr(volatile VALUE *)
Definition: string.c:2439
#define Qnil
#define NIL_P
const ffi_type ffi_type_void
Definition: types.c:63
void * pointer
Definition: conversions.h:24
unsigned int uint
Definition: conversions.h:14
double ddouble
Definition: conversions.h:19
ffi_sarg fffi_sarg
Definition: conversions.h:9
signed char schar
Definition: conversions.h:11
unsigned char uchar
Definition: conversions.h:10
ffi_arg fffi_arg
Definition: conversions.h:8
signed long slong
Definition: conversions.h:17
unsigned long ulong
Definition: conversions.h:16
signed short sshort
Definition: conversions.h:13
signed int sint
Definition: conversions.h:15
unsigned long VALUE
Definition: value.h:38
unsigned long ID
Definition: value.h:39