virtualbox-com 0.9.9 → 0.10.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.
Files changed (39) hide show
  1. data/LICENSE +339 -19
  2. data/examples/simple.rb +2 -0
  3. data/ext/virtualbox-com/4.1/extconf.rb +4 -0
  4. data/ext/virtualbox-com/4.1/generated.inc +17345 -0
  5. data/ext/virtualbox-com/4.1/vbox.c +858 -0
  6. data/ext/virtualbox-com/4.2/extconf.rb +4 -0
  7. data/ext/virtualbox-com/4.2/generated.inc +19751 -0
  8. data/ext/virtualbox-com/4.2/vbox.c +858 -0
  9. data/ext/virtualbox-com/helpers.h +62 -0
  10. data/ext/virtualbox-com/loader/extconf.rb +3 -0
  11. data/ext/virtualbox-com/loader/vbox-loader.c +187 -0
  12. data/ext/virtualbox-com/types.h +34 -0
  13. data/ext/virtualbox-com/vbox.c +858 -0
  14. data/lib/virtualbox/com.rb +4 -26
  15. data/lib/virtualbox/com/{abstract_enum.rb → abstracts.rb} +22 -18
  16. data/lib/virtualbox/com/exceptions.rb +29 -3
  17. data/lib/virtualbox/com/model/4.1-generated.rb +2141 -0
  18. data/lib/virtualbox/com/model/4.2-generated.rb +141 -432
  19. data/lib/virtualbox/com/model/4.2.rb +4 -4
  20. data/lib/virtualbox/com/util.rb +2 -1
  21. data/lib/virtualbox/com/version.rb +1 -1
  22. data/lib/virtualbox/com/xpcomc-ffi.rb +5 -19
  23. data/lib/virtualbox/com/xpcomc-ffi/abstracts.rb +103 -0
  24. data/lib/virtualbox/com/{iid.rb → xpcomc-ffi/iid.rb} +18 -0
  25. data/lib/virtualbox/com/xpcomc-ffi/lib.rb +6 -0
  26. data/lib/virtualbox/com/xpcomc-ffi/model-types.rb +1 -0
  27. data/lib/virtualbox/com/xpcomc-native.rb +8 -0
  28. data/scripts/abstracts.rb +84 -0
  29. data/scripts/sig.rb +201 -0
  30. data/scripts/spec.rb +56 -0
  31. data/scripts/to_c.rb +157 -0
  32. data/scripts/xidl-conv.rb +110 -50
  33. data/virtualbox-com.gemspec +18 -11
  34. metadata +49 -47
  35. data/.gitignore +0 -9
  36. data/README.md +0 -89
  37. data/Rakefile +0 -8
  38. data/lib/virtualbox/com/abstract_interface.rb +0 -144
  39. data/lib/virtualbox/com/abstract_model.rb +0 -14
@@ -0,0 +1,858 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <stdlib.h>
4
+ #include <stdarg.h>
5
+ #include <dlfcn.h>
6
+ #include <stdint.h>
7
+
8
+ #include <ruby.h>
9
+ #include <ruby/encoding.h>
10
+
11
+ #include "../types.h"
12
+ #include "../helpers.h"
13
+
14
+ #define NS_CHECK(x) ns_check(x)
15
+
16
+
17
+
18
+
19
+ /*======================================================================
20
+ * Ruby shortcut
21
+ * - handle conversion to fixed size type (int, pointer)
22
+ *======================================================================*/
23
+
24
+
25
+ extern VBOX_XPCOMC virtualbox_com_xpcom;
26
+
27
+
28
+ static VBOX_XPCOMC xpcom = NULL;
29
+
30
+ static VALUE mVirtualBox = Qundef;
31
+ static VALUE mCOM = Qundef;
32
+ static VALUE mModel = Qundef;
33
+
34
+ static VALUE cBlob = Qundef;
35
+ static VALUE cWString = Qundef;
36
+ static VALUE cCArray = Qundef;
37
+ static VALUE cIID = Qundef;
38
+ static VALUE cAbstractModel = Qundef;
39
+ static VALUE cAbstractInterface = Qundef;
40
+ static VALUE cAbstractEnum = Qundef;
41
+
42
+ static VALUE oZero = Qundef;
43
+ static VALUE oMax_u16 = Qundef;
44
+ static VALUE oMax_u32 = Qundef;
45
+ static VALUE oMax_u64 = Qundef;
46
+ static VALUE oMax_s16 = Qundef;
47
+ static VALUE oMax_s32 = Qundef;
48
+ static VALUE oMax_s64 = Qundef;
49
+ static VALUE oMin_s16 = Qundef;
50
+ static VALUE oMin_s32 = Qundef;
51
+ static VALUE oMin_s64 = Qundef;
52
+ static VALUE oExceptionMap = Qundef;
53
+
54
+ static VALUE sYes = Qundef;
55
+ static VALUE sNo = Qundef;
56
+ static VALUE sTrue = Qundef;
57
+ static VALUE sFalse = Qundef;
58
+ static VALUE sOn = Qundef;
59
+ static VALUE sOff = Qundef;
60
+ static VALUE sEnabled = Qundef;
61
+ static VALUE sDisabled = Qundef;
62
+ static VALUE sIID = Qundef;
63
+ static VALUE sCode = Qundef;
64
+ static VALUE sFunction = Qundef;
65
+
66
+ static ID _IID;
67
+ static ID _map;
68
+ static ID _brackets;
69
+ static ID _bracketseq;
70
+ static ID _pow;
71
+ static ID _minus;
72
+ static ID _neg;
73
+ static ID _ge;
74
+ static ID _le;
75
+ static ID _is_a;
76
+ static ID _dup;
77
+ static ID _symbol;
78
+ static ID _value;
79
+ static ID _const_get;
80
+ static ID _new;
81
+
82
+ static rb_encoding * _UTF8;
83
+
84
+
85
+
86
+
87
+ static void no_instantiation(VALUE klass) {
88
+ rb_undef_method(rb_singleton_class(klass), "new");
89
+ rb_undef_alloc_func(klass);
90
+ }
91
+
92
+
93
+ static void ns_check(uint32_t rcode) {
94
+ if (rcode & 0x80000000) {
95
+ VALUE c = ULL2NUM(rcode);
96
+ VALUE k = rb_funcall(oExceptionMap, _brackets, 1, c);
97
+ VALUE h = rb_hash_new();
98
+ rb_funcall(h, _bracketseq, 2, sCode, c);
99
+ rb_exc_raise(rb_funcall(k, _new, 1, h));
100
+ }
101
+ }
102
+
103
+ /* Forward definition */
104
+ static void nsISupports_free(struct obj *ptr);
105
+
106
+
107
+
108
+
109
+ /*======================================================================*
110
+ * Internal classes
111
+ * They are an intermediate to
112
+ * - manage data conversion
113
+ * - perform garbage collection
114
+ *======================================================================*/
115
+
116
+ /* Class: IID
117
+ */
118
+ #define IID_STR_MAX 36 /* 8+1+4+1+4+1+4+1+12 */
119
+ static VALUE iid__new(iid_t *iid) {
120
+ iid_t *a_iid = ALLOC(iid_t);
121
+ *a_iid = *iid;
122
+ return Data_Wrap_Struct(cIID, 0, free, a_iid);
123
+ }
124
+ static VALUE iid__to_s(VALUE self) {
125
+ iid_t *iid = DATA_PTR(self);
126
+ char str[IID_STR_MAX+1];
127
+ snprintf(str, IID_STR_MAX+1,
128
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
129
+ iid->m0, iid->m1, iid->m2,
130
+ iid->m3[0], iid->m3[1], iid->m3[2], iid->m3[3],
131
+ iid->m3[4], iid->m3[5], iid->m3[6], iid->m3[7]);
132
+ return rb_str_new(str, IID_STR_MAX);
133
+ }
134
+ static void iid_init(VALUE under) {
135
+ cIID = rb_define_class_under(under, "IID", rb_cObject);
136
+ no_instantiation(cIID);
137
+ rb_define_method(cIID, "to_s", iid__to_s, 0);
138
+ }
139
+
140
+
141
+ /* Class: Blob
142
+ */
143
+ struct blob_info {
144
+ uint32_t size;
145
+ uint8_t *data;
146
+ };
147
+ static void blob_free(struct blob_info *bi) {
148
+ xpcom->unalloc_mem(bi->data);
149
+ free(bi);
150
+ }
151
+ static VALUE blob_new(uint32_t size, uint8_t *data) {
152
+ struct blob_info *bi = ALLOC(struct blob_info);
153
+ bi->size = size;
154
+ bi->data = data;
155
+ return Data_Wrap_Struct(cBlob, 0, blob_free, bi);
156
+ }
157
+ static VALUE blob__new(VALUE self, VALUE data) {
158
+ data = StringValue(data);
159
+ return blob_new(RSTRING_LEN(data), (uint8_t*)RSTRING_PTR(data));
160
+ }
161
+
162
+ static VALUE blob__to_s(VALUE self) {
163
+ struct blob_info * bi = ((struct blob_info *)DATA_PTR(self));
164
+ return rb_str_new((char *)bi->data, bi->size);
165
+ }
166
+ static void blob_init(VALUE under) {
167
+ cBlob = rb_define_class_under(under, "Blob", rb_cObject);
168
+ no_instantiation(cBlob);
169
+ rb_define_singleton_method(cBlob, "new", blob__new, 1);
170
+ rb_define_method(cBlob, "to_s", blob__to_s, 0);
171
+ }
172
+
173
+
174
+ /* Class: WString
175
+ */
176
+ static VALUE wstring_new(wstring_t wstr) {
177
+ return Data_Wrap_Struct(cWString, 0, xpcom->utf16_free, wstr);
178
+ }
179
+ static VALUE wstring__new(VALUE self, VALUE str) {
180
+ wstring_t u16;
181
+ char *u8;
182
+ str = StringValue(str);
183
+ str = rb_str_export_to_enc(str, _UTF8);
184
+ u8 = StringValueCStr(str);
185
+ xpcom->utf8_to_utf16(u8, &u16);
186
+ return wstring_new(u16);
187
+ }
188
+ static VALUE wstring__to_s(VALUE self) {
189
+ wstring_t u16 = DATA_PTR(self);
190
+ char *u8;
191
+ VALUE str;
192
+ xpcom->utf16_to_utf8(u16, &u8);
193
+ str = rb_str_new_cstr(u8);
194
+ rb_enc_associate(str, _UTF8);
195
+ xpcom->utf8_free(u8);
196
+ return str;
197
+ }
198
+ static void wstring_init(VALUE under) {
199
+ cWString = rb_define_class_under(under, "WString", rb_cObject);
200
+ no_instantiation(cWString);
201
+ rb_define_singleton_method(cWString, "new", wstring__new, 1);
202
+ rb_define_method(cWString, "to_s", wstring__to_s, 0);
203
+ }
204
+
205
+
206
+ /* Class: CArray
207
+ */
208
+ struct carray_info {
209
+ uint32_t size;
210
+ void *data;
211
+ VALUE ary;
212
+ };
213
+ static void carray_free(struct carray_info *ci) {
214
+ free(ci->data);
215
+ free(ci);
216
+ }
217
+ static void carray_mark(struct carray_info *ci) {
218
+ rb_gc_mark(ci->ary);
219
+ }
220
+ static VALUE carray_new(uint32_t size, void *data, VALUE ary) {
221
+ struct carray_info *ci = ALLOC(struct carray_info);
222
+ ci->size = size;
223
+ ci->data = data;
224
+ ci->ary = ary;
225
+ return Data_Wrap_Struct(cCArray, carray_mark, carray_free, ci);
226
+ }
227
+ static inline uint32_t carray_get_size(VALUE val) {
228
+ return ((struct carray_info *)DATA_PTR(val))->size;
229
+ }
230
+ static inline void *carray_get_data(VALUE val) {
231
+ return ((struct carray_info *)DATA_PTR(val))->data;
232
+ }
233
+ static void carray_init(VALUE under) {
234
+ cCArray = rb_define_class_under(under, "CArray", rb_cObject);
235
+ no_instantiation(cCArray);
236
+ }
237
+
238
+
239
+
240
+
241
+ /*======================================================================*
242
+ * Data preparation:
243
+ * Will check type and perform basic conversion.
244
+ * All exceptions should be raised here
245
+ *======================================================================*/
246
+
247
+ static VALUE prepare_int16(VALUE val) {
248
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
249
+ rb_raise(rb_eArgError, "expecting Integer");
250
+ if (rb_funcall(val, _ge, 1, oMin_s16) == Qfalse ||
251
+ rb_funcall(val, _le, 1, oMax_s16) == Qfalse)
252
+ rb_raise(rb_eArgError, "expecting array of Integer [-2^15..2^15-1]");
253
+ return val;
254
+ }
255
+ static VALUE prepare_int32(VALUE val) {
256
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
257
+ rb_raise(rb_eArgError, "expecting Integer");
258
+ if (rb_funcall(val, _ge, 1, oMin_s32) == Qfalse ||
259
+ rb_funcall(val, _le, 1, oMax_s32) == Qfalse)
260
+ rb_raise(rb_eArgError, "expecting array of Integer [-2^32..2^31-1]");
261
+ return val;
262
+ }
263
+ static VALUE prepare_int64(VALUE val) {
264
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
265
+ rb_raise(rb_eArgError, "expecting Integer");
266
+ if (rb_funcall(val, _ge, 1, oMin_s64) == Qfalse ||
267
+ rb_funcall(val, _le, 1, oMax_s64) == Qfalse)
268
+ rb_raise(rb_eArgError, "expecting array of Integer [-2^63..2^63-1]");
269
+ return val;
270
+ }
271
+ static VALUE prepare_uint16(VALUE val) {
272
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
273
+ rb_raise(rb_eArgError, "expecting Integer");
274
+ if (rb_funcall(val, _ge, 1, oZero ) == Qfalse ||
275
+ rb_funcall(val, _le, 1, oMax_u16) == Qfalse)
276
+ rb_raise(rb_eArgError, "expecting Integer [0..2^16-1]");
277
+ return val;
278
+ }
279
+ static VALUE prepare_uint32(VALUE val) {
280
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
281
+ rb_raise(rb_eArgError, "expecting Integer");
282
+ if (rb_funcall(val, _ge, 1, oZero ) == Qfalse ||
283
+ rb_funcall(val, _le, 1, oMax_u32) == Qfalse)
284
+ rb_raise(rb_eArgError, "expecting Integer [0..2^32-1]");
285
+ return val;
286
+ }
287
+ static VALUE prepare_uint64(VALUE val) {
288
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
289
+ rb_raise(rb_eArgError, "expecting Integer");
290
+ if (rb_funcall(val, _ge, 1, oZero ) == Qfalse ||
291
+ rb_funcall(val, _le, 1, oMax_u64) == Qfalse)
292
+ rb_raise(rb_eArgError, "expecting Integer [0..2^64-1]");
293
+ return val;
294
+ }
295
+
296
+ static VALUE prepare_bool(VALUE val) {
297
+ switch(rb_type(val)) {
298
+ case T_TRUE :
299
+ return Qtrue;
300
+
301
+ case T_FALSE: case T_NIL:
302
+ return Qfalse;
303
+
304
+ case T_BIGNUM: case T_FIXNUM:
305
+ return rb_equal(val, INT2FIX(0));
306
+
307
+ case T_SYMBOL:
308
+ if (val == sYes || val == sTrue || val == sOn || val == sEnabled )
309
+ return Qtrue;
310
+ if (val == sNo || val == sFalse || val == sOff || val == sDisabled)
311
+ return Qfalse;
312
+ break;
313
+ }
314
+ rb_raise(rb_eArgError, "boolean-like value expected");
315
+ }
316
+
317
+ static VALUE prepare_ptr(VALUE val) {
318
+ rb_raise(rb_eArgError, "passing pointer is not allowed");
319
+ }
320
+
321
+ static inline VALUE prepare_blob(VALUE val) {
322
+ return blob__new(cBlob, val);
323
+ }
324
+
325
+ static inline VALUE prepare_wstring(VALUE val) {
326
+ return wstring__new(cWString, val);
327
+ }
328
+
329
+ static VALUE prepare_enum(VALUE val, VALUE klass) {
330
+ switch(rb_type(val)) {
331
+ case T_FIXNUM:
332
+ case T_BIGNUM: {
333
+ if (NIL_P(rb_funcall(klass, _symbol, 1, val)))
334
+ goto arg_error;
335
+ break;
336
+ }
337
+ case T_SYMBOL: {
338
+ VALUE v = rb_funcall(klass, _value, 1, val);
339
+ if (NIL_P(v)) goto arg_error;
340
+ val = v;
341
+ break;
342
+ }
343
+ default: arg_error:
344
+ rb_raise(rb_eArgError, "can't interpret '%s' as part of %s",
345
+ StringValueCStr(val), rb_class2name(klass));
346
+ }
347
+ return val;
348
+ }
349
+
350
+ static VALUE prepare_interface(VALUE val, VALUE klass) {
351
+ if (0 && rb_funcall(val, _is_a, 1, klass) == Qfalse) {
352
+ rb_raise(rb_eArgError, "expecting %s", rb_class2name(klass));
353
+ }
354
+ return val;
355
+ }
356
+
357
+
358
+ static VALUE prepare_array_uint16(VALUE ary) {
359
+ VALUE res = Qundef;
360
+ uint16_t *data = NULL;
361
+ long len, i;
362
+
363
+ ary = rb_check_array_type(ary);
364
+ len = RARRAY_LEN(ary);
365
+ data = ALLOC_N(uint16_t, len);
366
+ res = carray_new(len, data, Qnil);
367
+
368
+ for (i = 0 ; i < len ; i++) {
369
+ VALUE val = rb_ary_entry(ary, i);
370
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
371
+ rb_raise(rb_eArgError, "expecting array of Integer");
372
+ if (rb_funcall(val, _ge, 1, oZero ) == Qfalse ||
373
+ rb_funcall(val, _le, 1, oMax_u16) == Qfalse)
374
+ rb_raise(rb_eArgError, "expecting array of Integer [0..2^16-1]");
375
+ data[i] = NUM2UINT16(val);
376
+ }
377
+ return res;
378
+ }
379
+
380
+ static VALUE prepare_array_int16(VALUE ary) {
381
+ VALUE res = Qundef;
382
+ int16_t * data = NULL;
383
+ long len, i;
384
+
385
+ ary = rb_check_array_type(ary);
386
+ len = RARRAY_LEN(ary);
387
+ data = ALLOC_N(int16_t, len);
388
+ res = carray_new(len, data, Qnil);
389
+
390
+ for (i = 0 ; i < len ; i++) {
391
+ VALUE val = rb_ary_entry(ary, i);
392
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
393
+ rb_raise(rb_eArgError, "expecting array of Integer");
394
+ if (rb_funcall(val, _ge, 1, oMin_s16) == Qfalse ||
395
+ rb_funcall(val, _le, 1, oMax_s16) == Qfalse)
396
+ rb_raise(rb_eArgError, "expecting array of Integer [-2^15..2^15-1]");
397
+ data[i] = NUM2INT16(val);
398
+ }
399
+ return res;
400
+ }
401
+
402
+ static VALUE prepare_array_uint32(VALUE ary) {
403
+ VALUE res = Qundef;
404
+ uint32_t *data = NULL;
405
+ long len, i;
406
+
407
+ ary = rb_check_array_type(ary);
408
+ len = RARRAY_LEN(ary);
409
+ data = ALLOC_N(uint32_t, len);
410
+ res = carray_new(len, data, Qnil);
411
+
412
+ for (i = 0 ; i < len ; i++) {
413
+ VALUE val = rb_ary_entry(ary, i);
414
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
415
+ rb_raise(rb_eArgError, "expecting array of Integer");
416
+ if (rb_funcall(val, _ge, 1, oZero ) == Qfalse ||
417
+ rb_funcall(val, _le, 1, oMax_u32) == Qfalse)
418
+ rb_raise(rb_eArgError, "expecting array of Integer [0..2^32-1]");
419
+ data[i] = NUM2UINT32(val);
420
+ }
421
+ return res;
422
+ }
423
+
424
+ static VALUE prepare_array_int32(VALUE ary) {
425
+ VALUE res = Qundef;
426
+ int32_t * data = NULL;
427
+ long len, i;
428
+
429
+ ary = rb_check_array_type(ary);
430
+ len = RARRAY_LEN(ary);
431
+ data = ALLOC_N(int32_t, len);
432
+ res = carray_new(len, data, Qnil);
433
+
434
+ for (i = 0 ; i < len ; i++) {
435
+ VALUE val = rb_ary_entry(ary, i);
436
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
437
+ rb_raise(rb_eArgError, "expecting array of Integer");
438
+ if (rb_funcall(val, _ge, 1, oMin_s32) == Qfalse ||
439
+ rb_funcall(val, _le, 1, oMax_s32) == Qfalse)
440
+ rb_raise(rb_eArgError, "expecting array of Integer [-2^31..2^31-1]");
441
+ data[i] = NUM2INT32(val);
442
+ }
443
+ return res;
444
+ }
445
+
446
+ static VALUE prepare_array_uint64(VALUE ary) {
447
+ VALUE res = Qundef;
448
+ uint64_t *data = NULL;
449
+ long len, i;
450
+
451
+ ary = rb_check_array_type(ary);
452
+ len = RARRAY_LEN(ary);
453
+ data = ALLOC_N(uint64_t, len);
454
+ res = carray_new(len, data, Qnil);
455
+
456
+ for (i = 0 ; i < len ; i++) {
457
+ VALUE val = rb_ary_entry(ary, i);
458
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
459
+ rb_raise(rb_eArgError, "expecting array of Integer");
460
+ if (rb_funcall(val, _ge, 1, oZero ) == Qfalse ||
461
+ rb_funcall(val, _le, 1, oMax_u64) == Qfalse)
462
+ rb_raise(rb_eArgError, "expecting array of Integer [0..2^64-1]");
463
+ data[i] = NUM2UINT64(val);
464
+ }
465
+ return res;
466
+ }
467
+
468
+ static VALUE prepare_array_int64(VALUE ary) {
469
+ VALUE res = Qundef;
470
+ int64_t * data = NULL;
471
+ long len, i;
472
+
473
+ ary = rb_check_array_type(ary);
474
+ len = RARRAY_LEN(ary);
475
+ data = ALLOC_N(int64_t, len);
476
+ res = carray_new(len, data, Qnil);
477
+
478
+ for (i = 0 ; i < len ; i++) {
479
+ VALUE val = rb_ary_entry(ary, i);
480
+ if (rb_funcall(val, _is_a, 1, rb_cInteger) == Qfalse)
481
+ rb_raise(rb_eArgError, "expecting array of Integer");
482
+ if (rb_funcall(val, _ge, 1, oMin_s64) == Qfalse ||
483
+ rb_funcall(val, _le, 1, oMax_s64) == Qfalse)
484
+ rb_raise(rb_eArgError, "expecting array of Integer [-2^63..2^63-1]");
485
+ data[i] = NUM2INT64(val);
486
+ }
487
+ return res;
488
+ }
489
+
490
+ static VALUE prepare_array_bool(VALUE ary) {
491
+ VALUE res = Qundef;
492
+ bool_t *data = NULL;
493
+ long len, i;
494
+
495
+ ary = rb_check_array_type(ary);
496
+ len = RARRAY_LEN(ary);
497
+ data = ALLOC_N(bool_t, len);
498
+ res = carray_new(len, data, Qnil);
499
+
500
+ for (i = 0 ; i < len ; i++) {
501
+ VALUE val = prepare_bool(rb_ary_entry(ary, i));
502
+ data[i] = val == Qtrue ? ~0 : 0;
503
+ }
504
+ return res;
505
+ }
506
+
507
+ static VALUE prepare_array_wstring(VALUE ary) {
508
+ VALUE res = Qundef;
509
+ wstring_t *data = NULL;
510
+ long len, i;
511
+
512
+ ary = rb_ary_dup(rb_check_array_type(ary));
513
+ len = RARRAY_LEN(ary);
514
+ data = ALLOC_N(wstring_t, len);
515
+ res = carray_new(len, data, ary);
516
+
517
+ for (i = 0 ; i < len ; i++) {
518
+ VALUE val = prepare_wstring(rb_ary_entry(ary, i));
519
+ rb_ary_store(ary, i, val);
520
+ data[i] = (wstring_t)DATA_PTR(val);
521
+ }
522
+ OBJ_FREEZE(ary);
523
+ return res;
524
+ }
525
+
526
+ static VALUE prepare_array_enum(VALUE ary, VALUE klass) {
527
+ VALUE res = Qundef;
528
+ uint32_t *data = NULL;
529
+ long len, i;
530
+
531
+ ary = rb_check_array_type(ary);
532
+ len = RARRAY_LEN(ary);
533
+ data = ALLOC_N(uint32_t, len);
534
+ res = carray_new(len, data, Qnil);
535
+
536
+ for (i = 0 ; i < len ; i++) {
537
+ VALUE val = prepare_enum(rb_ary_entry(ary, i), klass);
538
+ data[i] = NUM2UINT32(val);
539
+ }
540
+ return res;
541
+ }
542
+
543
+ static VALUE prepare_array_interface(VALUE ary, VALUE klass) {
544
+ VALUE res = Qundef;
545
+ void * *data = NULL;
546
+ long len, i;
547
+
548
+ ary = rb_ary_dup(rb_check_array_type(ary));
549
+ len = RARRAY_LEN(ary);
550
+ data = (void*)ALLOC_N(uint32_t, len);
551
+ res = carray_new(len, data, ary);
552
+
553
+ for (i = 0 ; i < len ; i++) {
554
+ VALUE val = rb_ary_entry(ary, i);
555
+ if (rb_funcall(val, _is_a, 1, klass) == Qfalse)
556
+ rb_raise(rb_eArgError, "expecting array of %s",
557
+ rb_class2name(klass));
558
+ data[i] = DATA_PTR(val);
559
+ }
560
+ OBJ_FREEZE(ary);
561
+ return res;
562
+ }
563
+
564
+
565
+
566
+
567
+ /*======================================================================*
568
+ * Extract C value from Ruby object (object has been previously prepared)
569
+ * - it's not necessary to perform checking
570
+ * - C value can be directly used
571
+ *======================================================================*/
572
+
573
+ #define extract_int16(val, data) *(data) = NUM2INT16(val)
574
+ #define extract_int32(val, data) *(data) = NUM2INT32(val)
575
+ #define extract_int64(val, data) *(data) = NUM2INT64(val)
576
+ #define extract_uint16(val, data) *(data) = NUM2UINT16(val)
577
+ #define extract_uint32(val, data) *(data) = NUM2UINT32(val)
578
+ #define extract_uint64(val, data) *(data) = NUM2UINT64(val)
579
+ #define extract_bool(val, data) *(data) = (val) == Qtrue ? ~0 : 0
580
+ #define extract_ptr(val, data) *(data) = NUM2PTR(val)
581
+ #define extract_wstring(val, data) *(data) = DATA_PTR(val)
582
+ #define extract_enum(val, data, klass) *(data) = NUM2UINT32(val)
583
+ #define extract_interface(val, data, klass) *(data) = DATA_PTR(val)
584
+
585
+ static inline void extract_blob(VALUE val, uint32_t *size, void **data) {
586
+ struct blob_info * bi = ((struct blob_info *)DATA_PTR(val));
587
+ *size = bi->size;
588
+ *data = bi->data;
589
+ }
590
+
591
+ static inline void extract_carray(VALUE val, uint32_t *size, void **data) {
592
+ struct carray_info * ci = ((struct carray_info *)DATA_PTR(val));
593
+ *size = ci->size;
594
+ *data = ci->data;
595
+ }
596
+
597
+
598
+
599
+
600
+ /*======================================================================*
601
+ * Convert information from response
602
+ * - don't raise exception as this could lead to memory leak
603
+ *
604
+ *======================================================================*/
605
+
606
+ #define convert_int16(v) LL2NUM(v)
607
+ #define convert_int32(v) LL2NUM(v)
608
+ #define convert_int64(v) LL2NUM(v)
609
+ #define convert_uint16(v) ULL2NUM(v)
610
+ #define convert_uint32(v) ULL2NUM(v)
611
+ #define convert_uint64(v) ULL2NUM(v)
612
+ #define convert_ptr(v) PTR2NUM(v)
613
+ #define convert_bool(v) ((v) ? Qtrue : Qfalse)
614
+ #define convert_blob(s,d) ((d) ? blob_new(s,d) : Qnil)
615
+ #define convert_wstring(v) ((v) ? wstring_new(v) : Qnil)
616
+
617
+ static inline VALUE convert_enum(uint32_t v, VALUE klass) {
618
+ VALUE val = ULL2NUM(v);
619
+ VALUE sym = rb_funcall(klass, _symbol, 1, val);
620
+ if (NIL_P(sym)) {
621
+ rb_warn("unable to convert value %d to enumeration symbol", v);
622
+ return val;
623
+ }
624
+ return sym;
625
+ }
626
+
627
+ static inline VALUE convert_interface(void *iptr, VALUE klass) {
628
+ return iptr ? Data_Wrap_Struct(klass, 0, nsISupports_free, iptr)
629
+ : Qnil;
630
+ }
631
+
632
+
633
+ static inline VALUE convert_array_int32(uint32_t size, int32_t *array) {
634
+ if (array) {
635
+ VALUE res = rb_ary_new();
636
+ uint32_t i;
637
+ for (i = 0 ; i < size ; i++)
638
+ rb_ary_store(res, i, convert_int32(array[i]));
639
+ xpcom->unalloc_mem(array);
640
+ return res;
641
+ } else {
642
+ return Qnil;
643
+ }
644
+ }
645
+ static inline VALUE convert_array_int64(uint32_t size, int64_t *array) {
646
+ if (array) {
647
+ VALUE res = rb_ary_new2(size);
648
+ uint32_t i;
649
+ for (i = 0 ; i < size ; i++)
650
+ rb_ary_store(res, i, convert_int64(array[i]));
651
+ xpcom->unalloc_mem(array);
652
+ return res;
653
+ } else {
654
+ return Qnil;
655
+ }
656
+ }
657
+ static inline VALUE convert_array_uint32(uint32_t size, uint32_t *array) {
658
+ if (array) {
659
+ VALUE res = rb_ary_new2(size);
660
+ uint32_t i;
661
+ for (i = 0 ; i < size ; i++)
662
+ rb_ary_store(res, i, convert_uint32(array[i]));
663
+ xpcom->unalloc_mem(array);
664
+ return res;
665
+ } else {
666
+ return Qnil;
667
+ }
668
+ }
669
+ static inline VALUE convert_array_enum(uint32_t size, uint32_t *array, VALUE klass) {
670
+ if (array) {
671
+ VALUE res = rb_ary_new2(size);
672
+ uint32_t i;
673
+ for (i = 0 ; i < size ; i++)
674
+ rb_ary_store(res, i, convert_enum(array[i], klass));
675
+ xpcom->unalloc_mem(array);
676
+ return res;
677
+ } else {
678
+ return Qnil;
679
+ }
680
+ }
681
+ static inline VALUE convert_array_interface(uint32_t size, void **array, VALUE klass) {
682
+ if (array) {
683
+ VALUE res = rb_ary_new2(size);
684
+ uint32_t i;
685
+ for (i = 0 ; i < size ; i++)
686
+ rb_ary_push(res, convert_interface(array[i], klass));
687
+ xpcom->unalloc_mem(array);
688
+ return res;
689
+ } else {
690
+ return Qnil;
691
+ }
692
+ }
693
+
694
+ static inline VALUE convert_array_wstring(uint32_t size, void **array) {
695
+ if (array) {
696
+ VALUE res = rb_ary_new2(size);
697
+ uint32_t i;
698
+ for (i = 0 ; i < size ; i++)
699
+ rb_ary_push(res, convert_wstring(array[i]));
700
+ xpcom->unalloc_mem(array);
701
+ return res;
702
+ } else {
703
+ return Qnil;
704
+ }
705
+ }
706
+
707
+
708
+
709
+ /*======================================================================*
710
+ *
711
+ *
712
+ *
713
+ *======================================================================*/
714
+
715
+ #include "generated.inc"
716
+
717
+
718
+ static void nsISupports_free(struct obj *ptr) {
719
+ ((struct NSISupports *)ptr->vtbl)->Release(ptr);
720
+ }
721
+
722
+ static VALUE NSISupports__dup(VALUE self) {
723
+ VALUE klass = rb_class_of(self);
724
+ struct obj *obj = DATA_PTR(self);
725
+ struct NSISupports *vtbl = obj->vtbl;
726
+ vtbl->AddRef(obj);
727
+ return Data_Wrap_Struct(klass, 0, nsISupports_free, obj);
728
+ }
729
+
730
+ static VALUE NSISupports__clone(VALUE self) {
731
+ VALUE res = NSISupports__dup(self);
732
+ if (OBJ_TAINTED (self)) OBJ_TAINT(res);
733
+ if (OBJ_FROZEN (self)) OBJ_FREEZE(res);
734
+ if (OBJ_UNTRUSTED(self)) OBJ_UNTRUST(res);
735
+ return res;
736
+ }
737
+
738
+ static VALUE NSISupports__cast(VALUE self, VALUE model_name) {
739
+ VALUE res = Qundef;
740
+ VALUE model = rb_funcall(mModel,_const_get, 2, model_name, Qfalse);
741
+ VALUE iid = rb_funcall(model, _const_get, 2, sIID, Qfalse);
742
+ struct obj *obj = DATA_PTR(self);
743
+ struct NSISupports *vtbl = obj->vtbl;
744
+ void *nobj = NULL;
745
+
746
+ if (rb_funcall(model, _le, 1, cAbstractInterface) == Qfalse ||
747
+ rb_funcall(iid, _is_a, 1, cIID ) == Qfalse) {
748
+ rb_raise(rb_eArgError, "provided object is not a COM Model");
749
+ }
750
+
751
+ NS_CHECK(vtbl->QueryInterface(obj, DATA_PTR(iid), &nobj));
752
+ return convert_interface(nobj, model);
753
+ }
754
+
755
+
756
+
757
+
758
+
759
+ /*======================================================================*
760
+ * Initialisation of ruby extension
761
+ *======================================================================*/
762
+
763
+ /* ruby calls this to load the extension */
764
+ void RUBY_VBOX_INIT(void) {
765
+ VALUE oOne = INT2FIX(1);
766
+ VALUE oTwo = INT2FIX(2);
767
+ VALUE p15, p16, p31, p32, p63, p64;
768
+
769
+ xpcom = virtualbox_com_xpcom;
770
+
771
+ /* Basic ruby helper objects */
772
+ _IID = rb_intern("IID");
773
+ _map = rb_intern("map");
774
+ _brackets = rb_intern("[]");
775
+ _bracketseq = rb_intern("[]=");
776
+ _pow = rb_intern("**");
777
+ _minus = rb_intern("-" );
778
+ _neg = rb_intern("-@");
779
+ _ge = rb_intern(">=");
780
+ _le = rb_intern("<=");
781
+ _is_a = rb_intern("is_a?");
782
+ _dup = rb_intern("dup");
783
+ _symbol = rb_intern("symbol");
784
+ _value = rb_intern("value");
785
+ _const_get = rb_intern("const_get");
786
+ _new = rb_intern("new");
787
+
788
+ p15 = rb_funcall(oTwo, _pow, 1, INT2FIX(15));
789
+ p16 = rb_funcall(oTwo, _pow, 1, INT2FIX(16));
790
+ p31 = rb_funcall(oTwo, _pow, 1, INT2FIX(31));
791
+ p32 = rb_funcall(oTwo, _pow, 1, INT2FIX(32));
792
+ p63 = rb_funcall(oTwo, _pow, 1, INT2FIX(63));
793
+ p64 = rb_funcall(oTwo, _pow, 1, INT2FIX(64));
794
+ oZero = INT2FIX(0);
795
+ oMax_u16 = rb_funcall(p16, _minus, 1, oOne);
796
+ oMax_u32 = rb_funcall(p32, _minus, 1, oOne);
797
+ oMax_u64 = rb_funcall(p64, _minus, 1, oOne);
798
+ oMax_s16 = rb_funcall(p15, _minus, 1, oOne);
799
+ oMax_s32 = rb_funcall(p31, _minus, 1, oOne);
800
+ oMax_s64 = rb_funcall(p63, _minus, 1, oOne);
801
+ oMin_s16 = rb_funcall(p15, _neg, 0);
802
+ oMin_s32 = rb_funcall(p31, _neg, 0);
803
+ oMin_s64 = rb_funcall(p63, _neg, 0);
804
+
805
+ sYes = SYM("yes" );
806
+ sNo = SYM("no" );
807
+ sTrue = SYM("true" );
808
+ sFalse = SYM("false" );
809
+ sOn = SYM("on" );
810
+ sOff = SYM("off" );
811
+ sEnabled = SYM("enabled" );
812
+ sDisabled = SYM("disabled");
813
+ sIID = SYM("IID" );
814
+ sCode = SYM("code" );
815
+ sFunction = SYM("function");
816
+
817
+ _UTF8 = rb_enc_find("UTF-8");
818
+ if (_UTF8 == NULL)
819
+ rb_fatal("can't find UTF-8 encoding");
820
+
821
+ /* Define modules */
822
+ mVirtualBox = rb_define_module("VirtualBox");
823
+ mCOM = rb_define_module_under(mVirtualBox, "COM");
824
+ mModel = rb_define_module_under(mCOM, "Model");
825
+
826
+ /* Define abstract enumerations / interfaces */
827
+ cAbstractModel
828
+ = rb_define_class_under(mCOM, "AbstractModel", rb_cObject);
829
+ cAbstractEnum
830
+ = rb_define_class_under(mCOM, "AbstractEnum", cAbstractModel);
831
+ cAbstractInterface
832
+ = rb_define_class_under(mCOM, "AbstractInterface", cAbstractModel);
833
+
834
+ /* Retrieve exception map */
835
+ oExceptionMap
836
+ = rb_funcall(mCOM, _const_get, 2, SYM("EXCEPTION_MAP"), Qfalse);
837
+
838
+ /* Init internal classes */
839
+ iid_init(mCOM);
840
+ blob_init(mCOM);
841
+ wstring_init(mCOM);
842
+ carray_init(mCOM);
843
+
844
+ /* Init of generated xpcom classes */
845
+ comclass_init(mModel);
846
+
847
+ rb_define_method(cNSISupports, "cast", NSISupports__cast, 1);
848
+ rb_define_method(cNSISupports, "dup", NSISupports__dup, 0);
849
+ rb_define_method(cNSISupports, "clone", NSISupports__clone, 0);
850
+ }
851
+
852
+ VALUE virtualbox_com_virtualbox(void *ptr) {
853
+ return convert_interface(ptr, cVirtualBox);
854
+ }
855
+
856
+ VALUE virtualbox_com_session(void *ptr) {
857
+ return convert_interface(ptr, cSession);
858
+ }