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); p->storage = xmalloc(p->memory.size + 7); if (p->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->storage + 0x7) & (uintptr_t) ~0x7UL); if (nargs > 2 && (RTEST(rbClear) || rbClear == Qnil) && p->memory.size > 0) { memset(p->memory.address, 0, p->memory.size); } if (rb_block_given_p()) { return rb_ensure(rb_yield, self, buffer_free, self); } return self; }
/* * call-seq: initialize(size, count=1, clear=true) * @param [Fixnum, Bignum, Symbol, FFI::Type] size size of a memory cell (in bytes, or type whom size will be used) * @param [Numeric] count number of cells in memory * @param [Boolean] clear set memory to all-zero if +true+ * @return [self] * A new instance of FFI::MeoryPointer. */ static VALUE memptr_initialize(int argc, VALUE* argv, VALUE self) { VALUE size = Qnil, count = Qnil, clear = Qnil; int nargs = rb_scan_args(argc, argv, "12", &size, &count, &clear); memptr_malloc(self, rbffi_type_size(size), nargs > 1 ? NUM2LONG(count) : 1, RTEST(clear) || clear == Qnil); if (rb_block_given_p()) { return rb_ensure(rb_yield, self, memptr_free, self); } return self; }
/* * @overload initialize(pointer) * @param [Pointer] pointer another pointer to initialize from * Create a new pointer from another {Pointer}. * @overload initialize(type, address) * @param [Type] type type for pointer * @param [Integer] address base address for pointer * Create a new pointer from a {Type} and a base adresse * @return [self] * A new instance of Pointer. */ static VALUE ptr_initialize(int argc, VALUE* argv, VALUE self) { Pointer* p; VALUE rbType = Qnil, rbAddress = Qnil; int typeSize = 1; Data_Get_Struct(self, Pointer, p); switch (rb_scan_args(argc, argv, "11", &rbType, &rbAddress)) { case 1: rbAddress = rbType; typeSize = 1; break; case 2: typeSize = rbffi_type_size(rbType); break; default: rb_raise(rb_eArgError, "Invalid arguments"); } switch (TYPE(rbAddress)) { case T_FIXNUM: case T_BIGNUM: p->memory.address = (void*) (uintptr_t) NUM2LL(rbAddress); p->memory.size = LONG_MAX; if (p->memory.address == NULL) { p->memory.flags = 0; } break; default: if (rb_obj_is_kind_of(rbAddress, rbffi_PointerClass)) { Pointer* orig; p->rbParent = rbAddress; Data_Get_Struct(rbAddress, Pointer, orig); p->memory = orig->memory; } else { rb_raise(rb_eTypeError, "wrong argument type, expected Integer or FFI::Pointer"); } break; } p->memory.typeSize = typeSize; return self; }