An array {Field} in a {StructLayout}.
static VALUE
array_field_get(VALUE self, VALUE pointer)
{
StructField* f;
ArrayType* array;
VALUE argv[2];
Data_Get_Struct(self, StructField, f);
Data_Get_Struct(f->rbType, ArrayType, array);
argv[0] = pointer;
argv[1] = self;
return rb_class_new_instance(2, argv, isCharArray(array)
? rbffi_StructLayoutCharArrayClass : rbffi_StructInlineArrayClass);
}
static VALUE
array_field_put(VALUE self, VALUE pointer, VALUE value)
{
StructField* f;
ArrayType* array;
Data_Get_Struct(self, StructField, f);
Data_Get_Struct(f->rbType, ArrayType, array);
if (isCharArray(array) && rb_obj_is_instance_of(value, rb_cString)) {
VALUE argv[2];
argv[0] = INT2FIX(f->offset);
argv[1] = value;
rb_funcall2(pointer, rb_intern("put_string"), 2, argv);
} else {
#ifdef notyet
MemoryOp* op;
int count = RARRAY_LEN(value);
int i;
AbstractMemory* memory = MEMORY(pointer);
if (count > array->length) {
rb_raise(rb_eIndexError, "array too large");
}
/* clear the contents in case of a short write */
checkWrite(memory);
checkBounds(memory, f->offset, f->type->ffiType->size);
if (count < array->length) {
memset(memory->address + f->offset + (count * array->componentType->ffiType->size),
0, (array->length - count) * array->componentType->ffiType->size);
}
/* now copy each element in */
if ((op = get_memory_op(array->componentType)) != NULL) {
for (i = 0; i < count; ++i) {
(*op->put)(memory, f->offset + (i * array->componentType->ffiType->size), rb_ary_entry(value, i));
}
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
for (i = 0; i < count; ++i) {
VALUE entry = rb_ary_entry(value, i);
Struct* s;
if (!rb_obj_is_kind_of(entry, rbffi_StructClass)) {
rb_raise(rb_eTypeError, "array element not an instance of FFI::Struct");
break;
}
Data_Get_Struct(entry, Struct, s);
checkRead(s->pointer);
checkBounds(s->pointer, 0, array->componentType->ffiType->size);
memcpy(memory->address + f->offset + (i * array->componentType->ffiType->size),
s->pointer->address, array->componentType->ffiType->size);
}
} else {
rb_raise(rb_eNotImpError, "put not supported for arrays of type %s", rb_obj_classname(array->rbComponentType));
}
#else
rb_raise(rb_eNotImpError, "cannot set array field");
#endif
}
return value;
}
Generated with the Darkfish Rdoc Generator 2.