static VALUE struct_field_initialize(int argc, VALUE* argv, VALUE self) { VALUE rbOffset = Qnil, rbName = Qnil, rbType = Qnil; StructField* field; int nargs; Data_Get_Struct(self, StructField, field); nargs = rb_scan_args(argc, argv, "3", &rbName, &rbOffset, &rbType); if (TYPE(rbName) != T_SYMBOL && TYPE(rbName) != T_STRING) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Symbol/String)", rb_obj_classname(rbName)); } Check_Type(rbOffset, T_FIXNUM); if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected FFI::Type)", rb_obj_classname(rbType)); } field->offset = NUM2UINT(rbOffset); field->rbName = (TYPE(rbName) == T_SYMBOL) ? rbName : rb_str_intern(rbName); field->rbType = rbType; Data_Get_Struct(field->rbType, Type, field->type); field->memoryOp = get_memory_op(field->type); return self; }
/* * Document-method: FFI::Struct::InlineArray#initialize * call-seq: initialize(memory, field) * @param [AbstractMemory] memory * @param [StructField] field * @return [self] */ 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; }
/* * call-seq: initialize(name, offset, type) * @param [String,Symbol] name * @param [Fixnum] offset * @param [FFI::Type] type * @return [self] * A new FFI::StructLayout::Field instance. */ static VALUE struct_field_initialize(int argc, VALUE* argv, VALUE self) { VALUE rbOffset = Qnil, rbName = Qnil, rbType = Qnil; StructField* field; int nargs; Data_Get_Struct(self, StructField, field); nargs = rb_scan_args(argc, argv, "3", &rbName, &rbOffset, &rbType); if (TYPE(rbName) != T_SYMBOL && TYPE(rbName) != T_STRING) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Symbol/String)", rb_obj_classname(rbName)); } Check_Type(rbOffset, T_FIXNUM); if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected FFI::Type)", rb_obj_classname(rbType)); } field->offset = NUM2UINT(rbOffset); field->rbName = (TYPE(rbName) == T_SYMBOL) ? rbName : rb_str_intern(rbName); field->rbType = rbType; Data_Get_Struct(field->rbType, Type, field->type); field->memoryOp = get_memory_op(field->type); field->referenceIndex = -1; switch (field->type->nativeType == NATIVE_MAPPED ? ((MappedType *) field->type)->type->nativeType : field->type->nativeType) { case NATIVE_FUNCTION: case NATIVE_CALLBACK: case NATIVE_POINTER: field->referenceRequired = true; break; default: field->referenceRequired = (rb_respond_to(self, rb_intern("reference_required?")) && RTEST(rb_funcall2(self, rb_intern("reference_required?"), 0, NULL))) || (rb_respond_to(rbType, rb_intern("reference_required?")) && RTEST(rb_funcall2(rbType, rb_intern("reference_required?"), 0, NULL))); break; } return self; }
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); array->length = array->arrayType->length; return self; }
/* * call-seq: put(pointer, value) * @param [AbstractMemory] pointer pointer on a {Struct} * @param [String, Array] value +value+ may be a String only if array's type is a kind of +int8+ * @return [value] * Set an array in a {Struct}. */ 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; }