Class: Fiddle::Pointer
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
FFI::DataConverter
|
|
Inherits: | Object |
Defined in: | ext/fiddle/pointer.c, ext/fiddle/lib/fiddle/ffi_backend.rb |
Overview
Pointer
is a class to handle C pointers
Class Method Summary
-
.[](value)
(also: .to_ptr)
call-seq:
- .from_native(value, ctx)
- .malloc(size, free = nil)
-
.new(address) ⇒ fiddle_cptr
constructor
Create a new pointer to
address
with an optional #size andfreefunc
. -
.read(address, len) ⇒ String
Or read the memory at address
address
with lengthlen
and return a string with that memory. - .to_native(value, ctx)
-
.to_ptr(val) ⇒ cptr
(also: .[])
Alias for .[].
-
.write(address, str)
Write bytes in
str
to the location pointed to byaddress
.
Instance Attribute Summary
- #ffi_ptr readonly
-
#free ⇒ Fiddle::Function
rw
Get the free function for this pointer.
-
#free=(function)
rw
Set the free function for this pointer to
function
in the givenFunction
. -
#freed? ⇒ Boolean
readonly
Returns if the free function for this pointer has been called.
-
#null? ⇒ Boolean
readonly
Returns
true
if this is a null pointer. -
#size
rw
Get the size of this pointer.
-
#size=(size)
rw
Set the size of this pointer to #size
Instance Method Summary
-
#+(n) ⇒ new cptr
Returns a new pointer instance that has been advanced
n
bytes. -
#+@
(also: #ptr)
Returns a new
Pointer
instance that is a dereferenced pointer for this pointer. -
#-(n) ⇒ new cptr
Returns a new pointer instance that has been moved back
n
bytes. -
#-@
(also: #ref)
Returns a new
Pointer
instance that is a reference pointer for this pointer. -
#<=>(other) ⇒ 1, ...
Returns -1 if less than, 0 if equal to, 1 if greater than
other
. -
#==(other) ⇒ Boolean
(also: #eql?)
Returns true if
other
wraps the same pointer, otherwise returns false. -
#[](index) ⇒ Integer
Returns integer stored at index.
-
#[]=(index, int) ⇒ Integer
Set the value at
index
toint
. -
#call_free ⇒ nil
Call the free function for this pointer.
-
#eql?(other) ⇒ Boolean
Alias for #==.
- #initialize(addr, size = nil, free = nil) ⇒ Pointer constructor
-
#inspect
Returns a string formatted with an easily readable representation of the internal state of the pointer.
-
#ptr
Alias for #+@.
-
#ref
Alias for #-@.
-
#to_i ⇒ Integer
(also: #to_int)
Returns the integer memory location of this pointer.
-
#to_int
Alias for #to_i.
- #to_ptr
-
#to_s ⇒ String
Returns the pointer contents as a string.
-
#to_str ⇒ String
Returns the pointer contents as a string.
-
#to_value ⇒ ?
Cast this pointer to a ruby object.
Constructor Details
.new(address) ⇒ fiddle_cptr
.new(address, size) ⇒ fiddle_cptr
.new(address, size, freefunc) ⇒ fiddle_cptr
fiddle_cptr
.new(address, size) ⇒ fiddle_cptr
.new(address, size, freefunc) ⇒ fiddle_cptr
Create a new pointer to address
with an optional #size and freefunc
.
freefunc
will be called when the instance is garbage collected.
# File 'ext/fiddle/pointer.c', line 216
static VALUE rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self) { VALUE ptr, sym, size, wrap = 0, funcwrap = 0; struct ptr_data *data; void *p = NULL; freefunc_t f = NULL; long s = 0; if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) { VALUE addrnum = rb_Integer(ptr); if (addrnum != ptr) wrap = ptr; p = NUM2PTR(addrnum); } if (argc >= 2) { s = NUM2LONG(size); } if (argc >= 3) { f = get_freefunc(sym, &funcwrap); } if (p) { TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); if (data->ptr && data->free) { /* Free previous memory. Use of inappropriate initialize may cause SEGV. */ (*(data->free))(data->ptr); } RB_OBJ_WRITE(self, &data->wrap[0], wrap); RB_OBJ_WRITE(self, &data->wrap[1], funcwrap); data->ptr = p; data->size = s; data->free = f; } return Qnil; }
#initialize(addr, size = nil, free = nil) ⇒ Pointer
# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 291
def initialize(addr, size = nil, free = nil) ptr = if addr.is_a?(FFI::Pointer) addr elsif addr.is_a?(Integer) FFI::Pointer.new(addr) elsif addr.respond_to?(:to_ptr) fiddle_ptr = addr.to_ptr if fiddle_ptr.is_a?(Pointer) fiddle_ptr.ffi_ptr elsif fiddle_ptr.is_a?(FFI::AutoPointer) addr.ffi_ptr elsif fiddle_ptr.is_a?(FFI::Pointer) fiddle_ptr else raise DLError.new("to_ptr should return a Fiddle::Pointer object, was #{fiddle_ptr.class}") end elsif addr.is_a?(IO) raise NotImplementedError, "IO ptr isn't supported" end @size = size ? size : ptr.size @free = free @ffi_ptr = ptr @freed = false end
Class Method Details
.[](value) Also known as: .to_ptr
# File 'ext/fiddle/pointer.c', line 772
static VALUE rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val) { VALUE ptr, wrap = val, vptr; if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){ rb_io_t *fptr; FILE *fp; GetOpenFile(val, fptr); fp = rb_io_stdio_file(fptr); ptr = rb_fiddle_ptr_new(fp, 0, NULL); } else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){ char *str = StringValuePtr(val); wrap = val; ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL); } else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){ if (rb_obj_is_kind_of(vptr, rb_cPointer)){ ptr = vptr; wrap = 0; } else{ rb_raise(rb_eFiddleDLError, "to_ptr should return a Fiddle::Pointer object"); } } else{ VALUE num = rb_Integer(val); if (num == val) wrap = 0; ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL); } if (wrap) RB_OBJ_WRITE(ptr, &RPTR_DATA(ptr)->wrap[0], wrap); return ptr; }
.from_native(value, ctx)
[ GitHub ]# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 235
def self.from_native(value, ctx) self.new(value) end
.malloc(size, free = nil)
[ GitHub ]# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 327
def self.malloc(size, free = nil) if block_given? and free.nil? = "a free function must be supplied to #{self}.malloc " + "when it is called with a block" raise ArgumentError, end pointer = new(LibC.malloc(size), size, free) if block_given? begin yield(pointer) ensure pointer.call_free end else pointer end end
.read(address, len) ⇒ String
Or read the memory at address address
with length len
and return a string with that memory
# File 'ext/fiddle/pointer.c', line 815
static VALUE rb_fiddle_ptr_read_mem(VALUE klass, VALUE address, VALUE len) { return rb_str_new((char *)NUM2PTR(address), NUM2ULONG(len)); }
.to_native(value, ctx)
[ GitHub ]
Fiddle::Pointer ⇒ cptr
.to_ptr(val) ⇒ cptr
Also known as: .[]
cptr
.to_ptr(val) ⇒ cptr
Alias for .[].
.write(address, str)
Write bytes in str
to the location pointed to by address
.
# File 'ext/fiddle/pointer.c', line 827
static VALUE rb_fiddle_ptr_write_mem(VALUE klass, VALUE addr, VALUE str) { memcpy(NUM2PTR(addr), StringValuePtr(str), RSTRING_LEN(str)); return str; }
Instance Attribute Details
#ffi_ptr (readonly)
[ GitHub ]# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 219
attr_reader :ffi_ptr
#free ⇒ Fiddle::Function (rw)
# File 'ext/fiddle/pointer.c', line 435
static VALUE rb_fiddle_ptr_free_get(VALUE self) { struct ptr_data *pdata; VALUE address; VALUE arg_types; VALUE ret_type; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); if (!pdata->free) return Qnil; address = PTR2NUM(pdata->free); ret_type = INT2NUM(TYPE_VOID); arg_types = rb_ary_new(); rb_ary_push(arg_types, INT2NUM(TYPE_VOIDP)); return rb_fiddle_new_function(address, arg_types, ret_type); }
#free=(function) (rw)
Set the free function for this pointer to function
in the given Function
.
# File 'ext/fiddle/pointer.c', line 415
static VALUE rb_fiddle_ptr_free_set(VALUE self, VALUE val) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); data->free = get_freefunc(val, &data->wrap[1]); return Qnil; }
#freed? ⇒ Boolean
(readonly)
Returns if the free function for this pointer has been called.
# File 'ext/fiddle/pointer.c', line 476
static VALUE rb_fiddle_ptr_freed_p(VALUE self) { struct ptr_data *pdata; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); return pdata->freed ? Qtrue : Qfalse; }
#null? ⇒ Boolean
(readonly)
Returns true
if this is a null pointer.
# File 'ext/fiddle/pointer.c', line 400
static VALUE rb_fiddle_ptr_null_p(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return data->ptr ? Qfalse : Qtrue; }
#size (rw)
Get the size of this pointer.
# File 'ext/fiddle/pointer.c', line 758
static VALUE rb_fiddle_ptr_size_get(VALUE self) { return LONG2NUM(RPTR_DATA(self)->size); }
#size=(size) (rw)
Set the size of this pointer to #size
# File 'ext/fiddle/pointer.c', line 746
static VALUE rb_fiddle_ptr_size_set(VALUE self, VALUE size) { RPTR_DATA(self)->size = NUM2LONG(size); return size; }
Instance Method Details
#+(n) ⇒ new cptr
Returns a new pointer instance that has been advanced n
bytes.
# File 'ext/fiddle/pointer.c', line 626
static VALUE rb_fiddle_ptr_plus(VALUE self, VALUE other) { void *ptr; long num, size; ptr = rb_fiddle_ptr2cptr(self); size = RPTR_DATA(self)->size; num = NUM2LONG(other); return rb_fiddle_ptr_new((char *)ptr + num, size - num, 0); }
#+@ Also known as: #ptr
Returns a new Pointer
instance that is a dereferenced pointer for this pointer.
Analogous to the star operator in C.
# File 'ext/fiddle/pointer.c', line 369
static VALUE rb_fiddle_ptr_ptr(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return rb_fiddle_ptr_new(*((void**)(data->ptr)),0,0); }
#-(n) ⇒ new cptr
Returns a new pointer instance that has been moved back n
bytes.
# File 'ext/fiddle/pointer.c', line 644
static VALUE rb_fiddle_ptr_minus(VALUE self, VALUE other) { void *ptr; long num, size; ptr = rb_fiddle_ptr2cptr(self); size = RPTR_DATA(self)->size; num = NUM2LONG(other); return rb_fiddle_ptr_new((char *)ptr - num, size + num, 0); }
#-@ Also known as: #ref
Returns a new Pointer
instance that is a reference pointer for this pointer.
Analogous to the ampersand operator in C.
# File 'ext/fiddle/pointer.c', line 386
static VALUE rb_fiddle_ptr_ref(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return rb_fiddle_ptr_new(&(data->ptr),0,0); }
#<=>(other) ⇒ 1
, ...
Returns -1 if less than, 0 if equal to, 1 if greater than other
.
Returns nil if #ptr cannot be compared to other
.
# File 'ext/fiddle/pointer.c', line 605
static VALUE rb_fiddle_ptr_cmp(VALUE self, VALUE other) { void *ptr1, *ptr2; SIGNED_VALUE diff; if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qnil; ptr1 = rb_fiddle_ptr2cptr(self); ptr2 = rb_fiddle_ptr2cptr(other); diff = (SIGNED_VALUE)ptr1 - (SIGNED_VALUE)ptr2; if (!diff) return INT2FIX(0); return diff > 0 ? INT2NUM(1) : INT2NUM(-1); }
#==(other) ⇒ Boolean
#eql?(other) ⇒ Boolean
Also known as: #eql?
Boolean
#eql?(other) ⇒ Boolean
Returns true if other
wraps the same pointer, otherwise returns false.
# File 'ext/fiddle/pointer.c', line 584
static VALUE rb_fiddle_ptr_eql(VALUE self, VALUE other) { void *ptr1, *ptr2; if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qfalse; ptr1 = rb_fiddle_ptr2cptr(self); ptr2 = rb_fiddle_ptr2cptr(other); return ptr1 == ptr2 ? Qtrue : Qfalse; }
#[](index) ⇒ Integer
#[](start, length) ⇒ String
Integer
#[](start, length) ⇒ String
Returns integer stored at index.
If start and length are given, a string containing the bytes from start of length will be returned.
# File 'ext/fiddle/pointer.c', line 666
static VALUE rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self) { VALUE arg0, arg1; VALUE retval = Qnil; size_t offset, len; struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference"); switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){ case 1: offset = NUM2ULONG(arg0); retval = INT2NUM(*((char *)data->ptr + offset)); break; case 2: offset = NUM2ULONG(arg0); len = NUM2ULONG(arg1); retval = rb_str_new((char *)data->ptr + offset, len); break; default: rb_bug("rb_fiddle_ptr_aref()"); } return retval; }
#[]=(index, int) ⇒ Integer
#[]=(start, length, string or cptr or addr) ⇒ String
, ...
Integer
#[]=(start, length, string or cptr or addr) ⇒ String
, ...
Set the value at index
to int
.
Or, set the memory at start
until length
with the contents of string
, the memory from dl_cptr
, or the memory pointed at by the memory address addr
.
# File 'ext/fiddle/pointer.c', line 703
static VALUE rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self) { VALUE arg0, arg1, arg2; VALUE retval = Qnil; size_t offset, len; void *mem; struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference"); switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){ case 2: offset = NUM2ULONG(arg0); ((char*)data->ptr)[offset] = NUM2UINT(arg1); retval = arg1; break; case 3: offset = NUM2ULONG(arg0); len = NUM2ULONG(arg1); if (RB_TYPE_P(arg2, T_STRING)) { mem = StringValuePtr(arg2); } else if( rb_obj_is_kind_of(arg2, rb_cPointer) ){ mem = rb_fiddle_ptr2cptr(arg2); } else{ mem = NUM2PTR(arg2); } memcpy((char *)data->ptr + offset, mem, len); retval = arg2; break; default: rb_bug("rb_fiddle_ptr_aset()"); } return retval; }
#call_free ⇒ nil
Call the free function for this pointer. Calling more than once will do nothing. Does nothing if there is no free function attached.
# File 'ext/fiddle/pointer.c', line 462
static VALUE rb_fiddle_ptr_call_free(VALUE self) { struct ptr_data *pdata; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); fiddle_ptr_free_ptr(pdata); return Qnil; }
#==(other) ⇒ Boolean
#eql?(other) ⇒ Boolean
Boolean
#eql?(other) ⇒ Boolean
Alias for #==.
# File 'ext/fiddle/pointer.c', line 870
def eql?(other) return unless other.is_a?(Pointer) self.to_i == other.to_i end
#inspect
Returns a string formatted with an easily readable representation of the internal state of the pointer.
# File 'ext/fiddle/pointer.c', line 566
static VALUE rb_fiddle_ptr_inspect(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>", RB_OBJ_CLASSNAME(self), (void *)data, data->ptr, data->size, (void *)(VALUE)data->free); }
#+@
#ptr
Alias for #+@.
#-@
#ref
Alias for #-@.
#to_i ⇒ Integer
Also known as: #to_int
Returns the integer memory location of this pointer.
# File 'ext/fiddle/pointer.c', line 339
static VALUE rb_fiddle_ptr_to_i(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return PTR2NUM(data->ptr); }
#to_int
Alias for #to_i.
#to_ptr
[ GitHub ]# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 350
def to_ptr @ffi_ptr end
#to_s ⇒ String
#to_s(len) ⇒ String
String
#to_s(len) ⇒ String
Returns the pointer contents as a string.
When called with no arguments, this method will return the contents until the first NULL byte.
When called with len
, a string of len
bytes will be returned.
See to_str
# File 'ext/fiddle/pointer.c', line 499
static VALUE rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self) { struct ptr_data *data; VALUE arg1, val; int len; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); switch (rb_scan_args(argc, argv, "01", &arg1)) { case 0: val = rb_str_new2((char*)(data->ptr)); break; case 1: len = NUM2INT(arg1); val = rb_str_new((char*)(data->ptr), len); break; default: rb_bug("rb_fiddle_ptr_to_s"); } return val; }
#to_str ⇒ String
#to_str(len) ⇒ String
String
#to_str(len) ⇒ String
Returns the pointer contents as a string.
When called with no arguments, this method will return the contents with the length of this pointer’s #size.
When called with len
, a string of len
bytes will be returned.
See to_s
# File 'ext/fiddle/pointer.c', line 537
static VALUE rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self) { struct ptr_data *data; VALUE arg1, val; int len; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); switch (rb_scan_args(argc, argv, "01", &arg1)) { case 0: val = rb_str_new((char*)(data->ptr),data->size); break; case 1: len = NUM2INT(arg1); val = rb_str_new((char*)(data->ptr), len); break; default: rb_bug("rb_fiddle_ptr_to_str"); } return val; }
#to_value ⇒ ?
Cast this pointer to a ruby object.
# File 'ext/fiddle/pointer.c', line 353
static VALUE rb_fiddle_ptr_to_value(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return (VALUE)(data->ptr); }