123456789_123456789_123456789_123456789_123456789_

Class: FFI::Struct::InlineArray

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, Enumerable
Inherits: Object
Defined in: ext/ffi_c/Struct.c

Class Method Summary

Instance Method Summary

Constructor Details

.new(memory, field)

[ GitHub ]

  
# File 'ext/ffi_c/Struct.c', line 595

static VALUE
inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
{
    InlineArray* array;

    TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
    RB_OBJ_WRITE(self, &array->rbMemory, rbMemory);
    RB_OBJ_WRITE(self, &array->rbField, rbField);

    TypedData_Get_Struct(rbMemory, AbstractMemory, &rbffi_abstract_memory_data_type, array->memory);
    TypedData_Get_Struct(rbField, StructField, &rbffi_struct_field_data_type, array->field);
    TypedData_Get_Struct(array->field->rbType, ArrayType, &rbffi_array_type_data_type, array->arrayType);
    TypedData_Get_Struct(array->arrayType->rbComponentType, Type, &rbffi_type_data_type, array->componentType);

    array->op = get_memory_op(array->componentType);
    if (array->op == NULL && array->componentType->nativeType == NATIVE_MAPPED) {
        array->op = get_memory_op(((MappedType *) array->componentType)->type);
    }

    array->length = array->arrayType->length;

    return self;
}

Instance Method Details

#[](index)

[ GitHub ]

  
# File 'ext/ffi_c/Struct.c', line 649

static VALUE
inline_array_aref(VALUE self, VALUE rbIndex)
{
    InlineArray* array;

    TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);

    if (array->op != NULL) {
        VALUE rbNativeValue = array->op->get(array->memory,
                inline_array_offset(array, NUM2INT(rbIndex)));
        if (unlikely(array->componentType->nativeType == NATIVE_MAPPED)) {
            return rb_funcall(((MappedType *) array->componentType)->rbConverter,
                    rb_intern("from_native"), 2, rbNativeValue, Qnil);
        } else {
            return rbNativeValue;
        }

    } else if (array->componentType->nativeType == NATIVE_STRUCT) {
        VALUE rbOffset = INT2NUM(inline_array_offset(array, NUM2INT(rbIndex)));
        VALUE rbLength = INT2NUM(array->componentType->ffiType->size);
        VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
        VALUE obj;

         /* We avoid rb_class_new_instance here, to avoid passing the method block */
         obj = rb_obj_alloc(((StructByValue *) array->componentType)->rbStructClass);
         rb_funcallv(obj, id_initialize, 1, &rbPointer);
         return obj;
    } else {

        rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(array->arrayType->rbComponentType));
        return Qnil;
    }
}

#[]=(index, value)

[ GitHub ]

  
# File 'ext/ffi_c/Struct.c', line 689

static VALUE
inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
{
    InlineArray* array;

    rb_check_frozen(self);
    TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);

    if (array->op != NULL) {
        if (unlikely(array->componentType->nativeType == NATIVE_MAPPED)) {
            rbValue = rb_funcall(((MappedType *) array->componentType)->rbConverter,
                    rb_intern("to_native"), 2, rbValue, Qnil);
        }
        array->op->put(array->memory, inline_array_offset(array, NUM2INT(rbIndex)),
            rbValue);

    } else if (array->componentType->nativeType == NATIVE_STRUCT) {
        int offset = inline_array_offset(array, NUM2INT(rbIndex));
        Struct* s;

        if (!rb_obj_is_kind_of(rbValue, rbffi_StructClass)) {
            rb_raise(rb_eTypeError, "argument not an instance of struct");
            return Qnil;
        }

        checkWrite(array->memory);
        checkBounds(array->memory, offset, array->componentType->ffiType->size);

        TypedData_Get_Struct(rbValue, Struct, &rbffi_struct_data_type, s);
        checkRead(s->pointer);
        checkBounds(s->pointer, 0, array->componentType->ffiType->size);

        memcpy(array->memory->address + offset, s->pointer->address, array->componentType->ffiType->size);

    } else {
        ArrayType* arrayType;
        TypedData_Get_Struct(array->field->rbType, ArrayType, &rbffi_array_type_data_type, arrayType);

        rb_raise(rb_eArgError, "set not supported for %s", rb_obj_classname(arrayType->rbComponentType));
        return Qnil;
    }

    return rbValue;
}

#each #block(for)

[ GitHub ]

  
# File 'ext/ffi_c/Struct.c', line 738

static VALUE
inline_array_each(VALUE self)
{
    InlineArray* array;

    int i;

    TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);

    for (i = 0; i < array->length; ++i) {
        rb_yield(inline_array_aref(self, INT2FIX(i)));
    }

    return self;
}

#size Get(size)

[ GitHub ]

  
# File 'ext/ffi_c/Struct.c', line 624

static VALUE
inline_array_size(VALUE self)
{
    InlineArray* array;

    TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);

    return UINT2NUM(((ArrayType *) array->field->type)->length);
}

#to_a ⇒ ? Convert(+self+ to an array.)

[ GitHub ]

  
# File 'ext/ffi_c/Struct.c', line 759

static VALUE
inline_array_to_a(VALUE self)
{
    InlineArray* array;
    VALUE obj;
    int i;

    TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
    obj = rb_ary_new2(array->length);


    for (i = 0; i < array->length; ++i) {
        rb_ary_push(obj, inline_array_aref(self, INT2FIX(i)));
    }

    return obj;
}