Esempio n. 1
0
File: Struct.c Progetto: mjaric/ffi
/*
 * call-seq: [](index)
 * @param [Numeric] index
 * @return [Type, Struct]
 */
static VALUE
inline_array_aref(VALUE self, VALUE rbIndex)
{
    InlineArray* array;

    Data_Get_Struct(self, InlineArray, 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);

        return rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass);
    } else {

        rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(array->arrayType->rbComponentType));
        return Qnil;
    }
}
Esempio n. 2
0
File: Struct.c Progetto: sgonyea/ffi
static VALUE
inline_array_each(VALUE self)
{
    InlineArray* array;
    
    int i;

    Data_Get_Struct(self, InlineArray, array);
    
    if (array->op != NULL) {
        for (i = 0; i < array->length; ++i) {
            int offset = inline_array_offset(array, i);
            rb_yield(array->op->get(array->memory, offset));
        }
    } else if (array->componentType->nativeType == NATIVE_STRUCT) {
        for (i = 0; i < array->length; ++i) {
            VALUE rbOffset = UINT2NUM(inline_array_offset(array, i));
            VALUE rbLength = UINT2NUM(array->componentType->ffiType->size);
            VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);

            rb_yield(rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass));
        }
    } else {
        ArrayType* arrayType;
        Data_Get_Struct(array->field->rbType, ArrayType, arrayType);

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

    return self;
}
Esempio n. 3
0
File: Struct.c Progetto: mjaric/ffi
/*
 * call-seq: []=(index, value)
 * @param [Numeric] index
 * @param [Type, Struct]
 * @return [value]
 */
static VALUE
inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
{
    InlineArray* array;

    Data_Get_Struct(self, InlineArray, 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);

        Data_Get_Struct(rbValue, Struct, 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;
        Data_Get_Struct(array->field->rbType, ArrayType, arrayType);

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

    return rbValue;
}
Esempio n. 4
0
File: Struct.c Progetto: sgonyea/ffi
static VALUE
inline_array_to_a(VALUE self)
{
    InlineArray* array;
    VALUE obj;
    int i;

    Data_Get_Struct(self, InlineArray, array);
    obj = rb_ary_new2(array->length);

    
    for (i = 0; i < array->length; ++i) {
        int offset = inline_array_offset(array, i);
        rb_ary_push(obj, array->op->get(array->memory, offset));
    }

    return obj;
}