123456789_123456789_123456789_123456789_123456789_

Class: FFI::AbstractMemory

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Inherits: Object
Defined in: ext/ffi_c/AbstractMemory.c,
lib/ffi/abstract_memory.rb

Overview

AbstractMemory is the base class for many memory management classes such as Buffer.

This class has a lot of methods to work with integers :

  • put_intsize(offset, value)

  • get_intsize(offset)

  • put_uintsize(offset, value)

  • get_uintsize(offset)

  • writeuintsize(value)

  • read_intsize

  • write_uintsize(value)

  • read_uintsize

  • put_array_of_intsize(offset, ary)

  • get_array_of_intsize(offset, length)

  • put_array_of_uintsize(offset, ary)

  • get_array_of_uintsize(offset, length)

  • write_array_of_intsize(ary)

  • read_array_of_intsize(length)

  • write_array_of_uintsize(ary)

  • read_array_of_uintsize(length)

where size is 8, 16, 32 or 64. Same methods exist for long type.

Aliases exist : char for int8, short for int16, int for int32 and long_long for int64.

Others methods are listed below.

Constant Summary

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#size_limit?Boolean (readonly)

Return true if self has a size limit.

[ GitHub ]

  
# File 'lib/ffi/abstract_memory.rb', line 40

def size_limit?
  size != LONG_MAX
end

Instance Method Details

#[](idx) #read(accessor)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 660

static VALUE
memory_aref(VALUE self, VALUE idx)
{
    AbstractMemory* ptr;
    VALUE rbOffset = Qnil;

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr);

    rbOffset = ULONG2NUM(NUM2ULONG(idx) * ptr->typeSize);

    return rb_funcall2(self, id_plus, 1, &rbOffset);
}

#__copy_from__(rbsrc, rblen)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 681

static VALUE
memory_copy_from(VALUE self, VALUE rbsrc, VALUE rblen)
{
    AbstractMemory* dst;

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, dst);

    memcpy(dst->address, rbffi_AbstractMemory_Cast(rbsrc, &rbffi_abstract_memory_data_type)->address, NUM2INT(rblen));

    return self;
}

#clear #the(memory)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 315

static VALUE
memory_clear(VALUE self)
{
    AbstractMemory* ptr = MEMORY(self);
    checkWrite(ptr);
    memset(ptr->address, 0, ptr->size);
    return self;
}

#freeze

Freeze the AbstractMemory object and unset the writable flag.

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 699

static VALUE
memory_freeze(VALUE self)
{
    AbstractMemory* ptr = MEMORY(self);
    ptr->flags &= ~MEM_WR;
    return rb_call_super(0, NULL);
}

#get(type, offset) #data(of)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 347

static VALUE
memory_get(VALUE self, VALUE type_name, VALUE offset)
{
    AbstractMemory* ptr;
    VALUE nType;
    Type *type;
    MemoryOp *op;

    nType = rbffi_Type_Lookup(type_name);
    if(NIL_P(nType)) goto undefined_type;

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr);
    TypedData_Get_Struct(nType, Type, &rbffi_type_data_type, type);

    op = get_memory_op(type);
    if(op == NULL) goto undefined_type;

    return op->get(ptr, NUM2LONG(offset));

undefined_type: {
    VALUE msg = rb_sprintf("undefined type '%" PRIsVALUE "'", type_name);
    rb_exc_raise(rb_exc_new3(rb_eArgError, msg));
    return Qnil;
  }
}

#get_array_of_double Also known as: #get_array_of_float64

[ GitHub ]

#get_array_of_float Also known as: #get_array_of_float32

[ GitHub ]

#get_array_of_float32

Alias for #get_array_of_float.

#get_array_of_float64

#get_array_of_pointer

[ GitHub ]

#get_array_of_string(offset, count = nil) #an(array)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 444

static VALUE
memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
{
    VALUE offset = Qnil, countnum = Qnil, retVal = Qnil;
    AbstractMemory* ptr;
    long off;
    int count;

    rb_scan_args(argc, argv, "11", &offset, &countnum);
    off = NUM2LONG(offset);
    count = (countnum == Qnil ? 0 : NUM2INT(countnum));
    retVal = rb_ary_new2(count);

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr);
    checkRead(ptr);

    if (countnum != Qnil) {
        int i;

        checkBounds(ptr, off, count * sizeof (char*));

        for (i = 0; i < count; ++i) {
            const char* strptr = *((const char**) (ptr->address + off) + i);
            rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_str_new2(strptr)));
        }

    } else {
        checkBounds(ptr, off, sizeof (char*));
        for ( ; off < ptr->size - (long) sizeof (void *); off += (long) sizeof (void *)) {
            const char* strptr = *(const char**) (ptr->address + off);
            if (strptr == NULL) {
                break;
            }
            rb_ary_push(retVal, rb_str_new2(strptr));
        }
    }

    return retVal;
}

#get_bytes(offset, length) #string(contained)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 544

static VALUE
memory_get_bytes(VALUE self, VALUE offset, VALUE length)
{
    AbstractMemory* ptr = MEMORY(self);
    long off, len;

    off = NUM2LONG(offset);
    len = NUM2LONG(length);

    checkRead(ptr);
    checkBounds(ptr, off, len);

    return rb_str_new((char *) ptr->address + off, len);
}

#get_double Also known as: #get_float64

[ GitHub ]

#get_float Also known as: #get_float32

[ GitHub ]

#get_float32

Alias for #get_float.

#get_float64

Alias for #get_double.

#get_pointer

[ GitHub ]

#get_string(offset, length = nil) #string(contained)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 416

static VALUE
memory_get_string(int argc, VALUE* argv, VALUE self)
{
    VALUE length = Qnil, offset = Qnil;
    AbstractMemory* ptr = MEMORY(self);
    long off, len;
    char* end;
    int nargs = rb_scan_args(argc, argv, "11", &offset, &length);

    off = NUM2LONG(offset);
    len = nargs > 1 && length != Qnil ? NUM2LONG(length) : (ptr->size - off);
    checkRead(ptr);
    checkBounds(ptr, off, len);

    end = memchr(ptr->address + off, 0, len);
    return rb_str_new((char *) ptr->address + off,
            (end != NULL ? end - ptr->address - off : len));
}

#put(type, offset, value)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 380

static VALUE
memory_put(VALUE self, VALUE type_name, VALUE offset, VALUE value)
{
    AbstractMemory* ptr;
    VALUE nType;
    Type *type;
    MemoryOp *op;

    nType = rbffi_Type_Lookup(type_name);
    if(NIL_P(nType)) goto undefined_type;

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr);
    TypedData_Get_Struct(nType, Type, &rbffi_type_data_type, type);

    op = get_memory_op(type);
    if(op == NULL) goto undefined_type;

    op->put(ptr, NUM2LONG(offset), value);
    return Qnil;

undefined_type: {
    VALUE msg = rb_sprintf("unsupported type '%" PRIsVALUE "'", type_name);
    rb_exc_raise(rb_exc_new3(rb_eArgError, msg));
    return Qnil;
  }
}

#put_array_of_double Also known as: #put_array_of_float64

[ GitHub ]

#put_array_of_float Also known as: #put_array_of_float32

[ GitHub ]

#put_array_of_float32

Alias for #put_array_of_float.

#put_array_of_float64

#put_array_of_pointer

[ GitHub ]

#put_bytes(offset, str, index = 0, length = nil) #a(string)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 572

static VALUE
memory_put_bytes(int argc, VALUE* argv, VALUE self)
{
    AbstractMemory* ptr = MEMORY(self);
    VALUE offset = Qnil, str = Qnil, rbIndex = Qnil, rbLength = Qnil;
    long off, len, idx;
    int nargs = rb_scan_args(argc, argv, "22", &offset, &str, &rbIndex, &rbLength);

    Check_Type(str, T_STRING);

    off = NUM2LONG(offset);
    idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
    if (idx < 0) {
        rb_raise(rb_eRangeError, "index cannot be less than zero");
        return Qnil;
    }
    len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
    if ((idx + len) > RSTRING_LEN(str)) {
        rb_raise(rb_eRangeError, "index+length is greater than size of string");
        return Qnil;
    }

    checkWrite(ptr);
    checkBounds(ptr, off, len);

    memcpy(ptr->address + off, RSTRING_PTR(str) + idx, len);

    return self;
}

#put_double Also known as: #put_float64

[ GitHub ]

#put_float Also known as: #put_float32

[ GitHub ]

#put_float32

Alias for #put_float.

#put_float64

Alias for #put_double.

#put_pointer

[ GitHub ]

#put_string(offset, str) #a(string)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 516

static VALUE
memory_put_string(VALUE self, VALUE offset, VALUE str)
{
    AbstractMemory* ptr = MEMORY(self);
    long off, len;

    Check_Type(str, T_STRING);
    off = NUM2LONG(offset);
    len = RSTRING_LEN(str);

    checkWrite(ptr);
    checkBounds(ptr, off, len + 1);

    memcpy(ptr->address + off, RSTRING_PTR(str), len);
    *((char *) ptr->address + off + len) = '\0';

    return self;
}

#read_array_of_double

[ GitHub ]

#read_array_of_float

[ GitHub ]

#read_array_of_pointer

[ GitHub ]

#read_array_of_string(count = nil) #an(array) #get_array_of_string(0, count)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 491

static VALUE
memory_read_array_of_string(int argc, VALUE* argv, VALUE self)
{
    VALUE* rargv = ALLOCA_N(VALUE, argc + 1);
    int i;

    rargv[0] = INT2FIX(0);
    for (i = 0; i < argc; i++) {
        rargv[i + 1] = argv[i];
    }

    return memory_get_array_of_string(argc + 1, rargv, self);
}

#read_bytes(length) #equivalent(to :) #get_bytes(0, length)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 609

static VALUE
memory_read_bytes(VALUE self, VALUE length)
{
    return memory_get_bytes(self, INT2FIX(0), length);
}

#read_double

[ GitHub ]

#read_float

[ GitHub ]

#read_pointer

[ GitHub ]

#size #memory(size)
Also known as: #total

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 329

static VALUE
memory_size(VALUE self)
{
    AbstractMemory* ptr;

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr);

    return LONG2NUM(ptr->size);
}

#size #memory(size)

Alias for #size.

#type_size #the(memory)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 643

static VALUE
memory_type_size(VALUE self)
{
    AbstractMemory* ptr;

    TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr);

    return INT2NUM(ptr->typeSize);
}

#write_array_of_double

[ GitHub ]

#write_array_of_float

[ GitHub ]

#write_array_of_pointer

[ GitHub ]

#write_bytes(str, index = 0, length = nil) #equivalent(to :) #put_bytes(0, str, index, length)

[ GitHub ]

  
# File 'ext/ffi_c/AbstractMemory.c', line 624

static VALUE
memory_write_bytes(int argc, VALUE* argv, VALUE self)
{
    VALUE* wargv = ALLOCA_N(VALUE, argc + 1);
    int i;

    wargv[0] = INT2FIX(0);
    for (i = 0; i < argc; i++) {
        wargv[i + 1] = argv[i];
    }

    return memory_put_bytes(argc + 1, wargv, self);
}

#write_double

[ GitHub ]

#write_float

[ GitHub ]

#write_pointer

[ GitHub ]