/* * 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; } }
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; }
/* * 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; }
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; }