rubysl-dl 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +0 -1
- data/.travis.yml +8 -0
- data/README.md +2 -2
- data/Rakefile +0 -1
- data/ext/rubysl/dl/depend +46 -0
- data/ext/rubysl/dl/dl.c +742 -0
- data/ext/rubysl/dl/dl.def +59 -0
- data/ext/rubysl/dl/dl.h +313 -0
- data/ext/rubysl/dl/extconf.rb +193 -0
- data/ext/rubysl/dl/h2rb +500 -0
- data/ext/rubysl/dl/handle.c +215 -0
- data/ext/rubysl/dl/install.rb +49 -0
- data/ext/rubysl/dl/lib/dl/import.rb +225 -0
- data/ext/rubysl/dl/lib/dl/struct.rb +149 -0
- data/ext/rubysl/dl/lib/dl/types.rb +245 -0
- data/ext/rubysl/dl/lib/dl/win32.rb +25 -0
- data/ext/rubysl/dl/mkcall.rb +69 -0
- data/ext/rubysl/dl/mkcallback.rb +63 -0
- data/ext/rubysl/dl/mkcbtable.rb +25 -0
- data/ext/rubysl/dl/ptr.c +1062 -0
- data/ext/rubysl/dl/sample/c++sample.C +35 -0
- data/ext/rubysl/dl/sample/c++sample.rb +60 -0
- data/ext/rubysl/dl/sample/drives.rb +70 -0
- data/ext/rubysl/dl/sample/getch.rb +5 -0
- data/ext/rubysl/dl/sample/libc.rb +69 -0
- data/ext/rubysl/dl/sample/msgbox.rb +19 -0
- data/ext/rubysl/dl/sample/msgbox2.rb +18 -0
- data/ext/rubysl/dl/sample/stream.rb +87 -0
- data/ext/rubysl/dl/sym.c +993 -0
- data/ext/rubysl/dl/test/libtest.def +28 -0
- data/ext/rubysl/dl/test/test.c +247 -0
- data/ext/rubysl/dl/test/test.rb +306 -0
- data/ext/rubysl/dl/type.rb +115 -0
- data/lib/dl.rb +1 -0
- data/lib/rubysl/dl.rb +2 -0
- data/lib/rubysl/dl/version.rb +5 -0
- data/rubysl-dl.gemspec +20 -18
- metadata +109 -87
- data/lib/rubysl-dl.rb +0 -7
- data/lib/rubysl-dl/version.rb +0 -5
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'mkmf'
|
4
|
+
$:.unshift File.dirname(__FILE__)
|
5
|
+
require 'type'
|
6
|
+
require 'dlconfig'
|
7
|
+
|
8
|
+
if name = ARGV.shift
|
9
|
+
OUTPUT = File.open name, "wb"
|
10
|
+
at_exit { OUTPUT.close }
|
11
|
+
else
|
12
|
+
OUTPUT = STDOUT
|
13
|
+
end
|
14
|
+
|
15
|
+
def mkfunc(rettype, fnum, argc)
|
16
|
+
args = (0..(argc-1)).collect{|i| "long arg#{i}"}.join(", ")
|
17
|
+
|
18
|
+
subst_code = (0..(argc-1)).collect{|i|
|
19
|
+
" buff[#{i.to_s}] = arg#{i.to_s};"
|
20
|
+
}.join("\n")
|
21
|
+
|
22
|
+
ret_code =
|
23
|
+
if( DLTYPE[rettype][:c2rb] )
|
24
|
+
" return #{DLTYPE[rettype][:rb2c]['retval']};"
|
25
|
+
else
|
26
|
+
" /* no return value */"
|
27
|
+
end
|
28
|
+
|
29
|
+
code = [
|
30
|
+
"static #{DLTYPE[rettype][:ctype]}",
|
31
|
+
"rb_dl_callback_func_#{rettype.to_s}_#{fnum.to_s}(#{args})",
|
32
|
+
"{",
|
33
|
+
" VALUE retval, proto, proc, obj;",
|
34
|
+
" VALUE argv[#{argc.to_s}];",
|
35
|
+
" int argc;",
|
36
|
+
" long buff[#{argc.to_s}];",
|
37
|
+
"",
|
38
|
+
subst_code,
|
39
|
+
"",
|
40
|
+
" obj = rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(#{rettype.to_s}),INT2NUM(#{fnum.to_s})));",
|
41
|
+
" if(NIL_P(obj))",
|
42
|
+
" rb_raise(rb_eDLError, \"callback function does not exist in DL::FuncTable\");",
|
43
|
+
" Check_Type(obj, T_ARRAY);",
|
44
|
+
" proto = rb_ary_entry(obj, 0);",
|
45
|
+
" proc = rb_ary_entry(obj, 1);",
|
46
|
+
" Check_Type(proto, T_STRING);",
|
47
|
+
" if( RSTRING(proto)->len >= #{argc.to_s} )",
|
48
|
+
" rb_raise(rb_eArgError, \"too many arguments\");",
|
49
|
+
" rb_dl_scan_callback_args(buff, RSTRING(proto)->ptr, &argc, argv);",
|
50
|
+
" retval = rb_funcall2(proc, id_call, argc, argv);",
|
51
|
+
"",
|
52
|
+
ret_code,
|
53
|
+
"}",
|
54
|
+
].join("\n")
|
55
|
+
|
56
|
+
return code
|
57
|
+
end
|
58
|
+
|
59
|
+
DLTYPE.keys.sort.each{|t|
|
60
|
+
for n in 0..(MAX_CALLBACK - 1)
|
61
|
+
OUTPUT.print(mkfunc(t, n, 15), "\n\n")
|
62
|
+
end
|
63
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'mkmf'
|
4
|
+
$:.unshift File.dirname(__FILE__)
|
5
|
+
require 'type'
|
6
|
+
require 'dlconfig'
|
7
|
+
|
8
|
+
if name = ARGV.shift
|
9
|
+
OUTPUT = File.open name, "wb"
|
10
|
+
at_exit { OUTPUT.close }
|
11
|
+
else
|
12
|
+
OUTPUT = STDOUT
|
13
|
+
end
|
14
|
+
|
15
|
+
def mktable(rettype, fnum, argc)
|
16
|
+
code =
|
17
|
+
"rb_dl_callback_table[#{rettype}][#{fnum}] = &rb_dl_callback_func_#{rettype.to_s}_#{fnum};"
|
18
|
+
return code
|
19
|
+
end
|
20
|
+
|
21
|
+
DLTYPE.keys.sort.each{|t|
|
22
|
+
for n in 0..(MAX_CALLBACK - 1)
|
23
|
+
OUTPUT.print(mktable(t, n, 15), "\n")
|
24
|
+
end
|
25
|
+
}
|
data/ext/rubysl/dl/ptr.c
ADDED
@@ -0,0 +1,1062 @@
|
|
1
|
+
/* -*- C -*-
|
2
|
+
* $Id: ptr.c 15471 2008-02-14 08:46:06Z matz $
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "ruby.h"
|
6
|
+
#include <ctype.h>
|
7
|
+
#ifdef HAVE_RUBY_ST_H
|
8
|
+
#include "ruby/st.h"
|
9
|
+
#else
|
10
|
+
#include "st.h"
|
11
|
+
#endif
|
12
|
+
#include "dl.h"
|
13
|
+
|
14
|
+
VALUE rb_cDLPtrData;
|
15
|
+
VALUE rb_mDLMemorySpace;
|
16
|
+
static st_table* st_memory_table;
|
17
|
+
|
18
|
+
#ifndef T_SYMBOL
|
19
|
+
# define T_SYMBOL T_FIXNUM
|
20
|
+
#endif
|
21
|
+
|
22
|
+
static void
|
23
|
+
rb_dlmem_delete(void *ptr)
|
24
|
+
{
|
25
|
+
st_delete(st_memory_table, (st_data_t*)&ptr, NULL);
|
26
|
+
}
|
27
|
+
|
28
|
+
static void
|
29
|
+
rb_dlmem_aset(void *ptr, VALUE obj)
|
30
|
+
{
|
31
|
+
if (obj == Qnil) {
|
32
|
+
rb_dlmem_delete(ptr);
|
33
|
+
}
|
34
|
+
else{
|
35
|
+
st_insert(st_memory_table, (st_data_t)ptr, (st_data_t)obj);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE
|
40
|
+
rb_dlmem_aref(void *ptr)
|
41
|
+
{
|
42
|
+
VALUE val;
|
43
|
+
|
44
|
+
if(!st_lookup(st_memory_table, (st_data_t)ptr, (st_data_t*)(&val))) return Qnil;
|
45
|
+
return val == Qundef ? Qnil : val;
|
46
|
+
}
|
47
|
+
|
48
|
+
void
|
49
|
+
dlptr_free(struct ptr_data *data)
|
50
|
+
{
|
51
|
+
if (data->ptr) {
|
52
|
+
DEBUG_CODE({
|
53
|
+
printf("dlptr_free(): removing the pointer `0x%x' from the MemorySpace\n",
|
54
|
+
data->ptr);
|
55
|
+
});
|
56
|
+
rb_dlmem_delete(data->ptr);
|
57
|
+
if (data->free) {
|
58
|
+
DEBUG_CODE({
|
59
|
+
printf("dlptr_free(): 0x%x(data->ptr:0x%x)\n",data->free,data->ptr);
|
60
|
+
});
|
61
|
+
(*(data->free))(data->ptr);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
if (data->stype) dlfree(data->stype);
|
65
|
+
if (data->ssize) dlfree(data->ssize);
|
66
|
+
if (data->ids) dlfree(data->ids);
|
67
|
+
}
|
68
|
+
|
69
|
+
void
|
70
|
+
dlptr_init(VALUE val)
|
71
|
+
{
|
72
|
+
struct ptr_data *data;
|
73
|
+
|
74
|
+
Data_Get_Struct(val, struct ptr_data, data);
|
75
|
+
DEBUG_CODE({
|
76
|
+
printf("dlptr_init(): add the pointer `0x%x' to the MemorySpace\n",
|
77
|
+
data->ptr);
|
78
|
+
});
|
79
|
+
rb_dlmem_aset(data->ptr, val);
|
80
|
+
OBJ_TAINT(val);
|
81
|
+
}
|
82
|
+
|
83
|
+
VALUE
|
84
|
+
rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
85
|
+
{
|
86
|
+
struct ptr_data *data;
|
87
|
+
VALUE val;
|
88
|
+
|
89
|
+
rb_secure(4);
|
90
|
+
if (ptr) {
|
91
|
+
val = rb_dlmem_aref(ptr);
|
92
|
+
if (val == Qnil) {
|
93
|
+
val = Data_Make_Struct(klass, struct ptr_data,
|
94
|
+
0, dlptr_free, data);
|
95
|
+
data->ptr = ptr;
|
96
|
+
data->free = func;
|
97
|
+
data->ctype = DLPTR_CTYPE_UNKNOWN;
|
98
|
+
data->stype = NULL;
|
99
|
+
data->ssize = NULL;
|
100
|
+
data->slen = 0;
|
101
|
+
data->size = size;
|
102
|
+
data->ids = NULL;
|
103
|
+
data->ids_num = 0;
|
104
|
+
dlptr_init(val);
|
105
|
+
}
|
106
|
+
else{
|
107
|
+
if (func) {
|
108
|
+
Data_Get_Struct(val, struct ptr_data, data);
|
109
|
+
data->free = func;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
else{
|
114
|
+
val = Qnil;
|
115
|
+
}
|
116
|
+
|
117
|
+
return val;
|
118
|
+
}
|
119
|
+
|
120
|
+
VALUE
|
121
|
+
rb_dlptr_new(void *ptr, long size, freefunc_t func)
|
122
|
+
{
|
123
|
+
return rb_dlptr_new2(rb_cDLPtrData, ptr, size, func);
|
124
|
+
}
|
125
|
+
|
126
|
+
VALUE
|
127
|
+
rb_dlptr_malloc(long size, freefunc_t func)
|
128
|
+
{
|
129
|
+
void *ptr;
|
130
|
+
|
131
|
+
rb_secure(4);
|
132
|
+
ptr = dlmalloc((size_t)size);
|
133
|
+
memset(ptr,0,(size_t)size);
|
134
|
+
return rb_dlptr_new(ptr, size, func);
|
135
|
+
}
|
136
|
+
|
137
|
+
void *
|
138
|
+
rb_dlptr2cptr(VALUE val)
|
139
|
+
{
|
140
|
+
struct ptr_data *data;
|
141
|
+
void *ptr;
|
142
|
+
|
143
|
+
if (rb_obj_is_kind_of(val, rb_cDLPtrData)) {
|
144
|
+
Data_Get_Struct(val, struct ptr_data, data);
|
145
|
+
ptr = data->ptr;
|
146
|
+
}
|
147
|
+
else if (val == Qnil) {
|
148
|
+
ptr = NULL;
|
149
|
+
}
|
150
|
+
else{
|
151
|
+
rb_raise(rb_eTypeError, "DL::PtrData was expected");
|
152
|
+
}
|
153
|
+
|
154
|
+
return ptr;
|
155
|
+
}
|
156
|
+
|
157
|
+
static VALUE
|
158
|
+
rb_dlptr_s_allocate(VALUE klass)
|
159
|
+
{
|
160
|
+
VALUE obj;
|
161
|
+
struct ptr_data *data;
|
162
|
+
|
163
|
+
rb_secure(4);
|
164
|
+
obj = Data_Make_Struct(klass, struct ptr_data, 0, dlptr_free, data);
|
165
|
+
data->ptr = 0;
|
166
|
+
data->free = 0;
|
167
|
+
data->ctype = DLPTR_CTYPE_UNKNOWN;
|
168
|
+
data->stype = NULL;
|
169
|
+
data->ssize = NULL;
|
170
|
+
data->slen = 0;
|
171
|
+
data->size = 0;
|
172
|
+
data->ids = NULL;
|
173
|
+
data->ids_num = 0;
|
174
|
+
|
175
|
+
return obj;
|
176
|
+
}
|
177
|
+
|
178
|
+
static VALUE
|
179
|
+
rb_dlptr_initialize(int argc, VALUE argv[], VALUE self)
|
180
|
+
{
|
181
|
+
VALUE ptr, sym, size;
|
182
|
+
struct ptr_data *data;
|
183
|
+
void *p = NULL;
|
184
|
+
freefunc_t f = NULL;
|
185
|
+
long s = 0;
|
186
|
+
|
187
|
+
switch (rb_scan_args(argc, argv, "12", &ptr, &size, &sym)) {
|
188
|
+
case 1:
|
189
|
+
p = (void*)(DLNUM2LONG(rb_Integer(ptr)));
|
190
|
+
break;
|
191
|
+
case 2:
|
192
|
+
p = (void*)(DLNUM2LONG(rb_Integer(ptr)));
|
193
|
+
s = DLNUM2LONG(size);
|
194
|
+
break;
|
195
|
+
case 3:
|
196
|
+
p = (void*)(DLNUM2LONG(rb_Integer(ptr)));
|
197
|
+
s = DLNUM2LONG(size);
|
198
|
+
f = rb_dlsym2csym(sym);
|
199
|
+
break;
|
200
|
+
default:
|
201
|
+
rb_bug("rb_dlptr_initialize");
|
202
|
+
}
|
203
|
+
|
204
|
+
if (p) {
|
205
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
206
|
+
if (data->ptr && data->free) {
|
207
|
+
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
|
208
|
+
(*(data->free))(data->ptr);
|
209
|
+
}
|
210
|
+
data->ptr = p;
|
211
|
+
data->size = s;
|
212
|
+
data->free = f;
|
213
|
+
}
|
214
|
+
|
215
|
+
return Qnil;
|
216
|
+
}
|
217
|
+
|
218
|
+
static VALUE
|
219
|
+
rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
|
220
|
+
{
|
221
|
+
VALUE size, sym, obj;
|
222
|
+
int s = 0;
|
223
|
+
freefunc_t f = NULL;
|
224
|
+
|
225
|
+
switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
|
226
|
+
case 1:
|
227
|
+
s = NUM2INT(size);
|
228
|
+
break;
|
229
|
+
case 2:
|
230
|
+
s = NUM2INT(size);
|
231
|
+
f = rb_dlsym2csym(sym);
|
232
|
+
break;
|
233
|
+
default:
|
234
|
+
rb_bug("rb_dlptr_s_malloc");
|
235
|
+
}
|
236
|
+
|
237
|
+
obj = rb_dlptr_malloc(s,f);
|
238
|
+
|
239
|
+
return obj;
|
240
|
+
}
|
241
|
+
|
242
|
+
VALUE
|
243
|
+
rb_dlptr_to_i(VALUE self)
|
244
|
+
{
|
245
|
+
struct ptr_data *data;
|
246
|
+
|
247
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
248
|
+
return DLLONG2NUM(data->ptr);
|
249
|
+
}
|
250
|
+
|
251
|
+
VALUE
|
252
|
+
rb_dlptr_ptr(VALUE self)
|
253
|
+
{
|
254
|
+
struct ptr_data *data;
|
255
|
+
|
256
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
257
|
+
return rb_dlptr_new(*((void**)(data->ptr)),0,0);
|
258
|
+
}
|
259
|
+
|
260
|
+
VALUE
|
261
|
+
rb_dlptr_ref(VALUE self)
|
262
|
+
{
|
263
|
+
struct ptr_data *data;
|
264
|
+
|
265
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
266
|
+
return rb_dlptr_new(&(data->ptr),0,0);
|
267
|
+
}
|
268
|
+
|
269
|
+
VALUE
|
270
|
+
rb_dlptr_null_p(VALUE self)
|
271
|
+
{
|
272
|
+
struct ptr_data *data;
|
273
|
+
|
274
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
275
|
+
return data->ptr ? Qfalse : Qtrue;
|
276
|
+
}
|
277
|
+
|
278
|
+
VALUE
|
279
|
+
rb_dlptr_free_set(VALUE self, VALUE val)
|
280
|
+
{
|
281
|
+
struct ptr_data *data;
|
282
|
+
|
283
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
284
|
+
|
285
|
+
data->free = DLFREEFUNC(rb_dlsym2csym(val));
|
286
|
+
|
287
|
+
return Qnil;
|
288
|
+
}
|
289
|
+
|
290
|
+
VALUE
|
291
|
+
rb_dlptr_free_get(VALUE self)
|
292
|
+
{
|
293
|
+
struct ptr_data *pdata;
|
294
|
+
|
295
|
+
Data_Get_Struct(self, struct ptr_data, pdata);
|
296
|
+
|
297
|
+
return rb_dlsym_new(pdata->free,"(free)","0P");
|
298
|
+
}
|
299
|
+
|
300
|
+
VALUE
|
301
|
+
rb_dlptr_to_array(int argc, VALUE argv[], VALUE self)
|
302
|
+
{
|
303
|
+
struct ptr_data *data;
|
304
|
+
int n = 0;
|
305
|
+
int i;
|
306
|
+
int t = 0;
|
307
|
+
VALUE ary;
|
308
|
+
VALUE type, size;
|
309
|
+
|
310
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
311
|
+
|
312
|
+
switch (rb_scan_args(argc, argv, "11", &type, &size)) {
|
313
|
+
case 2:
|
314
|
+
t = StringValuePtr(type)[0];
|
315
|
+
n = NUM2INT(size);
|
316
|
+
break;
|
317
|
+
case 1:
|
318
|
+
t = StringValuePtr(type)[0];
|
319
|
+
switch (t) {
|
320
|
+
case 'C':
|
321
|
+
n = data->size;
|
322
|
+
break;
|
323
|
+
case 'H':
|
324
|
+
n = data->size / sizeof(short);
|
325
|
+
break;
|
326
|
+
case 'I':
|
327
|
+
n = data->size / sizeof(int);
|
328
|
+
break;
|
329
|
+
case 'L':
|
330
|
+
n = data->size / sizeof(long);
|
331
|
+
break;
|
332
|
+
case 'F':
|
333
|
+
n = data->size / sizeof(float);
|
334
|
+
break;
|
335
|
+
case 'D':
|
336
|
+
n = data->size / sizeof(double);
|
337
|
+
break;
|
338
|
+
case 'P': case 'p':
|
339
|
+
n = data->size / sizeof(void*);
|
340
|
+
break;
|
341
|
+
case 'S': case 's':
|
342
|
+
n = data->size / sizeof(char*);
|
343
|
+
break;
|
344
|
+
default:
|
345
|
+
n = 0;
|
346
|
+
}
|
347
|
+
break;
|
348
|
+
default:
|
349
|
+
rb_bug("rb_dlptr_to_array");
|
350
|
+
}
|
351
|
+
|
352
|
+
ary = rb_ary_new();
|
353
|
+
|
354
|
+
for (i=0; i < n; i++) {
|
355
|
+
switch (t) {
|
356
|
+
case 'C':
|
357
|
+
rb_ary_push(ary, INT2NUM(((char*)(data->ptr))[i]));
|
358
|
+
break;
|
359
|
+
case 'H':
|
360
|
+
rb_ary_push(ary, INT2NUM(((short*)(data->ptr))[i]));
|
361
|
+
break;
|
362
|
+
case 'I':
|
363
|
+
rb_ary_push(ary, INT2NUM(((int*)(data->ptr))[i]));
|
364
|
+
break;
|
365
|
+
case 'L':
|
366
|
+
rb_ary_push(ary, DLLONG2NUM(((long*)(data->ptr))[i]));
|
367
|
+
break;
|
368
|
+
case 'D':
|
369
|
+
rb_ary_push(ary, rb_float_new(((double*)(data->ptr))[i]));
|
370
|
+
break;
|
371
|
+
case 'F':
|
372
|
+
rb_ary_push(ary, rb_float_new(((float*)(data->ptr))[i]));
|
373
|
+
break;
|
374
|
+
case 'S':
|
375
|
+
{
|
376
|
+
char *str = ((char**)(data->ptr))[i];
|
377
|
+
if (str) {
|
378
|
+
rb_ary_push(ary, rb_tainted_str_new2(str));
|
379
|
+
}
|
380
|
+
else{
|
381
|
+
rb_ary_push(ary, Qnil);
|
382
|
+
}
|
383
|
+
}
|
384
|
+
break;
|
385
|
+
case 's':
|
386
|
+
{
|
387
|
+
char *str = ((char**)(data->ptr))[i];
|
388
|
+
if (str) {
|
389
|
+
rb_ary_push(ary, rb_tainted_str_new2(str));
|
390
|
+
xfree(str);
|
391
|
+
}
|
392
|
+
else{
|
393
|
+
rb_ary_push(ary, Qnil);
|
394
|
+
}
|
395
|
+
}
|
396
|
+
break;
|
397
|
+
case 'P':
|
398
|
+
rb_ary_push(ary, rb_dlptr_new(((void**)(data->ptr))[i],0,0));
|
399
|
+
break;
|
400
|
+
case 'p':
|
401
|
+
rb_ary_push(ary,
|
402
|
+
rb_dlptr_new(((void**)(data->ptr))[i],0,dlfree));
|
403
|
+
break;
|
404
|
+
}
|
405
|
+
}
|
406
|
+
|
407
|
+
return ary;
|
408
|
+
}
|
409
|
+
|
410
|
+
|
411
|
+
VALUE
|
412
|
+
rb_dlptr_to_s(int argc, VALUE argv[], VALUE self)
|
413
|
+
{
|
414
|
+
struct ptr_data *data;
|
415
|
+
VALUE arg1, val = Qnil;
|
416
|
+
int len;
|
417
|
+
|
418
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
419
|
+
switch (rb_scan_args(argc, argv, "01", &arg1)) {
|
420
|
+
case 0:
|
421
|
+
val = rb_tainted_str_new2((char*)(data->ptr));
|
422
|
+
break;
|
423
|
+
case 1:
|
424
|
+
len = NUM2INT(arg1);
|
425
|
+
val = rb_tainted_str_new((char*)(data->ptr), len);
|
426
|
+
break;
|
427
|
+
default:
|
428
|
+
rb_bug("rb_dlptr_to_s");
|
429
|
+
}
|
430
|
+
|
431
|
+
return val;
|
432
|
+
}
|
433
|
+
|
434
|
+
VALUE
|
435
|
+
rb_dlptr_to_str(int argc, VALUE argv[], VALUE self)
|
436
|
+
{
|
437
|
+
struct ptr_data *data;
|
438
|
+
VALUE arg1, val = Qnil;
|
439
|
+
int len;
|
440
|
+
|
441
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
442
|
+
switch (rb_scan_args(argc, argv, "01", &arg1)) {
|
443
|
+
case 0:
|
444
|
+
val = rb_tainted_str_new((char*)(data->ptr),data->size);
|
445
|
+
break;
|
446
|
+
case 1:
|
447
|
+
len = NUM2INT(arg1);
|
448
|
+
val = rb_tainted_str_new((char*)(data->ptr), len);
|
449
|
+
break;
|
450
|
+
default:
|
451
|
+
rb_bug("rb_dlptr_to_str");
|
452
|
+
}
|
453
|
+
|
454
|
+
return val;
|
455
|
+
}
|
456
|
+
|
457
|
+
VALUE
|
458
|
+
rb_dlptr_inspect(VALUE self)
|
459
|
+
{
|
460
|
+
struct ptr_data *data;
|
461
|
+
char str[1024];
|
462
|
+
|
463
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
464
|
+
snprintf(str, 1023, "#<%s:0x%lx ptr=0x%lx size=%ld free=0x%lx>",
|
465
|
+
rb_class2name(CLASS_OF(self)), (long unsigned)data,
|
466
|
+
(long unsigned)data->ptr, data->size,
|
467
|
+
(long)data->free);
|
468
|
+
return rb_str_new2(str);
|
469
|
+
}
|
470
|
+
|
471
|
+
VALUE
|
472
|
+
rb_dlptr_eql(VALUE self, VALUE other)
|
473
|
+
{
|
474
|
+
void *ptr1, *ptr2;
|
475
|
+
ptr1 = rb_dlptr2cptr(self);
|
476
|
+
ptr2 = rb_dlptr2cptr(other);
|
477
|
+
|
478
|
+
return ptr1 == ptr2 ? Qtrue : Qfalse;
|
479
|
+
}
|
480
|
+
|
481
|
+
VALUE
|
482
|
+
rb_dlptr_cmp(VALUE self, VALUE other)
|
483
|
+
{
|
484
|
+
void *ptr1, *ptr2;
|
485
|
+
ptr1 = rb_dlptr2cptr(self);
|
486
|
+
ptr2 = rb_dlptr2cptr(other);
|
487
|
+
return DLLONG2NUM((long)ptr1 - (long)ptr2);
|
488
|
+
}
|
489
|
+
|
490
|
+
VALUE
|
491
|
+
rb_dlptr_plus(VALUE self, VALUE other)
|
492
|
+
{
|
493
|
+
void *ptr;
|
494
|
+
long num, size;
|
495
|
+
|
496
|
+
ptr = rb_dlptr2cptr(self);
|
497
|
+
size = RDLPTR(self)->size;
|
498
|
+
num = DLNUM2LONG(other);
|
499
|
+
return rb_dlptr_new((char *)ptr + num, size - num, 0);
|
500
|
+
}
|
501
|
+
|
502
|
+
VALUE
|
503
|
+
rb_dlptr_minus(VALUE self, VALUE other)
|
504
|
+
{
|
505
|
+
void *ptr;
|
506
|
+
long num, size;
|
507
|
+
|
508
|
+
ptr = rb_dlptr2cptr(self);
|
509
|
+
size = RDLPTR(self)->size;
|
510
|
+
num = DLNUM2LONG(other);
|
511
|
+
return rb_dlptr_new((char *)ptr - num, size + num, 0);
|
512
|
+
}
|
513
|
+
|
514
|
+
VALUE
|
515
|
+
rb_dlptr_define_data_type(int argc, VALUE argv[], VALUE self)
|
516
|
+
{
|
517
|
+
VALUE data_type, type, rest, vid;
|
518
|
+
struct ptr_data *data;
|
519
|
+
int i, t, num;
|
520
|
+
char *ctype;
|
521
|
+
|
522
|
+
rb_scan_args(argc, argv, "11*", &data_type, &type, &rest);
|
523
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
524
|
+
|
525
|
+
if (argc == 1 || (argc == 2 && type == Qnil)) {
|
526
|
+
if (NUM2INT(data_type) == DLPTR_CTYPE_UNKNOWN) {
|
527
|
+
data->ctype = DLPTR_CTYPE_UNKNOWN;
|
528
|
+
data->slen = 0;
|
529
|
+
data->ids_num = 0;
|
530
|
+
if (data->stype) {
|
531
|
+
dlfree(data->stype);
|
532
|
+
data->stype = NULL;
|
533
|
+
}
|
534
|
+
if (data->ids) {
|
535
|
+
dlfree(data->ids);
|
536
|
+
data->ids = NULL;
|
537
|
+
}
|
538
|
+
return Qnil;
|
539
|
+
}
|
540
|
+
else{
|
541
|
+
rb_raise(rb_eArgError, "wrong arguments");
|
542
|
+
}
|
543
|
+
}
|
544
|
+
|
545
|
+
t = NUM2INT(data_type);
|
546
|
+
StringValue(type);
|
547
|
+
Check_Type(rest, T_ARRAY);
|
548
|
+
num = RARRAY_LEN(rest);
|
549
|
+
for (i=0; i<num; i++) {
|
550
|
+
rb_to_id(rb_ary_entry(rest,i));
|
551
|
+
}
|
552
|
+
|
553
|
+
data->ctype = t;
|
554
|
+
data->slen = num;
|
555
|
+
data->ids_num = num;
|
556
|
+
if (data->stype) dlfree(data->stype);
|
557
|
+
data->stype = (char*)dlmalloc(sizeof(char) * num);
|
558
|
+
if (data->ssize) dlfree(data->ssize);
|
559
|
+
data->ssize = (int*)dlmalloc(sizeof(int) * num);
|
560
|
+
if (data->ids) dlfree(data->ids);
|
561
|
+
data->ids = (ID*)dlmalloc(sizeof(ID) * data->ids_num);
|
562
|
+
|
563
|
+
ctype = StringValuePtr(type);
|
564
|
+
for (i=0; i<num; i++) {
|
565
|
+
vid = rb_ary_entry(rest,i);
|
566
|
+
data->ids[i] = rb_to_id(vid);
|
567
|
+
data->stype[i] = *ctype;
|
568
|
+
ctype ++;
|
569
|
+
if (isdigit(*ctype)) {
|
570
|
+
char *p, *d;
|
571
|
+
for (p=ctype; isdigit(*p); p++) ;
|
572
|
+
d = ALLOCA_N(char, p - ctype + 1);
|
573
|
+
strncpy(d, ctype, p - ctype);
|
574
|
+
d[p - ctype] = '\0';
|
575
|
+
data->ssize[i] = atoi(d);
|
576
|
+
ctype = p;
|
577
|
+
}
|
578
|
+
else{
|
579
|
+
data->ssize[i] = 1;
|
580
|
+
}
|
581
|
+
}
|
582
|
+
|
583
|
+
if (*ctype) {
|
584
|
+
rb_raise(rb_eArgError, "too few/many arguments");
|
585
|
+
}
|
586
|
+
|
587
|
+
if (!data->size)
|
588
|
+
data->size = dlsizeof(RSTRING(type)->ptr);
|
589
|
+
|
590
|
+
return Qnil;
|
591
|
+
}
|
592
|
+
|
593
|
+
VALUE
|
594
|
+
rb_dlptr_define_struct(int argc, VALUE argv[], VALUE self)
|
595
|
+
{
|
596
|
+
VALUE *pass_argv;
|
597
|
+
int pass_argc, i;
|
598
|
+
|
599
|
+
pass_argc = argc + 1;
|
600
|
+
pass_argv = ALLOCA_N(VALUE, pass_argc);
|
601
|
+
pass_argv[0] = INT2FIX(DLPTR_CTYPE_STRUCT);
|
602
|
+
for (i=1; i<pass_argc; i++) {
|
603
|
+
pass_argv[i] = argv[i-1];
|
604
|
+
}
|
605
|
+
return rb_dlptr_define_data_type(pass_argc, pass_argv, self);
|
606
|
+
}
|
607
|
+
|
608
|
+
VALUE
|
609
|
+
rb_dlptr_define_union(int argc, VALUE argv[], VALUE self)
|
610
|
+
{
|
611
|
+
VALUE *pass_argv;
|
612
|
+
int pass_argc, i;
|
613
|
+
|
614
|
+
pass_argc = argc + 1;
|
615
|
+
pass_argv = ALLOCA_N(VALUE, pass_argc);
|
616
|
+
pass_argv[0] = INT2FIX(DLPTR_CTYPE_UNION);
|
617
|
+
for (i=1; i<pass_argc; i++) {
|
618
|
+
pass_argv[i] = argv[i-1];
|
619
|
+
}
|
620
|
+
return rb_dlptr_define_data_type(pass_argc, pass_argv, self);
|
621
|
+
}
|
622
|
+
|
623
|
+
VALUE
|
624
|
+
rb_dlptr_get_data_type(VALUE self)
|
625
|
+
{
|
626
|
+
struct ptr_data *data;
|
627
|
+
|
628
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
629
|
+
if (data->stype)
|
630
|
+
return rb_assoc_new(INT2FIX(data->ctype),
|
631
|
+
rb_tainted_str_new(data->stype, data->slen));
|
632
|
+
else
|
633
|
+
return rb_assoc_new(INT2FIX(data->ctype), Qnil);
|
634
|
+
}
|
635
|
+
|
636
|
+
static VALUE
|
637
|
+
cary2ary(void *ptr, char t, int len)
|
638
|
+
{
|
639
|
+
VALUE ary;
|
640
|
+
VALUE elem;
|
641
|
+
int i;
|
642
|
+
|
643
|
+
if (len < 1)
|
644
|
+
return Qnil;
|
645
|
+
|
646
|
+
if (len == 1) {
|
647
|
+
switch (t) {
|
648
|
+
case 'I':
|
649
|
+
elem = INT2NUM(*((int*)ptr));
|
650
|
+
ptr = (char *)ptr + sizeof(int);
|
651
|
+
break;
|
652
|
+
case 'L':
|
653
|
+
elem = DLLONG2NUM(*((long*)ptr));
|
654
|
+
ptr = (char *)ptr + sizeof(long);
|
655
|
+
break;
|
656
|
+
case 'P':
|
657
|
+
case 'S':
|
658
|
+
elem = rb_dlptr_new(*((void**)ptr),0, 0);
|
659
|
+
ptr = (char *)ptr + sizeof(void*);
|
660
|
+
break;
|
661
|
+
case 'F':
|
662
|
+
elem = rb_float_new(*((float*)ptr));
|
663
|
+
ptr = (char *)ptr + sizeof(float);
|
664
|
+
break;
|
665
|
+
case 'D':
|
666
|
+
elem = rb_float_new(*((double*)ptr));
|
667
|
+
ptr = (char *)ptr + sizeof(double);
|
668
|
+
break;
|
669
|
+
case 'C':
|
670
|
+
elem = INT2NUM(*((char*)ptr));
|
671
|
+
ptr = (char *)ptr + sizeof(char);
|
672
|
+
break;
|
673
|
+
case 'H':
|
674
|
+
elem = INT2NUM(*((short*)ptr));
|
675
|
+
ptr = (char *)ptr + sizeof(short);
|
676
|
+
break;
|
677
|
+
default:
|
678
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", t);
|
679
|
+
}
|
680
|
+
return elem;
|
681
|
+
}
|
682
|
+
|
683
|
+
ary = rb_ary_new();
|
684
|
+
for (i=0; i < len; i++) {
|
685
|
+
switch (t) {
|
686
|
+
case 'I':
|
687
|
+
elem = INT2NUM(*((int*)ptr));
|
688
|
+
ptr = (char *)ptr + sizeof(int);
|
689
|
+
break;
|
690
|
+
case 'L':
|
691
|
+
elem = DLLONG2NUM(*((long*)ptr));
|
692
|
+
ptr = (char *)ptr + sizeof(long);
|
693
|
+
break;
|
694
|
+
case 'P':
|
695
|
+
case 'S':
|
696
|
+
elem = rb_dlptr_new(*((void**)ptr), 0, 0);
|
697
|
+
ptr = (char *)ptr + sizeof(void*);
|
698
|
+
break;
|
699
|
+
case 'F':
|
700
|
+
elem = rb_float_new(*((float*)ptr));
|
701
|
+
ptr = (char *)ptr + sizeof(float);
|
702
|
+
break;
|
703
|
+
case 'D':
|
704
|
+
elem = rb_float_new(*((float*)ptr));
|
705
|
+
ptr = (char *)ptr + sizeof(double);
|
706
|
+
break;
|
707
|
+
case 'C':
|
708
|
+
elem = INT2NUM(*((char*)ptr));
|
709
|
+
ptr = (char *)ptr + sizeof(char);
|
710
|
+
break;
|
711
|
+
case 'H':
|
712
|
+
elem = INT2NUM(*((short*)ptr));
|
713
|
+
ptr = (char *)ptr + sizeof(short);
|
714
|
+
break;
|
715
|
+
default:
|
716
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", t);
|
717
|
+
}
|
718
|
+
rb_ary_push(ary, elem);
|
719
|
+
}
|
720
|
+
|
721
|
+
return ary;
|
722
|
+
}
|
723
|
+
|
724
|
+
VALUE
|
725
|
+
rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
|
726
|
+
{
|
727
|
+
VALUE key = Qnil, num = Qnil;
|
728
|
+
ID id;
|
729
|
+
struct ptr_data *data;
|
730
|
+
int i;
|
731
|
+
int offset;
|
732
|
+
|
733
|
+
if (rb_scan_args(argc, argv, "11", &key, &num) == 1) {
|
734
|
+
num = INT2NUM(0);
|
735
|
+
}
|
736
|
+
|
737
|
+
if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) {
|
738
|
+
VALUE pass[1];
|
739
|
+
pass[0] = num;
|
740
|
+
return rb_dlptr_to_str(1, pass, rb_dlptr_plus(self, key));
|
741
|
+
}
|
742
|
+
rb_to_id(key);
|
743
|
+
if (! (TYPE(key) == T_STRING || TYPE(key) == T_SYMBOL)) {
|
744
|
+
rb_raise(rb_eTypeError, "the key must be a string or symbol");
|
745
|
+
}
|
746
|
+
|
747
|
+
id = rb_to_id(key);
|
748
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
749
|
+
offset = 0;
|
750
|
+
switch (data->ctype) {
|
751
|
+
case DLPTR_CTYPE_STRUCT:
|
752
|
+
for (i=0; i < data->ids_num; i++) {
|
753
|
+
switch (data->stype[i]) {
|
754
|
+
case 'I':
|
755
|
+
DLALIGN(data->ptr,offset,INT_ALIGN);
|
756
|
+
break;
|
757
|
+
case 'L':
|
758
|
+
DLALIGN(data->ptr,offset,LONG_ALIGN);
|
759
|
+
break;
|
760
|
+
case 'P':
|
761
|
+
case 'S':
|
762
|
+
DLALIGN(data->ptr,offset,VOIDP_ALIGN);
|
763
|
+
break;
|
764
|
+
case 'F':
|
765
|
+
DLALIGN(data->ptr,offset,FLOAT_ALIGN);
|
766
|
+
break;
|
767
|
+
case 'D':
|
768
|
+
DLALIGN(data->ptr,offset,DOUBLE_ALIGN);
|
769
|
+
break;
|
770
|
+
case 'C':
|
771
|
+
break;
|
772
|
+
case 'H':
|
773
|
+
DLALIGN(data->ptr,offset,SHORT_ALIGN);
|
774
|
+
break;
|
775
|
+
default:
|
776
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]);
|
777
|
+
}
|
778
|
+
if (data->ids[i] == id) {
|
779
|
+
return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);
|
780
|
+
}
|
781
|
+
switch (data->stype[i]) {
|
782
|
+
case 'I':
|
783
|
+
offset += sizeof(int) * data->ssize[i];
|
784
|
+
break;
|
785
|
+
case 'L':
|
786
|
+
offset += sizeof(long) * data->ssize[i];
|
787
|
+
break;
|
788
|
+
case 'P':
|
789
|
+
case 'S':
|
790
|
+
offset += sizeof(void*) * data->ssize[i];
|
791
|
+
break;
|
792
|
+
case 'F':
|
793
|
+
offset += sizeof(float) * data->ssize[i];
|
794
|
+
break;
|
795
|
+
case 'D':
|
796
|
+
offset += sizeof(double) * data->ssize[i];
|
797
|
+
break;
|
798
|
+
case 'C':
|
799
|
+
offset += sizeof(char) * data->ssize[i];
|
800
|
+
break;
|
801
|
+
case 'H':
|
802
|
+
offset += sizeof(short) * data->ssize[i];
|
803
|
+
break;
|
804
|
+
default:
|
805
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]);
|
806
|
+
}
|
807
|
+
}
|
808
|
+
break;
|
809
|
+
case DLPTR_CTYPE_UNION:
|
810
|
+
for (i=0; i < data->ids_num; i++) {
|
811
|
+
if (data->ids[i] == id) {
|
812
|
+
return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);
|
813
|
+
}
|
814
|
+
}
|
815
|
+
break;
|
816
|
+
} /* end of switch */
|
817
|
+
|
818
|
+
rb_raise(rb_eNameError, "undefined key `%s' for %s",
|
819
|
+
rb_id2name(id), rb_class2name(CLASS_OF(self)));
|
820
|
+
|
821
|
+
return Qnil;
|
822
|
+
}
|
823
|
+
|
824
|
+
static void *
|
825
|
+
ary2cary(char t, VALUE val, long *size)
|
826
|
+
{
|
827
|
+
void *ptr;
|
828
|
+
|
829
|
+
if (TYPE(val) == T_ARRAY) {
|
830
|
+
ptr = rb_ary2cary(t, val, size);
|
831
|
+
}
|
832
|
+
else{
|
833
|
+
ptr = rb_ary2cary(t, rb_ary_new3(1, val), size);
|
834
|
+
}
|
835
|
+
return ptr;
|
836
|
+
}
|
837
|
+
|
838
|
+
VALUE
|
839
|
+
rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
|
840
|
+
{
|
841
|
+
VALUE key = Qnil, num = Qnil, val = Qnil;
|
842
|
+
ID id;
|
843
|
+
struct ptr_data *data;
|
844
|
+
int i;
|
845
|
+
int offset;
|
846
|
+
long memsize;
|
847
|
+
void *memimg;
|
848
|
+
|
849
|
+
rb_secure(4);
|
850
|
+
switch (rb_scan_args(argc, argv, "21", &key, &num, &val)) {
|
851
|
+
case 2:
|
852
|
+
val = num;
|
853
|
+
num = Qnil;
|
854
|
+
break;
|
855
|
+
}
|
856
|
+
|
857
|
+
if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) {
|
858
|
+
void *dst, *src;
|
859
|
+
long len;
|
860
|
+
|
861
|
+
StringValue(val);
|
862
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
863
|
+
dst = (void*)((long)(data->ptr) + DLNUM2LONG(key));
|
864
|
+
src = RSTRING(val)->ptr;
|
865
|
+
len = RSTRING(val)->len;
|
866
|
+
if (num == Qnil) {
|
867
|
+
memcpy(dst, src, len);
|
868
|
+
}
|
869
|
+
else{
|
870
|
+
long n = NUM2INT(num);
|
871
|
+
memcpy(dst, src, n < len ? n : len);
|
872
|
+
if (n > len) MEMZERO((char*)dst + len, char, n - len);
|
873
|
+
}
|
874
|
+
return val;
|
875
|
+
}
|
876
|
+
|
877
|
+
id = rb_to_id(key);
|
878
|
+
Data_Get_Struct(self, struct ptr_data, data);
|
879
|
+
switch (data->ctype) {
|
880
|
+
case DLPTR_CTYPE_STRUCT:
|
881
|
+
offset = 0;
|
882
|
+
for (i=0; i < data->ids_num; i++) {
|
883
|
+
switch (data->stype[i]) {
|
884
|
+
case 'I':
|
885
|
+
DLALIGN(data->ptr,offset,INT_ALIGN);
|
886
|
+
break;
|
887
|
+
case 'L':
|
888
|
+
DLALIGN(data->ptr,offset,LONG_ALIGN);
|
889
|
+
break;
|
890
|
+
case 'P':
|
891
|
+
case 'S':
|
892
|
+
DLALIGN(data->ptr,offset,VOIDP_ALIGN);
|
893
|
+
break;
|
894
|
+
case 'D':
|
895
|
+
DLALIGN(data->ptr,offset,DOUBLE_ALIGN);
|
896
|
+
break;
|
897
|
+
case 'F':
|
898
|
+
DLALIGN(data->ptr,offset,FLOAT_ALIGN);
|
899
|
+
break;
|
900
|
+
case 'C':
|
901
|
+
break;
|
902
|
+
case 'H':
|
903
|
+
DLALIGN(data->ptr,offset,SHORT_ALIGN);
|
904
|
+
break;
|
905
|
+
default:
|
906
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]);
|
907
|
+
}
|
908
|
+
if (data->ids[i] == id) {
|
909
|
+
memimg = ary2cary(data->stype[i], val, &memsize);
|
910
|
+
memcpy((char *)data->ptr + offset, memimg, memsize);
|
911
|
+
dlfree(memimg);
|
912
|
+
return val;
|
913
|
+
}
|
914
|
+
switch (data->stype[i]) {
|
915
|
+
case 'I':
|
916
|
+
case 'i':
|
917
|
+
offset += sizeof(int) * data->ssize[i];
|
918
|
+
break;
|
919
|
+
case 'L':
|
920
|
+
case 'l':
|
921
|
+
offset += sizeof(long) * data->ssize[i];
|
922
|
+
break;
|
923
|
+
case 'P':
|
924
|
+
case 'p':
|
925
|
+
case 'S':
|
926
|
+
case 's':
|
927
|
+
offset += sizeof(void*) * data->ssize[i];
|
928
|
+
break;
|
929
|
+
case 'D':
|
930
|
+
case 'd':
|
931
|
+
offset += sizeof(double) * data->ssize[i];
|
932
|
+
break;
|
933
|
+
case 'F':
|
934
|
+
case 'f':
|
935
|
+
offset += sizeof(float) * data->ssize[i];
|
936
|
+
break;
|
937
|
+
case 'C':
|
938
|
+
case 'c':
|
939
|
+
offset += sizeof(char) * data->ssize[i];
|
940
|
+
break;
|
941
|
+
case 'H':
|
942
|
+
case 'h':
|
943
|
+
offset += sizeof(short) * data->ssize[i];
|
944
|
+
break;
|
945
|
+
default:
|
946
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]);
|
947
|
+
}
|
948
|
+
}
|
949
|
+
return val;
|
950
|
+
/* break; */
|
951
|
+
case DLPTR_CTYPE_UNION:
|
952
|
+
for (i=0; i < data->ids_num; i++) {
|
953
|
+
if (data->ids[i] == id) {
|
954
|
+
switch (data->stype[i]) {
|
955
|
+
case 'I': case 'i':
|
956
|
+
memsize = sizeof(int) * data->ssize[i];
|
957
|
+
break;
|
958
|
+
case 'L': case 'l':
|
959
|
+
memsize = sizeof(long) * data->ssize[i];
|
960
|
+
break;
|
961
|
+
case 'P': case 'p':
|
962
|
+
case 'S': case 's':
|
963
|
+
memsize = sizeof(void*) * data->ssize[i];
|
964
|
+
break;
|
965
|
+
case 'F': case 'f':
|
966
|
+
memsize = sizeof(float) * data->ssize[i];
|
967
|
+
break;
|
968
|
+
case 'D': case 'd':
|
969
|
+
memsize = sizeof(double) * data->ssize[i];
|
970
|
+
break;
|
971
|
+
case 'C': case 'c':
|
972
|
+
memsize = sizeof(char) * data->ssize[i];
|
973
|
+
break;
|
974
|
+
case 'H': case 'h':
|
975
|
+
memsize = sizeof(short) * data->ssize[i];
|
976
|
+
break;
|
977
|
+
default:
|
978
|
+
rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]);
|
979
|
+
}
|
980
|
+
memimg = ary2cary(data->stype[i], val, NULL);
|
981
|
+
memcpy(data->ptr, memimg, memsize);
|
982
|
+
dlfree(memimg);
|
983
|
+
}
|
984
|
+
}
|
985
|
+
return val;
|
986
|
+
/* break; */
|
987
|
+
}
|
988
|
+
|
989
|
+
rb_raise(rb_eNameError, "undefined key `%s' for %s",
|
990
|
+
rb_id2name(id), rb_class2name(CLASS_OF(self)));
|
991
|
+
|
992
|
+
return Qnil;
|
993
|
+
}
|
994
|
+
|
995
|
+
VALUE
|
996
|
+
rb_dlptr_size(int argc, VALUE argv[], VALUE self)
|
997
|
+
{
|
998
|
+
VALUE size;
|
999
|
+
|
1000
|
+
if (rb_scan_args(argc, argv, "01", &size) == 0){
|
1001
|
+
return DLLONG2NUM(RDLPTR(self)->size);
|
1002
|
+
}
|
1003
|
+
else{
|
1004
|
+
RDLPTR(self)->size = DLNUM2LONG(size);
|
1005
|
+
return size;
|
1006
|
+
}
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
static int
|
1010
|
+
dlmem_each_i(void* key, VALUE value, void* arg)
|
1011
|
+
{
|
1012
|
+
VALUE vkey = DLLONG2NUM(key);
|
1013
|
+
rb_yield(rb_assoc_new(vkey, value));
|
1014
|
+
return Qnil;
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
VALUE
|
1018
|
+
rb_dlmem_each(VALUE self)
|
1019
|
+
{
|
1020
|
+
st_foreach(st_memory_table, dlmem_each_i, 0);
|
1021
|
+
return Qnil;
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
void
|
1025
|
+
Init_dlptr()
|
1026
|
+
{
|
1027
|
+
rb_cDLPtrData = rb_define_class_under(rb_mDL, "PtrData", rb_cObject);
|
1028
|
+
rb_define_alloc_func(rb_cDLPtrData, rb_dlptr_s_allocate);
|
1029
|
+
rb_define_singleton_method(rb_cDLPtrData, "malloc", rb_dlptr_s_malloc, -1);
|
1030
|
+
rb_define_method(rb_cDLPtrData, "initialize", rb_dlptr_initialize, -1);
|
1031
|
+
rb_define_method(rb_cDLPtrData, "free=", rb_dlptr_free_set, 1);
|
1032
|
+
rb_define_method(rb_cDLPtrData, "free", rb_dlptr_free_get, 0);
|
1033
|
+
rb_define_method(rb_cDLPtrData, "to_i", rb_dlptr_to_i, 0);
|
1034
|
+
rb_define_method(rb_cDLPtrData, "ptr", rb_dlptr_ptr, 0);
|
1035
|
+
rb_define_method(rb_cDLPtrData, "+@", rb_dlptr_ptr, 0);
|
1036
|
+
rb_define_method(rb_cDLPtrData, "ref", rb_dlptr_ref, 0);
|
1037
|
+
rb_define_method(rb_cDLPtrData, "-@", rb_dlptr_ref, 0);
|
1038
|
+
rb_define_method(rb_cDLPtrData, "null?", rb_dlptr_null_p, 0);
|
1039
|
+
rb_define_method(rb_cDLPtrData, "to_a", rb_dlptr_to_array, -1);
|
1040
|
+
rb_define_method(rb_cDLPtrData, "to_s", rb_dlptr_to_s, -1);
|
1041
|
+
rb_define_method(rb_cDLPtrData, "to_str", rb_dlptr_to_str, -1);
|
1042
|
+
rb_define_method(rb_cDLPtrData, "inspect", rb_dlptr_inspect, 0);
|
1043
|
+
rb_define_method(rb_cDLPtrData, "<=>", rb_dlptr_cmp, 1);
|
1044
|
+
rb_define_method(rb_cDLPtrData, "==", rb_dlptr_eql, 1);
|
1045
|
+
rb_define_method(rb_cDLPtrData, "eql?", rb_dlptr_eql, 1);
|
1046
|
+
rb_define_method(rb_cDLPtrData, "+", rb_dlptr_plus, 1);
|
1047
|
+
rb_define_method(rb_cDLPtrData, "-", rb_dlptr_minus, 1);
|
1048
|
+
rb_define_method(rb_cDLPtrData, "define_data_type",
|
1049
|
+
rb_dlptr_define_data_type, -1);
|
1050
|
+
rb_define_method(rb_cDLPtrData, "struct!", rb_dlptr_define_struct, -1);
|
1051
|
+
rb_define_method(rb_cDLPtrData, "union!", rb_dlptr_define_union, -1);
|
1052
|
+
rb_define_method(rb_cDLPtrData, "data_type", rb_dlptr_get_data_type, 0);
|
1053
|
+
rb_define_method(rb_cDLPtrData, "[]", rb_dlptr_aref, -1);
|
1054
|
+
rb_define_method(rb_cDLPtrData, "[]=", rb_dlptr_aset, -1);
|
1055
|
+
rb_define_method(rb_cDLPtrData, "size", rb_dlptr_size, -1);
|
1056
|
+
rb_define_method(rb_cDLPtrData, "size=", rb_dlptr_size, -1);
|
1057
|
+
|
1058
|
+
rb_mDLMemorySpace = rb_define_module_under(rb_mDL, "MemorySpace");
|
1059
|
+
st_memory_table = st_init_numtable();
|
1060
|
+
rb_define_const(rb_mDLMemorySpace, "MemoryTable", Qnil); /* historical */
|
1061
|
+
rb_define_module_function(rb_mDLMemorySpace, "each", rb_dlmem_each, 0);
|
1062
|
+
}
|