summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Meissner <wmeissner@gmail.com>2010-01-27 19:04:33 +1000
committerWayne Meissner <wmeissner@gmail.com>2010-01-27 19:04:33 +1000
commit7675d69be5ceb057ad97e1abb35769ef51ae47ba (patch)
treeb7eb4b5faa46907c5539aba9a94cfd1ad86dab44
parentf3611c44c84a757bc33d5981c05f0209bda709da (diff)
downloadffi-7675d69be5ceb057ad97e1abb35769ef51ae47ba.tar.gz
Implement Pointer#slice and Buffer#slice, and use it for inner structs
-rw-r--r--ext/ffi_c/Buffer.c27
-rw-r--r--ext/ffi_c/Pointer.c29
-rw-r--r--lib/ffi/struct.rb4
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)