Ruby: ext/fiddle/conversions.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

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