Exemplo n.º 1
0
static VALUE
rb_gl_buffer_read(int argc, VALUE *argv, VALUE self) {
	struct buffer *buf;
	VALUE _length, _offset;
	GLsizeiptr offset, length;

	TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);

	rb_scan_args(argc, argv, "02", &_length, &_offset);

	if (buf->len == 0 && NIL_P(_length))
		rb_raise(rb_eArgError, "length must be provided for unbounded buffer");

	length = NUM2SIZET(_length);

	if (NIL_P(_offset)) {
		offset = 0;
	} else {
		offset = NUM2SIZET(_offset);
	}

	if (buf->len != 0 && length + offset > buf->len)
		rb_raise(rb_eArgError, "read to %lu past end of buffer %lu",
				(unsigned long)(length + offset), (unsigned long)buf->len);

	return rb_str_new((char *)buf->ptr + offset, length);
}
Exemplo n.º 2
0
static VALUE mmap_initialize(int argc, VALUE *argv, VALUE obj)
{
    mmap_data_t *data;
    VALUE file, voffset, vlength;
    off_t offset = 0;
    size_t length = 0;
    int fd;
    struct stat st;
    void *ptr;

    Data_Get_Struct(obj, mmap_data_t, data);
    if (data->ptr)
        rb_raise(rb_eRuntimeError, "already mapped");
    rb_scan_args(argc, argv, "12", &file, &voffset, &vlength);
    if (TYPE(file) != T_FILE)
        rb_raise(rb_eTypeError, "File object required");
    if (voffset != Qnil && NUM2LL(voffset) < 0)
        rb_raise(rb_eRangeError, "offset out of range: %lld", NUM2LL(voffset));
    if (vlength != Qnil && NUM2LL(vlength) < 0)
        rb_raise(rb_eRangeError, "length out of range: %lld", NUM2LL(vlength));
    fd = FIX2INT(rb_funcall(file, rb_intern("fileno"), 0));
    if (fstat(fd, &st) < 0)
        rb_sys_fail("fstat");
    offset = voffset == Qnil ? 0 : NUM2SIZET(voffset);
    length = vlength == Qnil ? st.st_size : NUM2SIZET(vlength);
    if (offset + length > st.st_size)
        length = st.st_size - offset;
    if ((ptr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, offset)) == MAP_FAILED)
        rb_sys_fail("mmap");

    data->ptr = ptr;
    data->size = length;
    return Qnil;
}
Exemplo n.º 3
0
static VALUE initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE src, voffset, vsize;
    size_t offset, size;
    size_t src_offset = 0, src_size = 0;
    mmapscanner_t *self;
    int src_size_defined = 0;

    rb_scan_args(argc, argv, "12", &src, &voffset, &vsize);
    if (voffset != Qnil && NUM2LL(voffset) < 0)
        rb_raise(rb_eRangeError, "offset out of range: %lld", NUM2LL(voffset));
    if (vsize != Qnil && NUM2LL(vsize) < 0)
        rb_raise(rb_eRangeError, "length out of range: %lld", NUM2LL(vsize));
    offset = voffset == Qnil ? 0 : NUM2SIZET(voffset);
    if (rb_obj_class(src) == cMmapScanner) {
        mmapscanner_t *ms;
        Data_Get_Struct(src, mmapscanner_t, ms);
        src_offset = ms->offset;
        src_size = ms->size;
        src = ms->data;
        src_size_defined = 1;
    } else if (TYPE(src) == T_FILE) {
        int fd = FIX2INT(rb_funcall(src, rb_intern("fileno"), 0));
        struct stat st;
        if (fstat(fd, &st) < 0)
            rb_sys_fail("fstat");
        if (st.st_size == 0) {
            src = rb_str_new(NULL, 0);
            src_size = 0;
        } else {
            src = rb_funcall(cMmap, rb_intern("new"), 1, src);
        }
    }
    if (rb_obj_class(src) == cMmap) {
        if (!src_size_defined) {
            mmap_data_t *data;
            Data_Get_Struct(src, mmap_data_t, data);
            src_size = data->size;
        }
    } else if (TYPE(src) == T_STRING) {
        if (!src_size_defined)
            src_size = RSTRING_LEN(src);
    } else {
        rb_raise(rb_eTypeError, "wrong argument type %s (expected File/String/MmapScanner/MmapScanner::Mmap)", rb_obj_classname(src));
    }
    if (offset > src_size)
        rb_raise(rb_eRangeError, "length out of range: %zu > %zu", offset, src_size);
    size = vsize == Qnil ? src_size - offset : NUM2SIZET(vsize);
    if (size > src_size - offset)
        size = src_size - offset;

    Data_Get_Struct(obj, mmapscanner_t, self);
    self->offset = src_offset + offset;
    self->size = size;
    self->pos = 0;
    self->matched = 0;
    self->matched_pos = 0;
    self->data = src;
    return Qnil;
}
Exemplo n.º 4
0
/*
 *  call-seq:
 *    Settings[option] = value
 *
 *  Sets a libgit2 library option.
 */
static VALUE rb_git_set_option(VALUE self, VALUE option, VALUE value)
{
	const char *opt;

	Check_Type(option, T_STRING);
	opt = StringValueCStr(option);

	if (strcmp(opt, "mwindow_size") == 0) {
		size_t val;
		Check_Type(value, T_FIXNUM);
		val = NUM2SIZET(value);
		git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, val);
	}
	
	else if (strcmp(opt, "mwindow_mapped_limit") == 0) {
		size_t val;
		Check_Type(value, T_FIXNUM);
		val = NUM2SIZET(value);
		git_libgit2_opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, val);
	}

	else {
		rb_raise(rb_eArgError, "Unknown option specified");
	}

	return Qnil;
}
Exemplo n.º 5
0
// read from buffer and return a ruby string
// params: dest, dest_start=0, src_start=0, len=self.length
// return: bytes copied
VALUE ruv_buffer_copy(int argc, VALUE* argv, VALUE rb_src) {
    VALUE  rb_dest, rb_dest_start, rb_src_start, rb_length;
    size_t dest_start, src_start, length;
    ruv_buffer_t *src, *dest;

    rb_scan_args(argc, argv, "13", &rb_dest, &rb_dest_start, &rb_src_start, &rb_length);

    if(!rb_obj_is_kind_of(rb_dest, rb_obj_class(rb_src))) {
        rb_raise(rb_eArgError, "Dest is not a buffer");
    }

    Data_Get_Struct(rb_src, ruv_buffer_t, src);
    Data_Get_Struct(rb_dest, ruv_buffer_t, dest);

    if(!NIL_P(rb_dest_start)) {
        Check_Type(rb_dest_start, T_FIXNUM);
        dest_start = NUM2SIZET(rb_dest_start);
    } else {
        dest_start = 0;
    }
    if(dest_start >= dest->length) {
        rb_raise(rb_eArgError, "dest_start is out of bounds.");
    }

    if(!NIL_P(rb_src_start)) {
        Check_Type(rb_src_start, T_FIXNUM);
        src_start = NUM2SIZET(rb_src_start);
    } else {
        src_start = 0;
    }
    if(src_start >= src->length) {
        rb_raise(rb_eArgError, "src_start is out of bounds.");
    }

    if(!NIL_P(rb_length)) {
        Check_Type(rb_length, T_FIXNUM);
        length = NUM2SIZET(rb_length);
    } else {
        length = src->length - src_start;
    }

    // make sure it's not out of bound
    length = MIN(length, src->length - src_start);
    length = MIN(length, dest->length - dest_start);

    memcpy(dest->data + dest_start, src->data + src_start, length);

    return SIZET2NUM(length);
}
Exemplo n.º 6
0
static VALUE
nst_allocate(VALUE self)
{
    narray_t *na;
    char *ptr;
    VALUE velmsz;

    GetNArray(self,na);

    switch(NA_TYPE(na)) {
    case NARRAY_DATA_T:
        ptr = NA_DATA_PTR(na);
        if (na->size > 0 && ptr == NULL) {
            velmsz = rb_const_get(CLASS_OF(self), rb_intern("element_byte_size"));
            ptr = xmalloc(NUM2SIZET(velmsz) * na->size);
            NA_DATA_PTR(na) = ptr;
        }
        break;
    case NARRAY_VIEW_T:
        rb_funcall(NA_VIEW_DATA(na), rb_intern("allocate"), 0);
        break;
    case NARRAY_FILEMAP_T:
        //ptr = ((narray_filemap_t*)na)->ptr;
        // to be implemented
    default:
        rb_bug("invalid narray type : %d",NA_TYPE(na));
    }
    return self;
}
Exemplo n.º 7
0
static VALUE
rb_gl_buffer_write(int argc, VALUE *argv, VALUE self) {
	struct buffer *buf;
	VALUE _data, _offset;
	GLsizeiptr offset;
	long length;

	TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);

	if (!buf->ptr)
		rb_raise(rb_eArgError, "write to unmapped buffer");

	rb_scan_args(argc, argv, "11", &_data, &_offset);

	if (NIL_P(_data))
		rb_raise(rb_eArgError, "cannot write nil to buffer");

	_data = rb_String(_data);

	length = RSTRING_LEN(_data);

	if (NIL_P(_offset)) {
		offset = 0;
	} else {
		offset = NUM2SIZET(_offset);
	}

	if (buf->len != 0 && length + offset > buf->len)
		rb_raise(rb_eArgError, "write to %lu past end of buffer %lu",
				(unsigned long)(length + offset), (unsigned long)buf->len);

	memcpy((char *)buf->ptr + offset, RSTRING_PTR(_data), RSTRING_LEN(_data));

	return self;
}
Exemplo n.º 8
0
/*
 * Generate a multi-click event at the current mouse position
 *
 * Unlike {Mouse.double_click} and {Mouse.triple_click} this will generate
 * a single event with the given number of clicks.
 *
 * You can optionally specify a point to click; the mouse cursor will
 * instantly jump to the given point; otherwise the click event happens
 * at the current cursor position.
 *
 * @overload multi_click(num_clicks)
 *   @param num_clicks [Number,#to_i]
 *   @return [CGPoint]
 * @overload multi_click(num_clicks, point)
 *   @param num_clicks [Number,#to_i]
 *   @param point [CGPoint]
 *   @return [CGPoint]
 */
static
VALUE
rb_mouse_multi_click(const int argc,
                     VALUE* const argv,
                     UNUSED const VALUE self)
{

    if (argc == 0) {
        rb_raise(rb_eArgError, "multi_click requires at least one arg");
        return Qnil;
    }

    // TODO: there has got to be a more idiomatic way to do this coercion
    const size_t num_clicks = NUM2SIZET(argv[0]);

    switch (argc) {
    case 1:
        mouse_multi_click(num_clicks);
        break;
    case 2:
    default:
        mouse_multi_click2(num_clicks, rb_mouse_unwrap_point(argv[1]));
    }

    return CURRENT_POSITION;
}
Exemplo n.º 9
0
/*
 * call-seq:
 *	Raindrops.new(size)	-> raindrops object
 *
 * Initializes a Raindrops object to hold +size+ counters.  +size+ is
 * only a hint and the actual number of counters the object has is
 * dependent on the CPU model, number of cores, and page size of
 * the machine.  The actual size of the object will always be equal
 * or greater than the specified +size+.
 */
static VALUE init(VALUE self, VALUE size)
{
	struct raindrops *r = DATA_PTR(self);
	int tries = 1;
	size_t tmp;

	if (r->drops != MAP_FAILED)
		rb_raise(rb_eRuntimeError, "already initialized");

	r->size = NUM2SIZET(size);
	if (r->size < 1)
		rb_raise(rb_eArgError, "size must be >= 1");

	tmp = PAGE_ALIGN(raindrop_size * r->size);
	r->capa = tmp / raindrop_size;
	assert(PAGE_ALIGN(raindrop_size * r->capa) == tmp && "not aligned");

retry:
	r->drops = mmap(NULL, tmp,
	                PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
	if (r->drops == MAP_FAILED) {
		if ((errno == EAGAIN || errno == ENOMEM) && tries-- > 0) {
			rb_gc();
			goto retry;
		}
		rb_sys_fail("mmap");
	}
	r->pid = getpid();

	return self;
}
Exemplo n.º 10
0
static void
iter_nstruct_to_a(na_loop_t *const lp)
{
    long    i, len;
    VALUE   opt, types, defs, def;
    VALUE   elmt, velm, vary;
    size_t  ofs, pos;
    narray_view_t *ne;

    opt = lp->option;
    types = RARRAY_AREF(opt,0);
    defs = RARRAY_AREF(opt,1);
    pos = lp->args[0].iter[0].pos;

    len = RARRAY_LEN(types);
    vary = rb_ary_new2(len);

    for (i=0; i<len; i++) {
        def  = RARRAY_AREF(defs,i);
        ofs  = NUM2SIZET(RARRAY_AREF(def,2));
        //ofs  = NUM2SIZET(RARRAY_AREF(ofsts,i));
        elmt = RARRAY_AREF(types,i);
        GetNArrayView(elmt,ne);
        ne->offset = pos + ofs;
        if (ne->base.ndim==0) {
            velm = rb_funcall(elmt,rb_intern("extract"),0);
        } else {
            velm = rb_funcall(elmt,rb_intern("to_a"),0);
        }
        rb_ary_push(vary, velm);
    }
    rb_ary_push(lp->args[1].value, vary);
}
Exemplo n.º 11
0
// ------
static void
iter_nstruct_from_a(na_loop_t *const lp)
{
    long  i, len;
    VALUE ary;
    VALUE types, defs, def;
    VALUE elmt, item;
    size_t ofs;
    narray_view_t *ne;

    types = RARRAY_AREF(lp->option,0);
    defs = RARRAY_AREF(lp->option,1);

    len = RARRAY_LEN(types);
    ary = lp->args[0].value;
    //rb_p(CLASS_OF(ary));rb_p(ary);

    for (i=0; i<len; i++) {
        def  = RARRAY_AREF(defs,i);
        ofs  = NUM2SIZET(RARRAY_AREF(def,2));
        elmt = RARRAY_AREF(types,i);
        GetNArrayView(elmt,ne);
        ne->offset = lp->args[1].iter[0].pos + ofs;
        item = RARRAY_AREF(ary,i);
        //rb_p(ary);
        //rb_p(item);
        //rb_p(elmt);
        //abort();
        rb_funcall(elmt, rb_intern("store"), 1, item);
    }
}
Exemplo n.º 12
0
static VALUE gl_VertexAttribPointerNV(VALUE obj,VALUE arg1,VALUE arg2,VALUE arg3,VALUE arg4,VALUE arg5)
{
	GLuint index;
	GLuint size;
	GLenum type;
	GLsizei stride;

	LOAD_GL_FUNC(glVertexAttribPointerNV, "GL_NV_vertex_program");

	index = (GLuint)NUM2UINT(arg1);
	size = (GLuint)NUM2UINT(arg2);
	type = (GLenum)NUM2INT(arg3);
	stride = (GLsizei)NUM2UINT(arg4);
	if (index>_MAX_VERTEX_ATTRIBS)
		rb_raise(rb_eArgError, "Index too large, maximum allowed value '%i'",_MAX_VERTEX_ATTRIBS);

	if (CheckBufferBinding(GL_ARRAY_BUFFER_BINDING)) {
		g_VertexAttrib_ptr[index] = arg5;
		fptr_glVertexAttribPointerNV(index,size,type,stride,(GLvoid *)NUM2SIZET(arg5));
	} else {
		VALUE data;
		data = pack_array_or_pass_string(type,arg5);
		rb_str_freeze(data);
		g_VertexAttrib_ptr[index] = data;
		fptr_glVertexAttribPointerNV(index,size,type,stride,(GLvoid *)RSTRING_PTR(data));
	}

	CHECK_GLERROR_FROM("glVertexAttribPointerNV");
	return Qnil;
}
Exemplo n.º 13
0
// read from buffer and return a ruby string
// params: start=0, length=self.length, encoding=Encoding.default_internal_encoding
// return: ruby string
VALUE ruv_buffer_read(int argc, VALUE* argv, VALUE rb_buffer) {
    VALUE rb_start, rb_length, rb_intern_enc, rb_str;
    size_t start, length;
    rb_encoding  *intern_enc;
    ruv_buffer_t *buffer;
    char *str_p;

    Data_Get_Struct(rb_buffer, ruv_buffer_t, buffer);

    rb_scan_args(argc, argv, "03", &rb_start, &rb_length, &rb_intern_enc);

    if(!NIL_P(rb_start)) {
        Check_Type(rb_start, T_FIXNUM);
        start = NUM2SIZET(rb_start);
    } else {
        start = 0;
    }
    if(start >= buffer->length) {
        rb_raise(rb_eArgError, "start is out of bounds.");
    }

    if(!NIL_P(rb_length)) {
        Check_Type(rb_length, T_FIXNUM);
        length = NUM2SIZET(length);
    } else {
        length = buffer->length - start;
    }

    // make sure it's not out of bound
    length = MIN(length, buffer->length - start);

    if(!NIL_P(rb_intern_enc)) {
        intern_enc = rb_enc_get(rb_intern_enc);
    } else {
        intern_enc = rb_default_internal_encoding();
    }

    str_p = buffer->data + start;

    rb_str = rb_tainted_str_new(str_p, length);

    if(intern_enc) {
        rb_str = rb_str_export_to_enc(rb_str, intern_enc);
    }

    return rb_str;
}
Exemplo n.º 14
0
static VALUE
rb_queue_apply(VALUE self, SEL sel, VALUE n)
{
    rb_vm_block_t *block = get_prepared_block();
    dispatch_apply_f(NUM2SIZET(n), RQueue(self)->queue, (void *)block,
	    rb_block_applier);

    GC_RELEASE(block);

    return Qnil;
}
Exemplo n.º 15
0
// read from buffer and return a ruby string
// params: value, start=0, end=self.length
// return: bytes copied
VALUE ruv_buffer_fill(int argc, VALUE* argv, VALUE rb_buffer) {
    VALUE rb_value, rb_start, rb_length;
    size_t start, length;
    ruv_buffer_t *buffer;
    int value;

    Data_Get_Struct(rb_buffer, ruv_buffer_t, buffer);

    rb_scan_args(argc, argv, "12", &rb_value, &rb_start, &rb_length);

    value = NUM2INT(rb_value);
    if(value > 255 || value < 0) {
        rb_raise(rb_eArgError, "value must be between 0 to 255");
    }

    if(!NIL_P(rb_start)) {
        Check_Type(rb_start, T_FIXNUM);
        start = NUM2SIZET(rb_start);
    } else {
        start = 0;
    }

    if(start >= buffer->length) {
        rb_raise(rb_eArgError, "start is out of bounds.");
    }

    if(!NIL_P(rb_length)) {
        Check_Type(rb_length, T_FIXNUM);
        length = NUM2SIZET(length);
    } else {
        length = buffer->length - start;
    }

    // make sure it's not out of bound
    length = MIN(length, buffer->length - start);

    memset(buffer->data + start, value, length);

    return SIZET2NUM(length);

}
Exemplo n.º 16
0
/*
 * call-seq:
 *	rd.size = new_size
 *
 * Increases or decreases the current capacity of our Raindrop.
 * Raises RangeError if +new_size+ is too big or small for the
 * current backing store
 */
static VALUE setsize(VALUE self, VALUE new_size)
{
	size_t new_rd_size = NUM2SIZET(new_size);
	struct raindrops *r = get(self);

	if (new_rd_size <= r->capa)
		r->size = new_rd_size;
	else
		resize(r, new_rd_size);

	return new_size;
}
Exemplo n.º 17
0
VALUE ruv_buffer_init(VALUE rb_buffer, VALUE rb_length) {
    Check_Type(rb_length, T_FIXNUM);

    size_t len = NUM2SIZET(rb_length);

    ruv_buffer_t* buffer;
    Data_Get_Struct(rb_buffer, ruv_buffer_t, buffer);

    buffer->data      = (char*)malloc(len);
    buffer->length    = len;

    return rb_buffer;
}
Exemplo n.º 18
0
static VALUE
my_malloc_init(VALUE self, VALUE size) {
  struct my_malloc *ptr;
  size_t requested = NUM2SIZET(size);

  if (0 == requested)
    rb_raise(rb_eArgError, "unable to allocate 0 bytes");

  Data_Get_Struct(self, struct my_malloc, ptr);

  ptr->ptr = malloc(requested);

  if (NULL == ptr->ptr)
    rb_raise(rb_eNoMemError, "unable to allocate %" PRIuSIZE " bytes", requested);
  
  ptr->size = requested;

  return self;
}
Exemplo n.º 19
0
void
Init_oobgc()
{
  mOOB = rb_define_module_under(rb_mGC, "OOB");
  rb_autoload(mOOB, rb_intern_const("UnicornMiddleware"), "gctools/oobgc/unicorn_middleware.rb");

  rb_define_singleton_method(mOOB, "setup", install, 0);
  rb_define_singleton_method(mOOB, "run", oobgc_run, 0);
  rb_define_singleton_method(mOOB, "dry_run", oobgc_dry_run, 0);
  rb_define_singleton_method(mOOB, "stat", oobgc_stat, 1);
  rb_define_singleton_method(mOOB, "clear", oobgc_clear, 0);

#define S(name) sym_##name = ID2SYM(rb_intern(#name));
  S(total_allocated_object);
  S(heap_swept_slot);
  S(heap_tomb_page_length);
  S(heap_final_slot);

  S(old_object);
  S(old_object_limit);
  S(remembered_shady_object);
  S(remembered_shady_object_limit);

  S(major_by);
  S(count);
  S(major_count);
  S(minor_count);
  S(sweep_count);
#undef S

  id_start = rb_intern("start");
  _oobgc.heap_obj_limit =
    NUM2SIZET(rb_hash_aref(rb_const_get(rb_mGC, rb_intern("INTERNAL_CONSTANTS")), ID2SYM(rb_intern("HEAP_OBJ_LIMIT"))));

  minor_gc_args = rb_hash_new();
  rb_hash_aset(minor_gc_args, ID2SYM(rb_intern("full_mark")), Qfalse);
  rb_ivar_set(mOOB, rb_intern("minor_gc_args"), minor_gc_args);
}
Exemplo n.º 20
0
static VALUE
//iter_struct_inspect(na_loop_t *const lp)
iter_struct_inspect(char *ptr, size_t pos, VALUE opt)
{
    VALUE   types, defs, def, name, elmt, vary, v, x;
    size_t  ofs;
    long    i, len;
    narray_view_t *ne;

    types = RARRAY_AREF(opt,0);
    defs = RARRAY_AREF(opt,1);

    len = RARRAY_LEN(types);
    vary = rb_ary_new2(len);

    for (i=0; i<len; i++) {
        def  = RARRAY_AREF(defs,i);
        name = RARRAY_AREF(def,0);
        ofs  = NUM2SIZET(RARRAY_AREF(def,2));
        elmt = RARRAY_AREF(types,i);
        GetNArrayView(elmt,ne);
        ne->offset = pos + ofs;
        v = rb_str_concat(rb_sym_to_s(name), rb_str_new2(": "));
        x = rb_funcall(elmt, rb_intern("format_to_a"), 0);        // <-- fix me
        if (ne->base.ndim==0) {
            x = rb_funcall(x, rb_intern("first"), 0);
        }
        x = rb_funcall(x, rb_intern("to_s"), 0);
        v = rb_str_concat(v, x);
        rb_ary_push(vary, v);
    }
    v = rb_ary_join(vary, rb_str_new2(", "));
    v = rb_str_concat(rb_str_new2("["), v);
    v = rb_str_concat(v, rb_str_new2("]"));
    return v;
}
Exemplo n.º 21
0
VALUE
na_make_view_struct(VALUE self, VALUE dtype, VALUE offset)
{
    size_t i, n;
    int j, k, ndim;
    size_t *shape;
    size_t *idx1, *idx2;
    ssize_t stride;
    stridx_t *stridx;
    narray_t *na, *nt;
    narray_view_t *na1, *na2;
    VALUE klass;
    volatile VALUE view;

    GetNArray(self,na);

    // build from Numo::Struct
    if (rb_obj_is_kind_of(dtype,cNArray)) {
	GetNArray(dtype,nt);
        ndim = na->ndim + nt->ndim;
        shape = ALLOCA_N(size_t,ndim);
        // struct dimensions
        for (j=0; j<na->ndim; j++) {
            shape[j] = na->shape[j];
        }
        // member dimension
        for (j=na->ndim,k=0; j<ndim; j++,k++) {
            shape[j] = nt->shape[k];
        }
        klass = CLASS_OF(dtype);
        stridx = ALLOC_N(stridx_t, ndim);
        stride = na_dtype_elmsz(klass);
        for (j=ndim,k=nt->ndim; k; ) {
            SDX_SET_STRIDE(stridx[--j],stride);
            stride *= nt->shape[--k];
        }
    } else {
        ndim = na->ndim;
        shape = ALLOCA_N(size_t,ndim);
        for (j=0; j<ndim; j++) {
            shape[j] = na->shape[j];
        }
        klass = CLASS_OF(self);
        if (TYPE(dtype)==T_CLASS) {
            if (RTEST(rb_class_inherited_p(dtype,cNArray))) {
                klass = dtype;
            }
        }
        stridx = ALLOC_N(stridx_t, ndim);
    }

    view = na_s_allocate_view(klass);
    na_copy_flags(self, view);
    GetNArrayView(view, na2);
    na_setup_shape((narray_t*)na2, ndim, shape);
    na2->stridx = stridx;

    switch(na->type) {
    case NARRAY_DATA_T:
    case NARRAY_FILEMAP_T:
        stride = na_get_elmsz(self);
        for (j=na->ndim; j--;) {
            SDX_SET_STRIDE(na2->stridx[j], stride);
            stride *= na->shape[j];
        }
        na2->offset = 0;
        na2->data = self;
        break;
    case NARRAY_VIEW_T:
        GetNArrayView(self, na1);
        for (j=na1->base.ndim; j--; ) {
            if (SDX_IS_INDEX(na1->stridx[j])) {
                n = na1->base.shape[j];
                idx1 = SDX_GET_INDEX(na1->stridx[j]);
                idx2 = ALLOC_N(size_t, na1->base.shape[j]);
                for (i=0; i<n; i++) {
                    idx2[i] = idx1[i];
                }
                SDX_SET_INDEX(na2->stridx[j],idx2);
            } else {
                na2->stridx[j] = na1->stridx[j];
            }
        }
        na2->offset = na1->offset;
        na2->data = na1->data;
        break;
    }

    if (RTEST(offset)) {
        na2->offset += NUM2SIZET(offset);
    }

    return view;
}
Exemplo n.º 22
0
VALUE ruv_buffer_write(int argc, VALUE* argv, VALUE rb_buffer) {
    VALUE           rb_str, rb_offset, rb_length, rb_extern_enc, rb_cBuffer;
    size_t          offset, length, max_length, char_count;
    ruv_buffer_t    *buffer;
    rb_encoding     *rb_extern_encoding;

    Data_Get_Struct(rb_buffer, ruv_buffer_t, buffer);

    rb_scan_args(argc, argv, "13", &rb_str, &rb_offset, &rb_length, &rb_extern_enc);
    StringValue(rb_str);

    // encoding: use specified external encoding if provided
    // otherwise use Encoding.default_external as default
    if(!NIL_P(rb_extern_enc)) {
        rb_extern_encoding = rb_enc_get(rb_extern_enc);
    } else {
        rb_extern_encoding = rb_default_external_encoding();
    }

    // convert to external encoding
    rb_str = rb_str_export_to_enc(rb_str, rb_extern_encoding);

    // offset: either specified in params or 0
    if(!NIL_P(rb_offset)) {
        Check_Type(rb_offset, T_FIXNUM);
        offset = NUM2SIZET(rb_offset);
        if(offset >= buffer->length) {
            rb_raise(rb_eArgError, "Overflow! offset is larger than buffer size.");
        }
    } else {
        offset = 0;
    }

    // max length: the smaller of the max available space or the whole ruby string
    max_length = MIN(buffer->length - offset, (size_t)RSTRING_LEN(rb_str));

    // length: number of bytes to write. (include half chars)
    if(!NIL_P(rb_length)) {
        Check_Type(rb_length, T_FIXNUM);
        length = NUM2SIZET(rb_length);
    } else {
        length = max_length;
    }

    // If we are not writing the whole string into the buffer,
    // re-adjust length so we don't write half a character (uft8, etc)
    // 1). get char count from calculated byte length
    // 2). get byte length back from char count
    // This way only whole char is written to buffer
    if(length != (size_t)RSTRING_LEN(rb_str)) {
        char_count  = rb_str_sublen(rb_str, length);
        length      = rb_str_offset(rb_str, char_count);
    }

    memcpy(buffer->data + offset, RSTRING_PTR(rb_str), length);

    // set instance variable so we know how much characters are written
    rb_cBuffer = rb_obj_class(rb_buffer);
    rb_iv_set(rb_cBuffer, RUV_BUFFER_CHAR_WRITTEN_SYM, SIZET2NUM(char_count));

    return SIZET2NUM(length);
}
Exemplo n.º 23
0
static VALUE
nstruct_add_type(VALUE type, int argc, VALUE *argv, VALUE nst)
{
    VALUE ofs, size;
    ID id;
    int i;
    VALUE name=Qnil;
    size_t *shape=NULL;
    int ndim=0;
    ssize_t stride;
    narray_view_t *nt;
    int j;

    for (i=0; i<argc; i++) {
        switch(TYPE(argv[i])) {
        case T_STRING:
        case T_SYMBOL:
            if (NIL_P(name)) {
                name = argv[i];
                break;
            }
            rb_raise(rb_eArgError,"multiple name in struct definition");
        case T_ARRAY:
            if (shape) {
                rb_raise(rb_eArgError,"multiple shape in struct definition");
            }
            ndim = RARRAY_LEN(argv[i]);
            if (ndim > NA_MAX_DIMENSION) {
                rb_raise(rb_eArgError,"too large number of dimensions");
            }
            if (ndim == 0) {
                rb_raise(rb_eArgError,"array is empty");
            }
            shape = ALLOCA_N(size_t, ndim);
            na_array_to_internal_shape(Qnil, argv[i], shape);
            break;
        }
    }

    id = rb_to_id(name);
    name = ID2SYM(id);
    if (rb_obj_is_kind_of(type,cNArray)) {
        narray_t *na;
        GetNArray(type,na);
        type = CLASS_OF(type);
        ndim = na->ndim;
        shape = na->shape;
    }
    type = rb_narray_view_new(type,ndim,shape);
    GetNArrayView(type,nt);

    nt->stridx = ALLOC_N(stridx_t,ndim);
    stride = na_dtype_elmsz(CLASS_OF(type));
    for (j=ndim; j--; ) {
        SDX_SET_STRIDE(nt->stridx[j], stride);
        stride *= shape[j];
    }

    ofs  = rb_iv_get(nst, "__offset__");
    nt->offset = NUM2SIZET(ofs);

    size = rb_funcall(type, rb_intern("byte_size"), 0);
    rb_iv_set(nst, "__offset__", rb_funcall(ofs,'+',1,size));
    rb_ary_push(rb_iv_get(nst,"__members__"),
                rb_ary_new3(4,name,type,ofs,size));  // <- field definition
    return Qnil;
}