Spec-Zone.ru › Ruby 2.4

класс Fiddle::Pointer

Родитель:
Object

Fiddle::Pointer — это класс для работы с указателями C

Публичные методы класса

Fiddle::Pointer[val] → cptr Показать исходный код
to_ptr(val) → cptr
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);
        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_eFiddleError, "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);
    }
    OBJ_INFECT(ptr, val);
    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
    return ptr;
}

Получить базовый указатель для объекта Ruby val и вернуть его как объект Fiddle::Pointer.

Fiddle::Pointer.malloc(size, freefunc = nil) → fiddle pointer instance Показать исходный код
static VALUE
rb_fiddle_ptr_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_fiddle_ptr_s_malloc");
    }

    obj = rb_fiddle_ptr_malloc(s,f);
    if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;

    return obj;
}

Выделить size байта памяти и связать их с необязательной freefunc, которая будет вызвана при сборе мусора указателя.

freefunc должен быть адресом, указывающим на функцию или экземпляр Fiddle::Function

Fiddle::Pointer.new(address) → fiddle_cptr Показать исходный код
new(address, size) → fiddle_cptr
new(address, size, freefunc) → fiddle_cptr
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);
        }
        data->wrap[0] = wrap;
        data->wrap[1] = funcwrap;
        data->ptr  = p;
        data->size = s;
        data->free = f;
    }

    return Qnil;
}

Создать новый указатель на address с необязательной size и freefunc.

freefunc будет вызвана при сборе мусора экземпляра.

to_ptr(val) → cptr Показать исходный код
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);
        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_eFiddleError, "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);
    }
    OBJ_INFECT(ptr, val);
    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
    return ptr;
}

Получить базовый указатель для объекта Ruby val и вернуть его как объект Fiddle::Pointer.

Общедоступные методы экземпляров

ptr + n → new cptr Показать исходный код
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);
}

Возвращает новый экземпляр указателя, сдвинутый на n байтов.

ptr Показать исходный код
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);
}

Возвращает новый экземпляр Fiddle::Pointer, представляющий разыменованный указатель для данного указателя.

Аналогично оператору звездочки в C.

ptr - n → new cptr Показать исходный код
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);
}

Возвращает новый экземпляр указателя, смещённый назад на n байтов.

ref Показать исходный код
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);
}

Возвращает новый экземпляр Fiddle::Pointer, представляющий указатель-ссылку для данного указателя.

Аналогично оператору амперсанда в C.

ptr <=> other → -1, 0, 1, or nil Показать исходный код
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);
}

Возвращает -1, если меньше, 0, если равно, 1, если больше other.

Возвращает nil, если ptr нельзя сравнить с other.

ptr == other → true или false Показать исходный код
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;
}

Возвращает true, если other оборачивает тот же указатель, иначе возвращает false.

ptr[index] → целое Показать исходный код
ptr[start, length] → строка
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_eFiddleError, "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_fiddle_ptr_aref()");
    }
    return retval;
}

Возвращает целое число, хранящееся по адресу index.

Если заданы start и length, возвращается строка, содержащая байты с позиции start длиной length.

ptr[index] = int → int Показать исходный код
ptr[start, length] = строка или cptr или адрес → строка или dl_cptr или адрес
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_eFiddleError, "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;
}

Установить значение по адресу index на int.

Или, установить память по адресу start до length с содержимым string, память с dl_cptr, или память по адресу addr.

eql?(other) → true или false Показать исходный код
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;
}

Возвращает true, если other оборачивает тот же указатель, иначе возвращает false.

free → Fiddle::Function Показать исходный код
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);
}

Получить функцию освобождения для этого указателя.

Возвращает новый экземпляр Fiddle::Function.

См. Fiddle::Function.new

free=(function) Показать исходный код
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;
}

Установить функцию освобождения для этого указателя на function в заданном Fiddle::Function.

inspect Показать исходный код
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), data, data->ptr, data->size, data->free);
}

Возвращает строку, содержащую удобочитаемое представление внутреннего состояния указателя.

null? Показать исходный код
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;
}

Возвращает true, если это нулевой указатель.

ptr Показать исходный код
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);
}

Возвращает новый экземпляр Fiddle::Pointer, представляющий разыменованный указатель для данного указателя.

Аналогично оператору звездочки в C.

ref Показать исходный код
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);
}

Возвращает новый экземпляр Fiddle::Pointer, представляющий указатель-ссылку для данного указателя.

Аналогично оператору амперсанда в C.

size Показать исходный код
static VALUE
rb_fiddle_ptr_size_get(VALUE self)
{
    return LONG2NUM(RPTR_DATA(self)->size);
}

Получить размер этого указателя.

size=(size) Показать исходный код
static VALUE
rb_fiddle_ptr_size_set(VALUE self, VALUE size)
{
    RPTR_DATA(self)->size = NUM2LONG(size);
    return size;
}

Установить размер этого указателя на size

to_i Показать исходный код
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_i Показать исходный код
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_s → строка Показать исходный код
to_s(len) → строка
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_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_fiddle_ptr_to_s");
    }

    return val;
}

Возвращает содержимое указателя как строку.

Без аргументов метод вернёт содержимое до первого нулевого байта.

С аргументом len, вернёт строку из len байтов.

См. #to_str

to_str → строка Показать исходный код
to_str(len) → строка
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_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_fiddle_ptr_to_str");
    }

    return val;
}

Возвращает содержимое указателя как строку.

Без аргументов метод вернёт содержимое с длиной, равной размеру size указателя.

С аргументом len, вернёт строку из len байтов.

См. #to_s

to_value Показать исходный код
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);
}

Преобразует этот указатель в объект руби.

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API