Class: DL::CPtr
- Inherits:
-
Object
- Object
- DL::CPtr
- Defined in:
- cptr.c
Overview
CPtr is a class to handle C pointers
Direct Known Subclasses
Class Method Summary collapse
-
.[] ⇒ Object
Get the underlying pointer for ruby object
val
and return it as a DL::CPtr object. -
.DL::CPtr.malloc(size, freefunc = nil) ⇒ Object
Allocate
size
bytes of memory and associate it with an optionalfreefunc
that will be called when the pointer is garbage collected. -
.to_ptr ⇒ Object
Get the underlying pointer for ruby object
val
and return it as a DL::CPtr object.
Instance Method Summary collapse
-
#+(n) ⇒ Object
Returns a new DL::CPtr that has been advanced
n
bytes. -
#ptr ⇒ Object
Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr.
-
#-(n) ⇒ Object
Returns a new DL::CPtr that has been moved back
n
bytes. -
#ref ⇒ Object
Returns a DL::CPtr that is a reference pointer for this DL::CPtr.
-
#<=>(other) ⇒ -1, ...
Returns -1 if less than, 0 if equal to, 1 if greater than
other
. -
#== ⇒ Object
Returns true if
other
wraps the same pointer, otherwise returns false. -
#[] ⇒ Object
Returns integer stored at index.
-
#[]= ⇒ Object
Set the value at
index
toint
. -
#eql? ⇒ Boolean
Returns true if
other
wraps the same pointer, otherwise returns false. -
#free ⇒ Object
Get the free function for this pointer.
-
#free=(function) ⇒ Object
Set the free function for this pointer to the DL::CFunc in
function
. -
#initialize ⇒ Object
constructor
Create a new pointer to
address
with an optionalsize
andfreefunc
. -
#inspect ⇒ Object
Returns a string formatted with an easily readable representation of the internal state of the DL::CPtr.
-
#null? ⇒ Boolean
Returns true if this is a null pointer.
-
#ptr ⇒ Object
Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr.
-
#ref ⇒ Object
Returns a DL::CPtr that is a reference pointer for this DL::CPtr.
-
#size ⇒ Object
Get the size of this pointer.
-
#size=(size) ⇒ Object
Set the size of this pointer to
size
. -
#to_i ⇒ Object
Returns the integer memory location of this DL::CPtr.
-
#to_i ⇒ Object
Returns the integer memory location of this DL::CPtr.
-
#to_s ⇒ Object
Returns the pointer contents as a string.
-
#to_str ⇒ Object
Returns the pointer contents as a string.
-
#to_value ⇒ Object
Cast this CPtr to a ruby object.
Constructor Details
#DL::CPtr.new(address) ⇒ Object #DL::CPtr.new(address, size) ⇒ Object #DL::CPtr.new(address, size, freefunc) ⇒ Object
Create a new pointer to address
with an optional size
and freefunc
. freefunc
will be called when the instance is garbage collected.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'cptr.c', line 152
static VALUE
rb_dlptr_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, &dlptr_data_type, data);
if (data->ptr && data->free) {
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
(*(data->free))(data->ptr);
}
data->wrap[0] = wrap;
data->wrap[1] = funcwrap;
data->ptr = p;
data->size = s;
data->free = f;
}
return Qnil;
}
|
Class Method Details
.DL::CPtr.to_ptr(val) ⇒ Object .DL::CPtr ⇒ Object
Get the underlying pointer for ruby object val
and return it as a DL::CPtr object.
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'cptr.c', line 603
static VALUE
rb_dlptr_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_dlptr_new(fp, 0, NULL);
}
else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
char *str = StringValuePtr(val);
ptr = rb_dlptr_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_cDLCPtr)){
ptr = vptr;
wrap = 0;
}
else{
rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
}
}
else{
VALUE num = rb_Integer(val);
if (num == val) wrap = 0;
ptr = rb_dlptr_new(NUM2PTR(num), 0, NULL);
}
OBJ_INFECT(ptr, val);
if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
return ptr;
}
|
.DL::CPtr.malloc(size, freefunc = nil) ⇒ Object
Allocate size
bytes of memory and associate it with an optional freefunc
that will be called when the pointer is garbage collected. freefunc
must be an address pointing to a function or an instance of DL::CFunc
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'cptr.c', line 199
static VALUE
rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
{
VALUE size, sym, obj, wrap = 0;
long s;
freefunc_t f;
switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
case 1:
s = NUM2LONG(size);
f = NULL;
break;
case 2:
s = NUM2LONG(size);
f = get_freefunc(sym, &wrap);
break;
default:
rb_bug("rb_dlptr_s_malloc");
}
obj = rb_dlptr_malloc(s,f);
if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
return obj;
}
|
.DL::CPtr.to_ptr(val) ⇒ Object .DL::CPtr ⇒ Object
Get the underlying pointer for ruby object val
and return it as a DL::CPtr object.
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'cptr.c', line 603
static VALUE
rb_dlptr_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_dlptr_new(fp, 0, NULL);
}
else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
char *str = StringValuePtr(val);
ptr = rb_dlptr_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_cDLCPtr)){
ptr = vptr;
wrap = 0;
}
else{
rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
}
}
else{
VALUE num = rb_Integer(val);
if (num == val) wrap = 0;
ptr = rb_dlptr_new(NUM2PTR(num), 0, NULL);
}
OBJ_INFECT(ptr, val);
if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
return ptr;
}
|
Instance Method Details
#+(n) ⇒ Object
Returns a new DL::CPtr that has been advanced n
bytes.
460 461 462 463 464 465 466 467 468 469 470 |
# File 'cptr.c', line 460
static VALUE
rb_dlptr_plus(VALUE self, VALUE other)
{
void *ptr;
long num, size;
ptr = rb_dlptr2cptr(self);
size = RPTR_DATA(self)->size;
num = NUM2LONG(other);
return rb_dlptr_new((char *)ptr + num, size - num, 0);
}
|
#ptr ⇒ Object
Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr. Analogous to the star operator in C.
258 259 260 261 262 263 264 265 |
# File 'cptr.c', line 258
VALUE
rb_dlptr_ptr(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return rb_dlptr_new(*((void**)(data->ptr)),0,0);
}
|
#-(n) ⇒ Object
Returns a new DL::CPtr that has been moved back n
bytes.
478 479 480 481 482 483 484 485 486 487 488 |
# File 'cptr.c', line 478
static VALUE
rb_dlptr_minus(VALUE self, VALUE other)
{
void *ptr;
long num, size;
ptr = rb_dlptr2cptr(self);
size = RPTR_DATA(self)->size;
num = NUM2LONG(other);
return rb_dlptr_new((char *)ptr - num, size + num, 0);
}
|
#ref ⇒ Object
Returns a DL::CPtr that is a reference pointer for this DL::CPtr. Analogous to the ampersand operator in C.
273 274 275 276 277 278 279 280 |
# File 'cptr.c', line 273
VALUE
rb_dlptr_ref(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return rb_dlptr_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
.
439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'cptr.c', line 439
static VALUE
rb_dlptr_cmp(VALUE self, VALUE other)
{
void *ptr1, *ptr2;
SIGNED_VALUE diff;
if(!rb_obj_is_kind_of(other, rb_cDLCPtr)) return Qnil;
ptr1 = rb_dlptr2cptr(self);
ptr2 = rb_dlptr2cptr(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
Returns true if other
wraps the same pointer, otherwise returns false.
419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'cptr.c', line 419
VALUE
rb_dlptr_eql(VALUE self, VALUE other)
{
void *ptr1, *ptr2;
if(!rb_obj_is_kind_of(other, rb_cDLCPtr)) return Qfalse;
ptr1 = rb_dlptr2cptr(self);
ptr2 = rb_dlptr2cptr(other);
return ptr1 == ptr2 ? Qtrue : Qfalse;
}
|
#[](index) ⇒ Integer #[](start, length) ⇒ String
Returns integer stored at index. If start and length are given, a string containing the bytes from start of length length will be returned.
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
# File 'cptr.c', line 499
VALUE
rb_dlptr_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, &dlptr_data_type, data);
if (!data->ptr) rb_raise(rb_eDLError, "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_tainted_str_new((char *)data->ptr + offset, len);
break;
default:
rb_bug("rb_dlptr_aref()");
}
return retval;
}
|
#[]=(index) ⇒ Integer #[]=(start, length) ⇒ 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
.
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 |
# File 'cptr.c', line 534
VALUE
rb_dlptr_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, &dlptr_data_type, data);
if (!data->ptr) rb_raise(rb_eDLError, "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_cDLCPtr) ){
mem = rb_dlptr2cptr(arg2);
}
else{
mem = NUM2PTR(arg2);
}
memcpy((char *)data->ptr + offset, mem, len);
retval = arg2;
break;
default:
rb_bug("rb_dlptr_aset()");
}
return retval;
}
|
#==(other) ⇒ Boolean #eql?(other) ⇒ Boolean
Returns true if other
wraps the same pointer, otherwise returns false.
419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'cptr.c', line 419
VALUE
rb_dlptr_eql(VALUE self, VALUE other)
{
void *ptr1, *ptr2;
if(!rb_obj_is_kind_of(other, rb_cDLCPtr)) return Qfalse;
ptr1 = rb_dlptr2cptr(self);
ptr2 = rb_dlptr2cptr(other);
return ptr1 == ptr2 ? Qtrue : Qfalse;
}
|
#free ⇒ Object
Get the free function for this pointer. Returns DL::CFunc or nil.
317 318 319 320 321 322 323 324 325 |
# File 'cptr.c', line 317
static VALUE
rb_dlptr_free_get(VALUE self)
{
struct ptr_data *pdata;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, pdata);
return rb_dlcfunc_new(pdata->free, DLTYPE_VOID, "free<anonymous>", CFUNC_CDECL);
}
|
#free=(function) ⇒ Object
Set the free function for this pointer to the DL::CFunc in function
.
301 302 303 304 305 306 307 308 309 310 |
# File 'cptr.c', line 301
static VALUE
rb_dlptr_free_set(VALUE self, VALUE val)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
data->free = get_freefunc(val, &data->wrap[1]);
return Qnil;
}
|
#inspect ⇒ Object
Returns a string formatted with an easily readable representation of the internal state of the DL::CPtr
399 400 401 402 403 404 405 406 407 408 409 |
# File 'cptr.c', line 399
static VALUE
rb_dlptr_inspect(VALUE self)
{
struct ptr_data *data;
char str[1024];
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
snprintf(str, 1023, "#<%s:%p ptr=%p size=%ld free=%p>",
rb_class2name(CLASS_OF(self)), data, data->ptr, data->size, data->free);
return rb_str_new2(str);
}
|
#null? ⇒ Boolean
Returns true if this is a null pointer.
287 288 289 290 291 292 293 294 |
# File 'cptr.c', line 287
VALUE
rb_dlptr_null_p(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return data->ptr ? Qfalse : Qtrue;
}
|
#ptr ⇒ Object
Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr. Analogous to the star operator in C.
258 259 260 261 262 263 264 265 |
# File 'cptr.c', line 258
VALUE
rb_dlptr_ptr(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return rb_dlptr_new(*((void**)(data->ptr)),0,0);
}
|
#ref ⇒ Object
Returns a DL::CPtr that is a reference pointer for this DL::CPtr. Analogous to the ampersand operator in C.
273 274 275 276 277 278 279 280 |
# File 'cptr.c', line 273
VALUE
rb_dlptr_ref(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return rb_dlptr_new(&(data->ptr),0,0);
}
|
#size ⇒ Object
Get the size of this pointer.
589 590 591 592 593 |
# File 'cptr.c', line 589
static VALUE
rb_dlptr_size_get(VALUE self)
{
return LONG2NUM(RPTR_DATA(self)->size);
}
|
#size=(size) ⇒ Object
Set the size of this pointer to size
577 578 579 580 581 582 |
# File 'cptr.c', line 577
static VALUE
rb_dlptr_size_set(VALUE self, VALUE size)
{
RPTR_DATA(self)->size = NUM2LONG(size);
return size;
}
|
#to_i ⇒ Object
Returns the integer memory location of this DL::CPtr.
230 231 232 233 234 235 236 237 |
# File 'cptr.c', line 230
static VALUE
rb_dlptr_to_i(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return PTR2NUM(data->ptr);
}
|
#to_i ⇒ Object
Returns the integer memory location of this DL::CPtr.
230 231 232 233 234 235 236 237 |
# File 'cptr.c', line 230
static VALUE
rb_dlptr_to_i(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return PTR2NUM(data->ptr);
}
|
#to_s ⇒ 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.
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'cptr.c', line 337
static VALUE
rb_dlptr_to_s(int argc, VALUE argv[], VALUE self)
{
struct ptr_data *data;
VALUE arg1, val;
int len;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
switch (rb_scan_args(argc, argv, "01", &arg1)) {
case 0:
val = rb_tainted_str_new2((char*)(data->ptr));
break;
case 1:
len = NUM2INT(arg1);
val = rb_tainted_str_new((char*)(data->ptr), len);
break;
default:
rb_bug("rb_dlptr_to_s");
}
return val;
}
|
#to_str ⇒ 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.
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'cptr.c', line 370
static VALUE
rb_dlptr_to_str(int argc, VALUE argv[], VALUE self)
{
struct ptr_data *data;
VALUE arg1, val;
int len;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
switch (rb_scan_args(argc, argv, "01", &arg1)) {
case 0:
val = rb_tainted_str_new((char*)(data->ptr),data->size);
break;
case 1:
len = NUM2INT(arg1);
val = rb_tainted_str_new((char*)(data->ptr), len);
break;
default:
rb_bug("rb_dlptr_to_str");
}
return val;
}
|
#to_value ⇒ Object
Cast this CPtr to a ruby object.
244 245 246 247 248 249 250 |
# File 'cptr.c', line 244
static VALUE
rb_dlptr_to_value(VALUE self)
{
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
return (VALUE)(data->ptr);
}
|