In Files

  • dl/cfunc.c

DL::CPtr

Public Class Methods

[](p1) click to toggle source
 
               VALUE
rb_dlptr_s_to_ptr(VALUE self, VALUE val)
{
    VALUE ptr;

    if (rb_obj_is_kind_of(val, rb_cIO) == Qtrue){
        rb_io_t *fptr;
        FILE *fp;
        GetOpenFile(val, fptr);
        fp = rb_io_stdio_file(fptr);
        ptr = rb_dlptr_new(fp, 0, NULL);
    }
    else if (rb_obj_is_kind_of(val, rb_cString) == Qtrue){
        char *str = StringValuePtr(val);
        ptr = rb_dlptr_new(str, RSTRING_LEN(val), NULL); 
    }
    else if (rb_respond_to(val, id_to_ptr)){
        VALUE vptr = rb_funcall(val, id_to_ptr, 0);
        if (rb_obj_is_kind_of(vptr, rb_cDLCPtr)){
            ptr = vptr;
        }
        else{
            rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
        }
    }
    else{
        ptr = rb_dlptr_new(NUM2PTR(rb_Integer(val)), 0, NULL);
    }
    OBJ_INFECT(ptr, val);
    return ptr;
}
            
malloc(p1, p2 = v2) click to toggle source
 
               static VALUE
rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
{
  VALUE size, sym, obj;
  int   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);
    break;
  default:
    rb_bug("rb_dlptr_s_malloc");
  }

  obj = rb_dlptr_malloc(s,f);

  return obj;
}
            
new(p1, p2 = v2, p3 = v3) click to toggle source
 
               static VALUE
rb_dlptr_initialize(int argc, VALUE argv[], VALUE self)
{
  VALUE ptr, sym, size;
  struct ptr_data *data;
  void *p = NULL;
  freefunc_t f = NULL;
  long s = 0;

  switch (rb_scan_args(argc, argv, "12", &ptr, &size, &sym)) {
  case 1:
    p = (void*)(NUM2PTR(rb_Integer(ptr)));
    break;
  case 2:
    p = (void*)(NUM2PTR(rb_Integer(ptr)));
    s = NUM2LONG(size);
    break;
  case 3:
    p = (void*)(NUM2PTR(rb_Integer(ptr)));
    s = NUM2LONG(size);
    f = get_freefunc(sym);
    break;
  default:
    rb_bug("rb_dlptr_initialize");
  }

  if (p) {
    Data_Get_Struct(self, struct ptr_data, data);
    if (data->ptr && data->free) {
      /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
      (*(data->free))(data->ptr);
    }
    data->ptr  = p;
    data->size = s;
    data->free = f;
  }

  return Qnil;
}
            
to_ptr(p1) click to toggle source
 
               VALUE
rb_dlptr_s_to_ptr(VALUE self, VALUE val)
{
    VALUE ptr;

    if (rb_obj_is_kind_of(val, rb_cIO) == Qtrue){
        rb_io_t *fptr;
        FILE *fp;
        GetOpenFile(val, fptr);
        fp = rb_io_stdio_file(fptr);
        ptr = rb_dlptr_new(fp, 0, NULL);
    }
    else if (rb_obj_is_kind_of(val, rb_cString) == Qtrue){
        char *str = StringValuePtr(val);
        ptr = rb_dlptr_new(str, RSTRING_LEN(val), NULL); 
    }
    else if (rb_respond_to(val, id_to_ptr)){
        VALUE vptr = rb_funcall(val, id_to_ptr, 0);
        if (rb_obj_is_kind_of(vptr, rb_cDLCPtr)){
            ptr = vptr;
        }
        else{
            rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
        }
    }
    else{
        ptr = rb_dlptr_new(NUM2PTR(rb_Integer(val)), 0, NULL);
    }
    OBJ_INFECT(ptr, val);
    return ptr;
}
            

Public Instance Methods

+(p1) click to toggle source
 
               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);
}
            
+@() click to toggle source
 
               VALUE
rb_dlptr_ptr(VALUE self)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  return rb_dlptr_new(*((void**)(data->ptr)),0,0);
}
            
-(p1) click to toggle source
 
               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);
}
            
-@() click to toggle source
 
               VALUE
rb_dlptr_ref(VALUE self)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  return rb_dlptr_new(&(data->ptr),0,0);
}
            
<=>(p1) click to toggle source
 
               VALUE
rb_dlptr_cmp(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;
    SIGNED_VALUE diff;
    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);
}
            
==(p1) click to toggle source
 
               VALUE
rb_dlptr_eql(VALUE self, VALUE other)
{
  void *ptr1, *ptr2;
  ptr1 = rb_dlptr2cptr(self);
  ptr2 = rb_dlptr2cptr(other);

  return ptr1 == ptr2 ? Qtrue : Qfalse;
}
            
[](p1, p2 = v2) click to toggle source
 
               VALUE
rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
{
    VALUE arg0, arg1;
    VALUE retval = Qnil;
    size_t offset, len;

    switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
    case 1:
        offset = NUM2ULONG(arg0);
        retval = INT2NUM(*((char*)RPTR_DATA(self)->ptr + offset));
        break;
    case 2:
        offset = NUM2ULONG(arg0);
        len    = NUM2ULONG(arg1);
        retval = rb_tainted_str_new((char *)RPTR_DATA(self)->ptr + offset, len);
        break;
    default:
        rb_bug("rb_dlptr_aref()");
    }
    return retval;
}
            
[]=(p1, p2, p3 = v3) click to toggle source
 
               VALUE
rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
{
    VALUE arg0, arg1, arg2;
    VALUE retval = Qnil;
    size_t offset, len;
    void *mem;

    switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
    case 2:
        offset = NUM2ULONG(arg0);
        ((char*)RPTR_DATA(self)->ptr)[offset] = NUM2UINT(arg1);
        retval = arg1;
        break;
    case 3:
        offset = NUM2ULONG(arg0);
        len    = NUM2ULONG(arg1);
        if( TYPE(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 *)RPTR_DATA(self)->ptr + offset, mem, len);
        retval = arg2;
        break;
    default:
        rb_bug("rb_dlptr_aset()");
    }
    return retval;
}
            
eql?(p1) click to toggle source
 
               VALUE
rb_dlptr_eql(VALUE self, VALUE other)
{
  void *ptr1, *ptr2;
  ptr1 = rb_dlptr2cptr(self);
  ptr2 = rb_dlptr2cptr(other);

  return ptr1 == ptr2 ? Qtrue : Qfalse;
}
            
free() click to toggle source
 
               VALUE
rb_dlptr_free_get(VALUE self)
{
  struct ptr_data *pdata;

  Data_Get_Struct(self, struct ptr_data, pdata);

  return rb_dlcfunc_new(pdata->free, DLTYPE_VOID, "free<anonymous>", CFUNC_CDECL);
}
            
free=(p1) click to toggle source
 
               VALUE
rb_dlptr_free_set(VALUE self, VALUE val)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  data->free = get_freefunc(val);

  return Qnil;
}
            
inspect() click to toggle source
 
               VALUE
rb_dlptr_inspect(VALUE self)
{
  struct ptr_data *data;
  char str[1024];

  Data_Get_Struct(self, struct ptr_data, 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?() click to toggle source
 
               VALUE
rb_dlptr_null_p(VALUE self)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  return data->ptr ? Qfalse : Qtrue;
}
            
ptr() click to toggle source
 
               VALUE
rb_dlptr_ptr(VALUE self)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  return rb_dlptr_new(*((void**)(data->ptr)),0,0);
}
            
ref() click to toggle source
 
               VALUE
rb_dlptr_ref(VALUE self)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  return rb_dlptr_new(&(data->ptr),0,0);
}
            
size(p1 = v1) click to toggle source
 
               VALUE
rb_dlptr_size(int argc, VALUE argv[], VALUE self)
{
  VALUE size;

  if (rb_scan_args(argc, argv, "01", &size) == 0){
    return LONG2NUM(RPTR_DATA(self)->size);
  }
  else{
    RPTR_DATA(self)->size = NUM2LONG(size);
    return size;
  }
}
            
size=(p1 = v1) click to toggle source
 
               VALUE
rb_dlptr_size(int argc, VALUE argv[], VALUE self)
{
  VALUE size;

  if (rb_scan_args(argc, argv, "01", &size) == 0){
    return LONG2NUM(RPTR_DATA(self)->size);
  }
  else{
    RPTR_DATA(self)->size = NUM2LONG(size);
    return size;
  }
}
            
to_i() click to toggle source
 
               VALUE
rb_dlptr_to_i(VALUE self)
{
  struct ptr_data *data;

  Data_Get_Struct(self, struct ptr_data, data);
  return PTR2NUM(data->ptr);
}
            
to_s(p1 = v1) click to toggle source
 
               VALUE
rb_dlptr_to_s(int argc, VALUE argv[], VALUE self)
{
  struct ptr_data *data;
  VALUE arg1, val;
  int len;

  Data_Get_Struct(self, struct ptr_data, 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(p1 = v1) click to toggle source
 
               VALUE
rb_dlptr_to_str(int argc, VALUE argv[], VALUE self)
{
  struct ptr_data *data;
  VALUE arg1, val;
  int len;

  Data_Get_Struct(self, struct ptr_data, 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() click to toggle source
 
               VALUE
rb_dlptr_to_value(VALUE self)
{
    struct ptr_data *data;
    Data_Get_Struct(self, struct ptr_data, data);
    return (VALUE)(data->ptr);
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus