123456789_123456789_123456789_123456789_123456789_

Class: FFI::StructLayout::Field

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Inherits: Object
Defined in: ext/ffi_c/StructLayout.c

Overview

A field in a ::FFI::StructLayout.

Class Method Summary

Instance Method Summary

Constructor Details

.new(name, offset, type) .new(FFI)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 140

static VALUE
struct_field_initialize(int argc, VALUE* argv, VALUE self)
{
    VALUE rbOffset = Qnil, rbName = Qnil, rbType = Qnil;
    StructField* field;
    int nargs;

    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);

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

    if (TYPE(rbName) != T_SYMBOL && TYPE(rbName) != T_STRING) {
        rb_raise(rb_eTypeError, "wrong argument type %s (expected Symbol/String)",
                rb_obj_classname(rbName));
    }

    Check_Type(rbOffset, T_FIXNUM);

    if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) {
        rb_raise(rb_eTypeError, "wrong argument type %s (expected FFI::Type)",
                rb_obj_classname(rbType));
    }

    field->offset = NUM2UINT(rbOffset);
    RB_OBJ_WRITE(self, &field->rbName, (TYPE(rbName) == T_SYMBOL) ? rbName : rb_str_intern(rbName));
    RB_OBJ_WRITE(self, &field->rbType, rbType);
    TypedData_Get_Struct(field->rbType, Type, &rbffi_type_data_type, field->type);
    field->memoryOp = get_memory_op(field->type);
    field->referenceIndex = -1;

    switch (field->type->nativeType == NATIVE_MAPPED ? ((MappedType *) field->type)->type->nativeType : field->type->nativeType) {
        case NATIVE_FUNCTION:
        case NATIVE_POINTER:
            field->referenceRequired = true;
            break;

        default:
            field->referenceRequired = (rb_respond_to(self, rb_intern("reference_required?"))
                    && RTEST(rb_funcall2(self, rb_intern("reference_required?"), 0, NULL)))
                    || (rb_respond_to(rbType, rb_intern("reference_required?"))
                        && RTEST(rb_funcall2(rbType, rb_intern("reference_required?"), 0, NULL)));
            break;
    }

    rb_obj_freeze(self);

    return self;
}

Instance Method Details

#alignment #the(field)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 220

static VALUE
struct_field_alignment(VALUE self)
{
    StructField* field;
    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
    return UINT2NUM(field->type->ffiType->alignment);
}

#get(pointer) #an(object)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 261

static VALUE
struct_field_get(VALUE self, VALUE pointer)
{
    StructField* f;

    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
    if (f->memoryOp == NULL) {
        rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(f->rbType));
        return Qnil;
    }

    return (*f->memoryOp->get)(MEMORY(pointer), f->offset);
}

#name #the(field)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 247

static VALUE
struct_field_name(VALUE self)
{
    StructField* field;
    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
    return field->rbName;
}

#offset #the(field)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 194

static VALUE
struct_field_offset(VALUE self)
{
    StructField* field;
    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
    return UINT2NUM(field->offset);
}

#put(pointer, value) #an(object)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 282

static VALUE
struct_field_put(VALUE self, VALUE pointer, VALUE value)
{
    StructField* f;

    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
    if (f->memoryOp == NULL) {
        rb_raise(rb_eArgError, "put not supported for %s", rb_obj_classname(f->rbType));
        return self;
    }

    (*f->memoryOp->put)(MEMORY(pointer), f->offset, value);

    return self;
}

#size #the(field)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 207

static VALUE
struct_field_size(VALUE self)
{
    StructField* field;
    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
    return UINT2NUM(field->type->ffiType->size);
}

#type #the(field)

[ GitHub ]

  
# File 'ext/ffi_c/StructLayout.c', line 233

static VALUE
struct_field_type(VALUE self)
{
    StructField* field;
    TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);

    return field->rbType;
}