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