diff options
author | Wayne Meissner <wmeissner@gmail.com> | 2010-01-27 19:04:33 +1000 |
---|---|---|
committer | Wayne Meissner <wmeissner@gmail.com> | 2010-01-27 19:04:33 +1000 |
commit | 7675d69be5ceb057ad97e1abb35769ef51ae47ba (patch) | |
tree | b7eb4b5faa46907c5539aba9a94cfd1ad86dab44 | |
parent | f3611c44c84a757bc33d5981c05f0209bda709da (diff) | |
download | ffi-7675d69be5ceb057ad97e1abb35769ef51ae47ba.tar.gz |
Implement Pointer#slice and Buffer#slice, and use it for inner structs
-rw-r--r-- | ext/ffi_c/Buffer.c | 27 | ||||
-rw-r--r-- | ext/ffi_c/Pointer.c | 29 | ||||
-rw-r--r-- | lib/ffi/struct.rb | 4 |
3 files changed, 46 insertions, 14 deletions
diff --git a/ext/ffi_c/Buffer.c b/ext/ffi_c/Buffer.c index 96c0cc1..c568984 100644 --- a/ext/ffi_c/Buffer.c +++ b/ext/ffi_c/Buffer.c @@ -110,19 +110,18 @@ buffer_alloc_inout(int argc, VALUE* argv, VALUE klass) } static VALUE -buffer_plus(VALUE self, VALUE rbOffset) +slice(VALUE self, long offset, long len) { Buffer* ptr; Buffer* result; VALUE obj = Qnil; - long offset = NUM2LONG(rbOffset); - + Data_Get_Struct(self, Buffer, ptr); - checkBounds(&ptr->memory, offset, 1); + checkBounds(&ptr->memory, offset, len); obj = Data_Make_Struct(BufferClass, Buffer, buffer_mark, -1, result); result->memory.address = ptr->memory.address + offset; - result->memory.size = ptr->memory.size - offset; + result->memory.size = len; result->memory.access = ptr->memory.access; result->memory.typeSize = ptr->memory.typeSize; result->rbParent = self; @@ -131,6 +130,23 @@ buffer_plus(VALUE self, VALUE rbOffset) } static VALUE +buffer_plus(VALUE self, VALUE rbOffset) +{ + Buffer* ptr; + long offset = NUM2LONG(rbOffset); + + Data_Get_Struct(self, Buffer, ptr); + + return slice(self, offset, ptr->memory.size - offset); +} + +static VALUE +buffer_slice(VALUE self, VALUE rbOffset, VALUE rbLength) +{ + return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength)); +} + +static VALUE buffer_inspect(VALUE self) { char tmp[100]; @@ -183,4 +199,5 @@ rbffi_Buffer_Init(VALUE moduleFFI) rb_define_method(BufferClass, "inspect", buffer_inspect, 0); rb_define_alias(BufferClass, "length", "total"); rb_define_method(BufferClass, "+", buffer_plus, 1); + rb_define_method(BufferClass, "slice", buffer_slice, 2); } diff --git a/ext/ffi_c/Pointer.c b/ext/ffi_c/Pointer.c index 0b51516..5bc8e18 100644 --- a/ext/ffi_c/Pointer.c +++ b/ext/ffi_c/Pointer.c @@ -130,20 +130,19 @@ ptr_initialize(int argc, VALUE* argv, VALUE self) static VALUE -ptr_plus(VALUE self, VALUE offset) +slice(VALUE self, long offset, long size) { AbstractMemory* ptr; Pointer* p; VALUE retval; - long off = NUM2LONG(offset); - + Data_Get_Struct(self, AbstractMemory, ptr); - checkBounds(ptr, off, 1); + checkBounds(ptr, offset, 1); retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p); - p->memory.address = ptr->address + off; - p->memory.size = ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off; + p->memory.address = ptr->address + offset; + p->memory.size = size; p->memory.access = ptr->access; p->memory.typeSize = ptr->typeSize; p->parent = self; @@ -152,6 +151,23 @@ ptr_plus(VALUE self, VALUE offset) } static VALUE +ptr_plus(VALUE self, VALUE offset) +{ + AbstractMemory* ptr; + long off = NUM2LONG(offset); + + Data_Get_Struct(self, AbstractMemory, ptr); + + return slice(self, off, ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off); +} + +static VALUE +ptr_slice(VALUE self, VALUE rbOffset, VALUE rbLength) +{ + return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength)); +} + +static VALUE ptr_inspect(VALUE self) { Pointer* ptr; @@ -211,6 +227,7 @@ rbffi_Pointer_Init(VALUE moduleFFI) rb_define_method(rbffi_PointerClass, "initialize", ptr_initialize, -1); rb_define_method(rbffi_PointerClass, "inspect", ptr_inspect, 0); rb_define_method(rbffi_PointerClass, "+", ptr_plus, 1); + rb_define_method(rbffi_PointerClass, "slice", ptr_slice, 2); rb_define_method(rbffi_PointerClass, "null?", ptr_null_p, 0); rb_define_method(rbffi_PointerClass, "address", ptr_address, 0); rb_define_alias(rbffi_PointerClass, "to_i", "address"); diff --git a/lib/ffi/struct.rb b/lib/ffi/struct.rb index 11924cc..5254743 100644 --- a/lib/ffi/struct.rb +++ b/lib/ffi/struct.rb @@ -55,9 +55,7 @@ module FFI class InlineStruct < Field def get(ptr) - # FIXME: really should use ptr#slice(off, len) to limit the inner struct - # to just its part of the outer struct - type.struct_class.new(ptr + self.offset) + type.struct_class.new(ptr.slice(self.offset, self.size)) end # def put(ptr, value) |