ffi 0.6.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- data/History.txt +7 -0
- data/LICENSE +10 -21
- data/README.rdoc +70 -0
- data/Rakefile +56 -84
- data/ext/ffi_c/AbstractMemory.c +56 -38
- data/ext/ffi_c/AbstractMemory.h +15 -22
- data/ext/ffi_c/Buffer.c +61 -22
- data/ext/ffi_c/Call.c +52 -540
- data/ext/ffi_c/Call.h +1 -1
- data/ext/ffi_c/DataConverter.c +62 -0
- data/ext/ffi_c/DynamicLibrary.c +21 -1
- data/ext/ffi_c/Function.c +252 -30
- data/ext/ffi_c/MappedType.c +146 -0
- data/{libtest/FunctionTest.c → ext/ffi_c/MappedType.h} +32 -25
- data/ext/ffi_c/MemoryPointer.c +12 -33
- data/ext/ffi_c/Platform.c +2 -0
- data/ext/ffi_c/Pointer.c +66 -28
- data/ext/ffi_c/Struct.c +19 -306
- data/ext/ffi_c/Struct.h +6 -0
- data/ext/ffi_c/StructByReference.c +150 -0
- data/{libtest/LastErrorTest.c → ext/ffi_c/StructByReference.h} +30 -21
- data/ext/ffi_c/StructLayout.c +26 -16
- data/ext/ffi_c/Type.c +39 -68
- data/ext/ffi_c/Type.h +12 -22
- data/ext/ffi_c/Types.c +20 -5
- data/ext/ffi_c/Types.h +7 -7
- data/ext/ffi_c/Variadic.c +21 -17
- data/ext/ffi_c/extconf.rb +4 -0
- data/ext/ffi_c/ffi.c +8 -2
- data/ext/ffi_c/rbffi.h +1 -0
- data/lib/ffi/autopointer.rb +23 -22
- data/lib/ffi/enum.rb +36 -21
- data/lib/ffi/errno.rb +20 -0
- data/lib/ffi/ffi.rb +13 -80
- data/lib/ffi/io.rb +12 -20
- data/lib/ffi/library.rb +109 -92
- data/lib/ffi/managedstruct.rb +1 -1
- data/lib/ffi/memorypointer.rb +15 -21
- data/lib/ffi/platform.rb +27 -33
- data/lib/ffi/pointer.rb +14 -21
- data/lib/ffi/struct.rb +98 -49
- data/lib/ffi/struct_layout_builder.rb +158 -0
- data/lib/ffi/types.rb +99 -128
- data/lib/ffi/union.rb +20 -0
- data/lib/ffi/variadic.rb +33 -22
- data/spec/ffi/async_callback_spec.rb +23 -0
- data/spec/ffi/callback_spec.rb +62 -0
- data/spec/ffi/custom_param_type.rb +31 -0
- data/spec/ffi/custom_type_spec.rb +73 -0
- data/spec/ffi/enum_spec.rb +19 -0
- data/spec/ffi/ffi_spec.rb +24 -0
- data/spec/ffi/pointer_spec.rb +15 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +7 -1
- data/spec/ffi/strptr_spec.rb +36 -0
- data/spec/ffi/struct_packed_spec.rb +46 -0
- data/spec/ffi/struct_spec.rb +19 -5
- data/spec/ffi/typedef_spec.rb +14 -0
- data/tasks/ann.rake +80 -0
- data/tasks/extension.rake +25 -0
- data/tasks/gem.rake +200 -0
- data/tasks/git.rake +41 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +301 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +139 -131
- data/README.md +0 -109
- data/ext/ffi_c/AutoPointer.c +0 -60
- data/ext/ffi_c/AutoPointer.h +0 -18
- data/ext/ffi_c/Ffi_c.iml +0 -12
- data/ffi.gemspec +0 -18
- data/gen/log +0 -1
- data/lib/Lib.iml +0 -21
- data/libtest/Benchmark.c +0 -73
- data/libtest/BoolTest.c +0 -52
- data/libtest/BufferTest.c +0 -52
- data/libtest/ClosureTest.c +0 -173
- data/libtest/EnumTest.c +0 -55
- data/libtest/GNUmakefile +0 -141
- data/libtest/GlobalVariable.c +0 -56
- data/libtest/NumberTest.c +0 -145
- data/libtest/PointerTest.c +0 -84
- data/libtest/ReferenceTest.c +0 -44
- data/libtest/StringTest.c +0 -55
- data/libtest/StructTest.c +0 -247
- data/libtest/UnionTest.c +0 -64
- data/libtest/VariadicTest.c +0 -57
- data/spec/ffi/Ffi.iml +0 -12
data/ext/ffi_c/Struct.c
CHANGED
@@ -45,16 +45,6 @@
|
|
45
45
|
#include "StructByValue.h"
|
46
46
|
#include "ArrayType.h"
|
47
47
|
|
48
|
-
#define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
|
49
|
-
|
50
|
-
typedef struct StructLayoutBuilder {
|
51
|
-
VALUE rbFieldNames;
|
52
|
-
VALUE rbFieldMap;
|
53
|
-
unsigned int size;
|
54
|
-
unsigned int alignment;
|
55
|
-
bool isUnion;
|
56
|
-
} StructLayoutBuilder;
|
57
|
-
|
58
48
|
typedef struct InlineArray_ {
|
59
49
|
VALUE rbMemory;
|
60
50
|
VALUE rbField;
|
@@ -69,16 +59,11 @@ typedef struct InlineArray_ {
|
|
69
59
|
|
70
60
|
|
71
61
|
static void struct_mark(Struct *);
|
72
|
-
static void struct_layout_builder_mark(StructLayoutBuilder *);
|
73
|
-
static void struct_layout_builder_free(StructLayoutBuilder *);
|
74
62
|
static VALUE struct_class_layout(VALUE klass);
|
75
63
|
static void struct_malloc(Struct* s);
|
76
64
|
static void inline_array_mark(InlineArray *);
|
77
65
|
|
78
|
-
static inline int align(int offset, int align);
|
79
|
-
|
80
66
|
VALUE rbffi_StructClass = Qnil;
|
81
|
-
static VALUE StructLayoutBuilderClass = Qnil;
|
82
67
|
|
83
68
|
VALUE rbffi_StructInlineArrayClass = Qnil;
|
84
69
|
VALUE rbffi_StructLayoutCharArrayClass = Qnil;
|
@@ -213,6 +198,10 @@ struct_field(Struct* s, VALUE fieldName)
|
|
213
198
|
StructLayout* layout = s->layout;
|
214
199
|
VALUE rbField;
|
215
200
|
|
201
|
+
if (likely(SYMBOL_P(fieldName) && st_lookup(layout->fieldSymbolTable, fieldName, (st_data_t *) &rbField))) {
|
202
|
+
return rbField;
|
203
|
+
}
|
204
|
+
|
216
205
|
rbField = rb_hash_aref(layout->rbFieldMap, fieldName);
|
217
206
|
if (rbField == Qnil) {
|
218
207
|
VALUE str = rb_funcall2(fieldName, id_to_s, 0, NULL);
|
@@ -345,293 +334,35 @@ struct_get_layout(VALUE self)
|
|
345
334
|
return s->rbLayout;
|
346
335
|
}
|
347
336
|
|
348
|
-
static VALUE
|
349
|
-
struct_layout_builder_allocate(VALUE klass)
|
350
|
-
{
|
351
|
-
StructLayoutBuilder* builder;
|
352
|
-
VALUE obj;
|
353
|
-
|
354
|
-
obj = Data_Make_Struct(klass, StructLayoutBuilder, struct_layout_builder_mark, struct_layout_builder_free, builder);
|
355
|
-
|
356
|
-
builder->size = 0;
|
357
|
-
builder->alignment = 1;
|
358
|
-
builder->isUnion = false;
|
359
|
-
builder->rbFieldNames = rb_ary_new();
|
360
|
-
builder->rbFieldMap = rb_hash_new();
|
361
|
-
|
362
|
-
return obj;
|
363
|
-
}
|
364
|
-
|
365
|
-
static void
|
366
|
-
struct_layout_builder_mark(StructLayoutBuilder* builder)
|
367
|
-
{
|
368
|
-
rb_gc_mark(builder->rbFieldNames);
|
369
|
-
rb_gc_mark(builder->rbFieldMap);
|
370
|
-
}
|
371
|
-
|
372
|
-
static void
|
373
|
-
struct_layout_builder_free(StructLayoutBuilder* builder)
|
374
|
-
{
|
375
|
-
xfree(builder);
|
376
|
-
}
|
377
|
-
|
378
|
-
static VALUE
|
379
|
-
struct_layout_builder_initialize(VALUE self)
|
380
|
-
{
|
381
|
-
StructLayoutBuilder* builder;
|
382
|
-
|
383
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
384
|
-
|
385
|
-
return self;
|
386
|
-
}
|
387
|
-
|
388
|
-
static VALUE
|
389
|
-
struct_layout_builder_get_size(VALUE self)
|
390
|
-
{
|
391
|
-
StructLayoutBuilder* builder;
|
392
|
-
|
393
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
394
|
-
|
395
|
-
return UINT2NUM(builder->size);
|
396
|
-
}
|
397
|
-
|
398
|
-
static VALUE
|
399
|
-
struct_layout_builder_set_size(VALUE self, VALUE rbSize)
|
400
|
-
{
|
401
|
-
StructLayoutBuilder* builder;
|
402
|
-
unsigned int size = NUM2UINT(rbSize);
|
403
|
-
|
404
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
405
|
-
builder->size = MAX(size, builder->size);
|
406
|
-
|
407
|
-
return UINT2NUM(builder->size);
|
408
|
-
}
|
409
|
-
|
410
|
-
static VALUE
|
411
|
-
struct_layout_builder_get_alignment(VALUE self)
|
412
|
-
{
|
413
|
-
StructLayoutBuilder* builder;
|
414
|
-
|
415
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
416
|
-
|
417
|
-
return UINT2NUM(builder->alignment);
|
418
|
-
}
|
419
|
-
|
420
|
-
static VALUE
|
421
|
-
struct_layout_builder_set_alignment(VALUE self, VALUE rbAlign)
|
422
|
-
{
|
423
|
-
StructLayoutBuilder* builder;
|
424
|
-
unsigned int align = NUM2UINT(rbAlign);
|
425
|
-
|
426
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
427
|
-
builder->size = MAX(align, builder->alignment);
|
428
|
-
|
429
|
-
return UINT2NUM(builder->alignment);
|
430
|
-
}
|
431
337
|
|
432
338
|
static VALUE
|
433
|
-
|
339
|
+
struct_null_p(VALUE self)
|
434
340
|
{
|
435
|
-
|
436
|
-
|
341
|
+
Struct* s;
|
437
342
|
|
438
|
-
Data_Get_Struct(self,
|
439
|
-
builder->isUnion = RTEST(rbUnion);
|
343
|
+
Data_Get_Struct(self, Struct, s);
|
440
344
|
|
441
|
-
return
|
345
|
+
return s->pointer->address == NULL ? Qtrue : Qfalse;
|
442
346
|
}
|
443
347
|
|
444
348
|
static VALUE
|
445
|
-
|
446
|
-
{
|
447
|
-
StructLayoutBuilder* builder;
|
448
|
-
|
449
|
-
|
450
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
451
|
-
|
452
|
-
|
453
|
-
return builder->isUnion ? Qtrue : Qfalse;
|
454
|
-
}
|
455
|
-
|
456
|
-
static void
|
457
|
-
store_field(StructLayoutBuilder* builder, VALUE rbName, VALUE rbField,
|
458
|
-
unsigned int offset, unsigned int size, unsigned int alignment)
|
349
|
+
struct_order(int argc, VALUE* argv, VALUE self)
|
459
350
|
{
|
460
|
-
|
461
|
-
rb_hash_aset(builder->rbFieldMap, rbName, rbField);
|
462
|
-
|
463
|
-
builder->alignment = MAX(builder->alignment, alignment);
|
351
|
+
Struct* s;
|
464
352
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
builder->size = MAX(builder->size, offset + size);
|
469
|
-
}
|
470
|
-
}
|
353
|
+
Data_Get_Struct(self, Struct, s);
|
354
|
+
if (argc == 0) {
|
355
|
+
return rb_funcall(s->rbPointer, rb_intern("order"), 0);
|
471
356
|
|
472
|
-
static int
|
473
|
-
calculate_offset(StructLayoutBuilder* builder, int alignment, VALUE rbOffset)
|
474
|
-
{
|
475
|
-
if (rbOffset != Qnil) {
|
476
|
-
return NUM2UINT(rbOffset);
|
477
357
|
} else {
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
static VALUE
|
483
|
-
struct_layout_builder_add_field(int argc, VALUE* argv, VALUE self)
|
484
|
-
{
|
485
|
-
StructLayoutBuilder* builder;
|
486
|
-
VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil;
|
487
|
-
unsigned int size, alignment, offset;
|
488
|
-
int nargs;
|
489
|
-
|
490
|
-
nargs = rb_scan_args(argc, argv, "21", &rbName, &rbType, &rbOffset);
|
491
|
-
|
492
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
493
|
-
|
494
|
-
alignment = NUM2UINT(rb_funcall2(rbType, rb_intern("alignment"), 0, NULL));
|
495
|
-
size = NUM2UINT(rb_funcall2(rbType, rb_intern("size"), 0, NULL));
|
496
|
-
|
497
|
-
offset = calculate_offset(builder, alignment, rbOffset);
|
498
|
-
|
499
|
-
//
|
500
|
-
// If a primitive type was passed in as the type arg, try and convert
|
501
|
-
//
|
502
|
-
if (!rb_obj_is_kind_of(rbType, rbffi_StructLayoutFieldClass)) {
|
503
|
-
VALUE fargv[3], rbFieldClass;
|
504
|
-
fargv[0] = rbName;
|
505
|
-
fargv[1] = UINT2NUM(offset);
|
506
|
-
fargv[2] = rbType;
|
358
|
+
VALUE retval = rb_obj_dup(self);
|
359
|
+
VALUE rbPointer = rb_funcall2(s->rbPointer, rb_intern("order"), argc, argv);
|
360
|
+
struct_set_pointer(retval, rbPointer);
|
507
361
|
|
508
|
-
|
509
|
-
|
510
|
-
rbFieldClass = rbffi_StructLayoutFunctionFieldClass;
|
511
|
-
|
512
|
-
} else if (rb_obj_is_kind_of(rbType, rbffi_StructByValueClass)) {
|
513
|
-
|
514
|
-
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct"));
|
515
|
-
|
516
|
-
} else if (rb_obj_is_kind_of(rbType, rbffi_ArrayTypeClass)) {
|
517
|
-
|
518
|
-
rbFieldClass = rbffi_StructLayoutArrayFieldClass;
|
519
|
-
|
520
|
-
} else if (rb_obj_is_kind_of(rbType, rbffi_EnumTypeClass)) {
|
521
|
-
|
522
|
-
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("Enum"));
|
523
|
-
|
524
|
-
} else {
|
525
|
-
rbFieldClass = rbffi_StructLayoutFieldClass;
|
526
|
-
}
|
527
|
-
|
528
|
-
if (!RTEST(rbFieldClass)) {
|
529
|
-
rb_raise(rb_eTypeError, "invalid struct field type (%s)", rb_obj_classname(rbType));
|
530
|
-
return Qnil;
|
531
|
-
}
|
532
|
-
|
533
|
-
rbField = rb_class_new_instance(3, fargv, rbFieldClass);
|
534
|
-
} else {
|
535
|
-
rbField = rbType;
|
536
|
-
}
|
537
|
-
|
538
|
-
store_field(builder, rbName, rbField, offset, size, alignment);
|
539
|
-
|
540
|
-
return self;
|
541
|
-
}
|
542
|
-
|
543
|
-
static VALUE
|
544
|
-
struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self)
|
545
|
-
{
|
546
|
-
StructLayoutBuilder* builder;
|
547
|
-
VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil;
|
548
|
-
VALUE rbFieldClass = Qnil, rbStructClass = Qnil;
|
549
|
-
VALUE fargv[3];
|
550
|
-
unsigned int size, alignment, offset;
|
551
|
-
int nargs;
|
552
|
-
|
553
|
-
nargs = rb_scan_args(argc, argv, "21", &rbName, &rbStructClass, &rbOffset);
|
554
|
-
|
555
|
-
if (!rb_obj_is_instance_of(rbStructClass, rb_cClass) || !rb_class_inherited(rbStructClass, rbffi_StructClass)) {
|
556
|
-
rb_raise(rb_eTypeError, "wrong argument type. Expected subclass of FFI::Struct");
|
557
|
-
}
|
558
|
-
|
559
|
-
rbType = rb_class_new_instance(1, &rbStructClass, rbffi_StructByValueClass);
|
560
|
-
|
561
|
-
alignment = NUM2UINT(rb_funcall2(rbType, rb_intern("alignment"), 0, NULL));
|
562
|
-
size = NUM2UINT(rb_funcall2(rbType, rb_intern("size"), 0, NULL));
|
563
|
-
|
564
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
565
|
-
|
566
|
-
offset = calculate_offset(builder, alignment, rbOffset);
|
567
|
-
|
568
|
-
fargv[0] = rbName;
|
569
|
-
fargv[1] = UINT2NUM(offset);
|
570
|
-
fargv[2] = rbType;
|
571
|
-
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct"));
|
572
|
-
if (!RTEST(rbFieldClass)) {
|
573
|
-
rb_raise(rb_eRuntimeError, "could not locate StructLayout::InlineStruct");
|
574
|
-
return Qnil;
|
362
|
+
return retval;
|
575
363
|
}
|
576
|
-
|
577
|
-
rbField = rb_class_new_instance(3, fargv, rbFieldClass);
|
578
|
-
|
579
|
-
store_field(builder, rbName, rbField, offset, size, alignment);
|
580
|
-
|
581
|
-
return self;
|
582
|
-
}
|
583
|
-
|
584
|
-
static VALUE
|
585
|
-
struct_layout_builder_add_array(int argc, VALUE* argv, VALUE self)
|
586
|
-
{
|
587
|
-
StructLayoutBuilder* builder;
|
588
|
-
VALUE rbName = Qnil, rbType = Qnil, rbLength = Qnil, rbOffset = Qnil, rbField;
|
589
|
-
VALUE fargv[3], aargv[2];
|
590
|
-
unsigned int size, alignment, offset;
|
591
|
-
int nargs;
|
592
|
-
|
593
|
-
nargs = rb_scan_args(argc, argv, "31", &rbName, &rbType, &rbLength, &rbOffset);
|
594
|
-
|
595
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
596
|
-
|
597
|
-
alignment = NUM2UINT(rb_funcall2(rbType, rb_intern("alignment"), 0, NULL));
|
598
|
-
size = NUM2UINT(rb_funcall2(rbType, rb_intern("size"), 0, NULL)) * NUM2UINT(rbLength);
|
599
|
-
|
600
|
-
offset = calculate_offset(builder, alignment, rbOffset);
|
601
|
-
|
602
|
-
aargv[0] = rbType;
|
603
|
-
aargv[1] = rbLength;
|
604
|
-
fargv[0] = rbName;
|
605
|
-
fargv[1] = UINT2NUM(offset);
|
606
|
-
fargv[2] = rb_class_new_instance(2, aargv, rbffi_ArrayTypeClass);
|
607
|
-
rbField = rb_class_new_instance(3, fargv, rbffi_StructLayoutArrayFieldClass);
|
608
|
-
|
609
|
-
store_field(builder, rbName, rbField, offset, size, alignment);
|
610
|
-
|
611
|
-
return self;
|
612
364
|
}
|
613
365
|
|
614
|
-
static inline int
|
615
|
-
align(int offset, int align)
|
616
|
-
{
|
617
|
-
return align + ((offset - 1) & ~(align - 1));
|
618
|
-
}
|
619
|
-
|
620
|
-
static VALUE
|
621
|
-
struct_layout_builder_build(VALUE self)
|
622
|
-
{
|
623
|
-
StructLayoutBuilder* builder;
|
624
|
-
VALUE argv[4];
|
625
|
-
|
626
|
-
Data_Get_Struct(self, StructLayoutBuilder, builder);
|
627
|
-
|
628
|
-
argv[0] = builder->rbFieldNames;
|
629
|
-
argv[1] = builder->rbFieldMap;
|
630
|
-
argv[2] = UINT2NUM(align(builder->size, builder->alignment)); // tail padding
|
631
|
-
argv[3] = UINT2NUM(builder->alignment);
|
632
|
-
|
633
|
-
return rb_class_new_instance(4, argv, rbffi_StructLayoutClass);
|
634
|
-
}
|
635
366
|
|
636
367
|
static VALUE
|
637
368
|
inline_array_allocate(VALUE klass)
|
@@ -848,10 +579,6 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
848
579
|
rbffi_StructClass = StructClass = rb_define_class_under(moduleFFI, "Struct", rb_cObject);
|
849
580
|
rb_global_variable(&rbffi_StructClass);
|
850
581
|
|
851
|
-
|
852
|
-
StructLayoutBuilderClass = rb_define_class_under(moduleFFI, "StructLayoutBuilder", rb_cObject);
|
853
|
-
rb_global_variable(&StructLayoutBuilderClass);
|
854
|
-
|
855
582
|
rbffi_StructInlineArrayClass = rb_define_class_under(rbffi_StructClass, "InlineArray", rb_cObject);
|
856
583
|
rb_global_variable(&rbffi_StructInlineArrayClass);
|
857
584
|
|
@@ -862,6 +589,7 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
862
589
|
|
863
590
|
rb_define_alloc_func(StructClass, struct_allocate);
|
864
591
|
rb_define_method(StructClass, "initialize", struct_initialize, -1);
|
592
|
+
rb_define_method(StructClass, "order", struct_order, -1);
|
865
593
|
|
866
594
|
rb_define_alias(rb_singleton_class(StructClass), "alloc_in", "new");
|
867
595
|
rb_define_alias(rb_singleton_class(StructClass), "alloc_out", "new");
|
@@ -878,22 +606,7 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
878
606
|
|
879
607
|
rb_define_method(StructClass, "[]", struct_aref, 1);
|
880
608
|
rb_define_method(StructClass, "[]=", struct_aset, 2);
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
rb_define_alloc_func(StructLayoutBuilderClass, struct_layout_builder_allocate);
|
885
|
-
rb_define_method(StructLayoutBuilderClass, "initialize", struct_layout_builder_initialize, 0);
|
886
|
-
rb_define_method(StructLayoutBuilderClass, "build", struct_layout_builder_build, 0);
|
887
|
-
|
888
|
-
rb_define_method(StructLayoutBuilderClass, "alignment", struct_layout_builder_get_alignment, 0);
|
889
|
-
rb_define_method(StructLayoutBuilderClass, "alignment=", struct_layout_builder_set_alignment, 1);
|
890
|
-
rb_define_method(StructLayoutBuilderClass, "size", struct_layout_builder_get_size, 0);
|
891
|
-
rb_define_method(StructLayoutBuilderClass, "size=", struct_layout_builder_set_size, 1);
|
892
|
-
rb_define_method(StructLayoutBuilderClass, "union=", struct_layout_builder_set_union, 1);
|
893
|
-
rb_define_method(StructLayoutBuilderClass, "union?", struct_layout_builder_union_p, 0);
|
894
|
-
rb_define_method(StructLayoutBuilderClass, "add_field", struct_layout_builder_add_field, -1);
|
895
|
-
rb_define_method(StructLayoutBuilderClass, "add_array", struct_layout_builder_add_array, -1);
|
896
|
-
rb_define_method(StructLayoutBuilderClass, "add_struct", struct_layout_builder_add_struct, -1);
|
609
|
+
rb_define_method(StructClass, "null?", struct_null_p, 0);
|
897
610
|
|
898
611
|
rb_include_module(rbffi_StructInlineArrayClass, rb_mEnumerable);
|
899
612
|
rb_define_alloc_func(rbffi_StructInlineArrayClass, inline_array_allocate);
|
data/ext/ffi_c/Struct.h
CHANGED
@@ -32,6 +32,11 @@
|
|
32
32
|
|
33
33
|
#include "AbstractMemory.h"
|
34
34
|
#include "Type.h"
|
35
|
+
#ifdef RUBY_1_9
|
36
|
+
#include <ruby/st.h>
|
37
|
+
#else
|
38
|
+
#include <st.h>
|
39
|
+
#endif
|
35
40
|
|
36
41
|
#ifdef __cplusplus
|
37
42
|
extern "C" {
|
@@ -63,6 +68,7 @@ extern "C" {
|
|
63
68
|
int size;
|
64
69
|
int align;
|
65
70
|
ffi_type** ffiTypes;
|
71
|
+
struct st_table* fieldSymbolTable;
|
66
72
|
VALUE rbFieldNames;
|
67
73
|
VALUE rbFieldMap;
|
68
74
|
VALUE rbFields;
|
@@ -0,0 +1,150 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2010, Wayne Meissner
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
7
|
+
*
|
8
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
9
|
+
* list of conditions and the following disclaimer.
|
10
|
+
* * Redistributions in binary form must reproduce the above copyright notice
|
11
|
+
* this list of conditions and the following disclaimer in the documentation
|
12
|
+
* and/or other materials provided with the distribution.
|
13
|
+
* * The name of the author or authors may not be used to endorse or promote
|
14
|
+
* products derived from this software without specific prior written permission.
|
15
|
+
*
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
20
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#include <sys/param.h>
|
29
|
+
#include <sys/types.h>
|
30
|
+
#include <stdio.h>
|
31
|
+
#include <stdint.h>
|
32
|
+
#include <stdbool.h>
|
33
|
+
#include <errno.h>
|
34
|
+
#include <ruby.h>
|
35
|
+
|
36
|
+
#include <ffi.h>
|
37
|
+
#include "rbffi.h"
|
38
|
+
#include "compat.h"
|
39
|
+
|
40
|
+
#include "Pointer.h"
|
41
|
+
#include "Struct.h"
|
42
|
+
#include "StructByReference.h"
|
43
|
+
|
44
|
+
|
45
|
+
#define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
|
46
|
+
|
47
|
+
static VALUE sbr_allocate(VALUE);
|
48
|
+
static VALUE sbr_initialize(VALUE, VALUE);
|
49
|
+
static void sbr_mark(StructByReference *);
|
50
|
+
|
51
|
+
VALUE rbffi_StructByReferenceClass = Qnil;
|
52
|
+
|
53
|
+
static VALUE
|
54
|
+
sbr_allocate(VALUE klass)
|
55
|
+
{
|
56
|
+
StructByReference* sbr;
|
57
|
+
|
58
|
+
VALUE obj = Data_Make_Struct(klass, StructByReference, sbr_mark, -1, sbr);
|
59
|
+
|
60
|
+
sbr->rbStructClass = Qnil;
|
61
|
+
|
62
|
+
return obj;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE
|
66
|
+
sbr_initialize(VALUE self, VALUE rbStructClass)
|
67
|
+
{
|
68
|
+
StructByReference* sbr = NULL;
|
69
|
+
|
70
|
+
if (!rb_class_inherited_p(rbStructClass, rbffi_StructClass)) {
|
71
|
+
rb_raise(rb_eTypeError, "wrong type (expected subclass of FFI::Struct)");
|
72
|
+
}
|
73
|
+
|
74
|
+
Data_Get_Struct(self, StructByReference, sbr);
|
75
|
+
sbr->rbStructClass = rbStructClass;
|
76
|
+
|
77
|
+
return self;
|
78
|
+
}
|
79
|
+
|
80
|
+
static void
|
81
|
+
sbr_mark(StructByReference *sbr)
|
82
|
+
{
|
83
|
+
rb_gc_mark(sbr->rbStructClass);
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
static VALUE
|
88
|
+
sbr_struct_class(VALUE self)
|
89
|
+
{
|
90
|
+
StructByReference* sbr;
|
91
|
+
|
92
|
+
Data_Get_Struct(self, StructByReference, sbr);
|
93
|
+
|
94
|
+
return sbr->rbStructClass;
|
95
|
+
}
|
96
|
+
|
97
|
+
static VALUE
|
98
|
+
sbr_native_type(VALUE self)
|
99
|
+
{
|
100
|
+
return rb_const_get(rbffi_TypeClass, rb_intern("POINTER"));
|
101
|
+
}
|
102
|
+
|
103
|
+
static VALUE
|
104
|
+
sbr_to_native(VALUE self, VALUE value, VALUE ctx)
|
105
|
+
{
|
106
|
+
StructByReference* sbr;
|
107
|
+
Struct* s;
|
108
|
+
|
109
|
+
if (unlikely(value == Qnil)) {
|
110
|
+
return rbffi_NullPointerSingleton;
|
111
|
+
}
|
112
|
+
|
113
|
+
Data_Get_Struct(self, StructByReference, sbr);
|
114
|
+
if (!rb_obj_is_kind_of(value, sbr->rbStructClass)) {
|
115
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
116
|
+
rb_obj_classname(value),
|
117
|
+
RSTRING_PTR(rb_class_name(sbr->rbStructClass)));
|
118
|
+
}
|
119
|
+
|
120
|
+
Data_Get_Struct(value, Struct, s);
|
121
|
+
|
122
|
+
return s->rbPointer;
|
123
|
+
}
|
124
|
+
|
125
|
+
static VALUE
|
126
|
+
sbr_from_native(VALUE self, VALUE value, VALUE ctx)
|
127
|
+
{
|
128
|
+
StructByReference* sbr;
|
129
|
+
|
130
|
+
Data_Get_Struct(self, StructByReference, sbr);
|
131
|
+
|
132
|
+
return rb_class_new_instance(1, &value, sbr->rbStructClass);
|
133
|
+
}
|
134
|
+
|
135
|
+
|
136
|
+
void
|
137
|
+
rbffi_StructByReference_Init(VALUE moduleFFI)
|
138
|
+
{
|
139
|
+
rbffi_StructByReferenceClass = rb_define_class_under(moduleFFI, "StructByReference", rb_cObject);
|
140
|
+
rb_global_variable(&rbffi_StructByReferenceClass);
|
141
|
+
rb_include_module(rbffi_StructByReferenceClass, rb_const_get(moduleFFI, rb_intern("DataConverter")));
|
142
|
+
|
143
|
+
rb_define_alloc_func(rbffi_StructByReferenceClass, sbr_allocate);
|
144
|
+
rb_define_method(rbffi_StructByReferenceClass, "initialize", sbr_initialize, 1);
|
145
|
+
rb_define_method(rbffi_StructByReferenceClass, "struct_class", sbr_struct_class, 0);
|
146
|
+
rb_define_method(rbffi_StructByReferenceClass, "native_type", sbr_native_type, 0);
|
147
|
+
rb_define_method(rbffi_StructByReferenceClass, "to_native", sbr_to_native, 2);
|
148
|
+
rb_define_method(rbffi_StructByReferenceClass, "from_native", sbr_from_native, 2);
|
149
|
+
}
|
150
|
+
|