static VALUE
inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
{
InlineArray* array;
Data_Get_Struct(self, InlineArray, array);
array->rbMemory = rbMemory;
array->rbField = rbField;
Data_Get_Struct(rbMemory, AbstractMemory, array->memory);
Data_Get_Struct(rbField, StructField, array->field);
Data_Get_Struct(array->field->rbType, ArrayType, array->arrayType);
Data_Get_Struct(array->arrayType->rbComponentType, 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;
}
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;
}
}
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;
}
static VALUE
inline_array_each(VALUE self)
{
InlineArray* array;
int i;
Data_Get_Struct(self, InlineArray, array);
for (i = 0; i < array->length; ++i) {
rb_yield(inline_array_aref(self, INT2FIX(i)));
}
return self;
}
static VALUE
inline_array_size(VALUE self)
{
InlineArray* array;
Data_Get_Struct(self, InlineArray, array);
return UINT2NUM(((ArrayType *) array->field->type)->length);
}
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) {
rb_ary_push(obj, inline_array_aref(self, INT2FIX(i)));
}
return obj;
}
static VALUE
inline_array_to_ptr(VALUE self)
{
InlineArray* array;
Data_Get_Struct(self, InlineArray, array);
return rb_funcall(array->rbMemory, rb_intern("slice"), 2,
UINT2NUM(array->field->offset), UINT2NUM(array->arrayType->base.ffiType->size));
}
Generated with the Darkfish Rdoc Generator 2.