### Home Classes Methods

### In Files

- ext/ffi_c/ffi.c

### Parent

FFI::AbstractMemory

### Methods

- ::alloc_in
- ::alloc_inout
- ::alloc_out
- ::new
- #+
- #initialize_copy
- #inspect
- #order
- #slice

### Files

- Makefile
- ChangeLog
- LICENSE
- README
- compile
- configure
- depcomp
- stamp-vti
- install-sh
- libtool-version
- mdate-sh
- missing

### Class/Module Index

Quicksearch

- FFI
- FFI::AutoPointer
- FFI::AutoPointer::CallableReleaser
- FFI::AutoPointer::DefaultReleaser
- FFI::AutoPointer::Releaser
- FFI::Buffer
- FFI::ConstGenerator
- FFI::ConstGenerator::Constant
- FFI::DataConverter
- FFI::Enum
- FFI::Enums
- FFI::Generator
- FFI::Generator::Task
- FFI::IO
- FFI::Library
- FFI::ManagedStruct
- FFI::MemoryPointer
- FFI::NotFoundError
- FFI::Platform
- FFI::PlatformError
- FFI::Pointer
- FFI::StrPtrConverter
- FFI::Struct
- FFI::Struct::ManagedStructConverter
- FFI::StructGenerator
- FFI::StructGenerator::Field
- FFI::StructLayout
- FFI::StructLayout::Enum
- FFI::StructLayout::InnerStruct
- FFI::StructLayout::Mapped
- FFI::StructLayoutBuilder
- FFI::TypesGenerator
- FFI::Union
- FFI::VariadicInvoker

No matching classes.

# FFI::Buffer

A Buffer is a function argument type. It should be use with functions playing with C arrays.

### Public Class Methods

alloc_in(*args) click to toggle source
Create a new Buffer for in arguments (alias : new_in).

    static VALUE
    buffer_alloc_inout(int argc, VALUE* argv, VALUE klass)
    {
        return buffer_initialize(argc, argv, buffer_allocate(klass));
    }

alloc_inout(*args) click to toggle source
Create a new Buffer for in and out arguments (alias : new_inout).

    static VALUE
    buffer_alloc_inout(int argc, VALUE* argv, VALUE klass)
    {
        return buffer_initialize(argc, argv, buffer_allocate(klass));
    }

alloc_out(*args) click to toggle source
Create a new Buffer for out arguments (alias : new_out).

    static VALUE
    buffer_alloc_inout(int argc, VALUE* argv, VALUE klass)
    {
        return buffer_initialize(argc, argv, buffer_allocate(klass));
    }

initialize(size, count=1, clear=false) click to toggle source
@param [Integer, Symbol, #size] Type or size in bytes of a buffer cell
@param [Fixnum] count number of cell in the Buffer
@param [Boolean] clear if true, set the buffer to all-zero
@return [self]
@raise {NoMemoryError} if failed to allocate memory for Buffer
A new instance of Buffer.

    static VALUE
    buffer_initialize(int argc, VALUE* argv, VALUE self)
    {
        VALUE rbSize = Qnil, rbCount = Qnil, rbClear = Qnil;
        Buffer* p;
        int nargs;

        Data_Get_Struct(self, Buffer, p);

        nargs = rb_scan_args(argc, argv, "12", &rbSize, &rbCount, &rbClear);
        p->memory.typeSize = rbffi_type_size(rbSize);
        p->memory.size = p->memory.typeSize * (nargs > 1 ? NUM2LONG(rbCount) : 1);

        if (p->memory.size > BUFFER_EMBED_MAXLEN) {
            p->data.storage = xmalloc(p->memory.size + 7);
            if (p->data.storage == NULL) {
                rb_raise(rb_eNoMemError, "Failed to allocate memory size=%lu bytes", p->memory.size);
                return Qnil;
            }

            /* ensure the memory is aligned on at least a 8 byte boundary */
            p->memory.address = (void *) (((uintptr_t) p->data.storage + 0x7) & (uintptr_t) ~0x7UL);

            if (p->memory.size > 0 && (nargs < 3 || RTEST(rbClear))) {
                memset(p->memory.address, 0, p->memory.size);
            }

        } else {
            p->memory.flags |= MEM_EMBED;
            p->memory.address = (void *) &p->data.embed[0];
        }

        if (rb_block_given_p()) {
            return rb_ensure(rb_yield, self, buffer_free, self);
        }

        return self;
    }

### Public Instance Methods

+ offset click to toggle source
@param [Numeric] offset
@return [Buffer] a new instance of Buffer pointing from offset until end of previous buffer.
Add a Buffer with an offset

    static VALUE
    buffer_plus(VALUE self, VALUE rbOffset)
    {
        Buffer* ptr;
        long offset = NUM2LONG(rbOffset);

        Data_Get_Struct(self, Buffer, ptr);

        return slice(self, offset, ptr->memory.size - offset);
    }

initialize_copy(other) click to toggle source
@return [self]
DO NOT CALL THIS METHOD.

    static VALUE
    buffer_initialize_copy(VALUE self, VALUE other)
    {
        AbstractMemory* src;
        Buffer* dst;

        Data_Get_Struct(self, Buffer, dst);
        src = rbffi_AbstractMemory_Cast(other, BufferClass);
        if ((dst->memory.flags & MEM_EMBED) == 0 && dst->data.storage != NULL) {
            xfree(dst->data.storage);
        }
        dst->data.storage = xmalloc(src->size + 7);
        if (dst->data.storage == NULL) {
            rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
            return Qnil;
        }

        dst->memory.address = (void *) (((uintptr_t) dst->data.storage + 0x7) & (uintptr_t) ~0x7UL);
        dst->memory.size = src->size;
        dst->memory.typeSize = src->typeSize;

        /* finally, copy the actual buffer contents */
        memcpy(dst->memory.address, src->address, src->size);

        return self;
    }

inspect click to toggle source
@return [String]
Inspect a Buffer.

    static VALUE
    buffer_inspect(VALUE self)
    {
        char tmp[100];
        Buffer* ptr;

        Data_Get_Struct(self, Buffer, ptr);

        snprintf(tmp, sizeof(tmp), "#<FFI:Buffer:%p address=%p size=%ld>", ptr, ptr->memory.address, ptr->memory.size);

        return rb_str_new2(tmp);
    }

order(p1) click to toggle source

Set or get endianness of Buffer. @overload order

    @return [:big, :little]
    Get endianness of Buffer.

@overload order(order)

    @param [:big, :little, :network] order
    @return [self]
    Set endinaness of Buffer (+:network+ is an alias for +:big+).

    static VALUE
    buffer_order(int argc, VALUE* argv, VALUE self)
    {
        Buffer* ptr;

        Data_Get_Struct(self, Buffer, ptr);
        if (argc == 0) {
            int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER;
            return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little"));
        } else {
            VALUE rbOrder = Qnil;
            int order = BYTE_ORDER;

            if (rb_scan_args(argc, argv, "1", &rbOrder) < 1) {
                rb_raise(rb_eArgError, "need byte order");
            }
            if (SYMBOL_P(rbOrder)) {
                ID id = SYM2ID(rbOrder);
                if (id == rb_intern("little")) {
                    order = LITTLE_ENDIAN;

                } else if (id == rb_intern("big") || id == rb_intern("network")) {
                    order = BIG_ENDIAN;
                }
            }
            if (order != BYTE_ORDER) {
                Buffer* p2;
                VALUE retval = slice(self, 0, ptr->memory.size);

                Data_Get_Struct(retval, Buffer, p2);
                p2->memory.flags |= MEM_SWAP;
                return retval;
            }

            return self;
        }
    }

slice(offset, length) click to toggle source
@param [Numeric] offset
@param [Numeric] length
@return [Buffer] a new instance of Buffer
Slice an existing Buffer.

    static VALUE
    buffer_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
    {
        return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
    }

[Validate]

Generated with the Darkfish Rdoc Generator 2.