Class: FFI::StructLayout::Array
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
Field
|
|
|
Instance Chain:
self,
Field
|
|
| Inherits: |
FFI::StructLayout::Field
|
| Defined in: | ext/ffi_c/StructLayout.c |
Overview
An array Field in a ::FFI::StructLayout.
Class Method Summary
Instance Method Summary
Field - Inherited
Constructor Details
This class inherits a constructor from FFI::StructLayout::Field
Instance Method Details
#get(pointer)
#an(array)
# File 'ext/ffi_c/StructLayout.c', line 357
static VALUE
array_field_get(VALUE self, VALUE pointer)
{
StructField* f;
ArrayType* array;
VALUE argv[2];
TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
TypedData_Get_Struct(f->rbType, ArrayType, &rbffi_array_type_data_type, array);
argv[0] = pointer;
argv[1] = self;
return rb_class_new_instance(2, argv, isCharArray(array)
? rbffi_StructLayoutCharArrayClass : rbffi_StructInlineArrayClass);
}
#put(pointer, value)
#an(array)
# File 'ext/ffi_c/StructLayout.c', line 381
static VALUE
array_field_put(VALUE self, VALUE pointer, VALUE value)
{
StructField* f;
ArrayType* array;
TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
TypedData_Get_Struct(f->rbType, ArrayType, &rbffi_array_type_data_type, array);
if (isCharArray(array) && rb_obj_is_instance_of(value, rb_cString)) {
VALUE argv[2];
argv[0] = INT2FIX(f->offset);
argv[1] = value;
if (RSTRING_LEN(value) < array->length) {
rb_funcall2(pointer, rb_intern("put_string"), 2, argv);
} else if (RSTRING_LEN(value) == array->length) {
rb_funcall2(pointer, rb_intern("put_bytes"), 2, argv);
} else {
rb_raise(rb_eIndexError, "String is longer (%ld bytes) than the char array (%d bytes)", RSTRING_LEN(value), array->length);
}
} 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;
TypedData_Get_Struct(entry, Struct, &rbffi_struct_data_type, 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;
}