A Buffer is a function argument type. It should be use with functions playing with C arrays.
static VALUE buffer_alloc_inout(int argc, VALUE* argv, VALUE klass) { return buffer_initialize(argc, argv, buffer_allocate(klass)); }
static VALUE buffer_alloc_inout(int argc, VALUE* argv, VALUE klass) { return buffer_initialize(argc, argv, buffer_allocate(klass)); }
static VALUE buffer_alloc_inout(int argc, VALUE* argv, VALUE klass) { return buffer_initialize(argc, argv, buffer_allocate(klass)); }
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; }
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); }
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; }
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); }
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; } }
Generated with the Darkfish Rdoc Generator 2.