Class: FFI::StructLayoutBuilder

Inherits:
Object
  • Object
show all
Defined in:
ext/ffi_c/Struct.c

Instance Method Summary collapse

Constructor Details

#initializeObject



299
300
301
302
303
304
305
306
307
# File 'ext/ffi_c/Struct.c', line 299

static VALUE
struct_layout_builder_initialize(VALUE self)
{
    StructLayoutBuilder* builder;

    Data_Get_Struct(self, StructLayoutBuilder, builder);

    return self;
}

Instance Method Details

#add_array(*args) ⇒ Object



481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'ext/ffi_c/Struct.c', line 481

static VALUE
struct_layout_builder_add_array(int argc, VALUE* argv, VALUE self)
{
    StructLayoutBuilder* builder;
    VALUE rbName = Qnil, rbType = Qnil, rbLength = Qnil, rbOffset = Qnil, rbField;
    VALUE fargv[3], aargv[2];
    unsigned int size, alignment, offset;
    int nargs;

    nargs = rb_scan_args(argc, argv, "31", &rbName, &rbType, &rbLength, &rbOffset);

    Data_Get_Struct(self, StructLayoutBuilder, builder);

    alignment = NUM2UINT(rb_funcall2(rbType, rb_intern("alignment"), 0, NULL));
    size = NUM2UINT(rb_funcall2(rbType, rb_intern("size"), 0, NULL)) * NUM2UINT(rbLength);

    offset = calculate_offset(builder, alignment, rbOffset);

    aargv[0] = rbType;
    aargv[1] = rbLength;
    fargv[0] = rbName;
    fargv[1] = UINT2NUM(offset);
    fargv[2] = rb_class_new_instance(2, aargv, rbffi_ArrayTypeClass);
    rbField = rb_class_new_instance(3, fargv, rbffi_StructLayoutArrayFieldClass);

    store_field(builder, rbName, rbField, offset, size, alignment);

    return self;
}

#add_field(*args) ⇒ Object



403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'ext/ffi_c/Struct.c', line 403

static VALUE
struct_layout_builder_add_field(int argc, VALUE* argv, VALUE self)
{
    StructLayoutBuilder* builder;
    VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil;
    unsigned int size, alignment, offset;
    int nargs;

    nargs = rb_scan_args(argc, argv, "21", &rbName, &rbType, &rbOffset);
    
    Data_Get_Struct(self, StructLayoutBuilder, builder);

    alignment = NUM2UINT(rb_funcall2(rbType, rb_intern("alignment"), 0, NULL));
    size = NUM2UINT(rb_funcall2(rbType, rb_intern("size"), 0, NULL));

    offset = calculate_offset(builder, alignment, rbOffset);

    //
    // If a primitive type was passed in as the type arg, try and convert
    //
    if (!rb_obj_is_kind_of(rbType, rbffi_StructLayoutFieldClass)) {
        VALUE fargv[3], rbFieldClass;
        fargv[0] = rbName;
        fargv[1] = UINT2NUM(offset);
        fargv[2] = rbType;
        if (rb_obj_is_kind_of(rbType, rbffi_FunctionTypeClass)) {
            rbFieldClass = rbffi_StructLayoutFunctionFieldClass;
        } else if (rb_obj_is_kind_of(rbType, rbffi_StructByValueClass)) {
            rbFieldClass = rbffi_StructLayoutStructFieldClass;
        } else if (rb_obj_is_kind_of(rbType, rbffi_ArrayTypeClass)) {
            rbFieldClass = rbffi_StructLayoutArrayFieldClass;
        } else {
            rbFieldClass = rbffi_StructLayoutFieldClass;
        }

        rbField = rb_class_new_instance(3, fargv, rbFieldClass);
    } else {
        rbField = rbType;
    }

    store_field(builder, rbName, rbField, offset, size, alignment);
    
    return self;
}

#add_struct(*args) ⇒ Object



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
# File 'ext/ffi_c/Struct.c', line 448

static VALUE
struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self)
{
    StructLayoutBuilder* builder;
    VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil, rbStructClass = Qnil;
    VALUE fargv[3];
    unsigned int size, alignment, offset;
    int nargs;

    nargs = rb_scan_args(argc, argv, "21", &rbName, &rbStructClass, &rbOffset);

    if (!rb_obj_is_instance_of(rbStructClass, rb_cClass) || !rb_class_inherited(rbStructClass, rbffi_StructClass)) {
        rb_raise(rb_eTypeError, "wrong argument type.  Expected subclass of FFI::Struct");
    }

    rbType = rb_class_new_instance(1, &rbStructClass, rbffi_StructByValueClass);

    alignment = NUM2UINT(rb_funcall2(rbType, rb_intern("alignment"), 0, NULL));
    size = NUM2UINT(rb_funcall2(rbType, rb_intern("size"), 0, NULL));

    Data_Get_Struct(self, StructLayoutBuilder, builder);

    offset = calculate_offset(builder, alignment, rbOffset);

    fargv[0] = rbName;
    fargv[1] = UINT2NUM(offset);
    fargv[2] = rbType;
    rbField = rb_class_new_instance(3, fargv, rbffi_StructLayoutStructFieldClass);
    store_field(builder, rbName, rbField, offset, size, alignment);

    return self;
}

#alignmentObject



331
332
333
334
335
336
337
338
339
# File 'ext/ffi_c/Struct.c', line 331

static VALUE
struct_layout_builder_get_alignment(VALUE self)
{
    StructLayoutBuilder* builder;

    Data_Get_Struct(self, StructLayoutBuilder, builder);

    return UINT2NUM(builder->alignment);
}

#alignment=(rbAlign) ⇒ Object



341
342
343
344
345
346
347
348
349
350
351
# File 'ext/ffi_c/Struct.c', line 341

static VALUE
struct_layout_builder_set_alignment(VALUE self, VALUE rbAlign)
{
    StructLayoutBuilder* builder;
    unsigned int align = NUM2UINT(rbAlign);

    Data_Get_Struct(self, StructLayoutBuilder, builder);
    builder->size = MAX(align, builder->alignment);

    return UINT2NUM(builder->alignment);
}

#buildObject



517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
# File 'ext/ffi_c/Struct.c', line 517

static VALUE
struct_layout_builder_build(VALUE self)
{
    StructLayoutBuilder* builder;
    VALUE argv[4];

    Data_Get_Struct(self, StructLayoutBuilder, builder);

    argv[0] = builder->rbFieldNames;
    argv[1] = builder->rbFieldMap;
    argv[2] = UINT2NUM(align(builder->size, builder->alignment)); // tail padding
    argv[3] = UINT2NUM(builder->alignment);

    return rb_class_new_instance(4, argv, rbffi_StructLayoutClass);
}

#sizeObject



309
310
311
312
313
314
315
316
317
# File 'ext/ffi_c/Struct.c', line 309

static VALUE
struct_layout_builder_get_size(VALUE self)
{
    StructLayoutBuilder* builder;

    Data_Get_Struct(self, StructLayoutBuilder, builder);

    return UINT2NUM(builder->size);
}

#size=(rbSize) ⇒ Object



319
320
321
322
323
324
325
326
327
328
329
# File 'ext/ffi_c/Struct.c', line 319

static VALUE
struct_layout_builder_set_size(VALUE self, VALUE rbSize)
{
    StructLayoutBuilder* builder;
    unsigned int size = NUM2UINT(rbSize);

    Data_Get_Struct(self, StructLayoutBuilder, builder);
    builder->size = MAX(size, builder->size);

    return UINT2NUM(builder->size);
}

#union=(rbUnion) ⇒ Object



353
354
355
356
357
358
359
360
361
362
363
# File 'ext/ffi_c/Struct.c', line 353

static VALUE
struct_layout_builder_set_union(VALUE self, VALUE rbUnion)
{
    StructLayoutBuilder* builder;


    Data_Get_Struct(self, StructLayoutBuilder, builder);
    builder->isUnion = RTEST(rbUnion);

    return rbUnion;
}

#union?Boolean

Returns:

  • (Boolean)


365
366
367
368
369
370
371
372
373
374
375
# File 'ext/ffi_c/Struct.c', line 365

static VALUE
struct_layout_builder_union_p(VALUE self)
{
    StructLayoutBuilder* builder;


    Data_Get_Struct(self, StructLayoutBuilder, builder);


    return builder->isUnion ? Qtrue : Qfalse;
}