static void na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, na_index_arg_t *q) { int n; VALUE excl_end; ssize_t beg, end, beg_orig, end_orig; const char *dot = "..", *edot = "..."; beg = beg_orig = NUM2SSIZET(rb_funcall(range,id_beg,0)); if (beg < 0) { beg += size; } end = end_orig = NUM2SSIZET(rb_funcall(range,id_end,0)); if (end < 0) { end += size; } excl_end = rb_funcall(range,id_exclude_end,0); if (RTEST(excl_end)) { end--; dot = edot; } if (beg < 0 || beg >= size || end < 0 || end >= size) { rb_raise(rb_eRangeError, "%"SZF"d%s%"SZF"d is out of range for size=%"SZF"d", beg_orig, dot, end_orig, size); } n = (end-beg)/step+1; if (n<0) n=0; na_index_set_step(q,orig_dim,n,beg,step); }
static void na_parse_enumerator(VALUE enum_obj, int orig_dim, ssize_t size, na_index_arg_t *q) { int len; ssize_t step; struct enumerator *e; if (!RB_TYPE_P(enum_obj, T_DATA)) { rb_raise(rb_eTypeError,"wrong argument type (not T_DATA)"); } e = (struct enumerator *)DATA_PTR(enum_obj); if (rb_obj_is_kind_of(e->obj, rb_cRange)) { if (e->meth == id_each) { na_parse_range(e->obj, 1, orig_dim, size, q); } else if (e->meth == id_step) { if (TYPE(e->args) != T_ARRAY) { rb_raise(rb_eArgError,"no argument for step"); } len = RARRAY_LEN(e->args); if (len != 1) { rb_raise(rb_eArgError,"invalid number of step argument (1 for %d)",len); } step = NUM2SSIZET(RARRAY_AREF(e->args,0)); na_parse_range(e->obj, step, orig_dim, size, q); } else { rb_raise(rb_eTypeError,"unknown Range method: %s",rb_id2name(e->meth)); } } else { rb_raise(rb_eTypeError,"not Range object"); } }
static VALUE rb_smbfile_read(int argc, VALUE *argv, VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); ssize_t req_read_size; VALUE str = rb_str_new2(""); rb_smbfile_readable_p_by_data(data); if (argc == 0) { req_read_size = -1; } else { req_read_size = NUM2SSIZET(argv[0]); if (req_read_size == 0) { return str; /* Return empty string */ } if (req_read_size < 0) { rb_raise(rb_eArgError, "Negative length given: %zd", req_read_size); } } while (req_read_size) { ssize_t buffer_read_size = data->buffer_used_size - data->buffer_pos; if (buffer_read_size == 0) { /* No remained data in buffer */ rb_smbfile_read_by_data(data); if (data->eof) { /* No remained data in file */ return (req_read_size > 0 && RSTRING_LEN(str) == 0) ? Qnil : str; } buffer_read_size = data->buffer_used_size - data->buffer_pos; } if (req_read_size > 0 && buffer_read_size > req_read_size) { buffer_read_size = req_read_size; } rb_str_cat(str, data->buffer + data->buffer_pos, buffer_read_size); data->pos += buffer_read_size; data->buffer_pos += buffer_read_size; if (req_read_size > 0) { req_read_size -= buffer_read_size; } } return str; }
static void na_parse_array(VALUE ary, int orig_dim, ssize_t size, na_index_arg_t *q) { int k; int n = RARRAY_LEN(ary); q->idx = ALLOC_N(size_t, n); for (k=0; k<n; k++) { q->idx[k] = na_range_check(NUM2SSIZET(RARRAY_AREF(ary,k)), size, orig_dim); } q->n = n; q->beg = 0; q->step = 1; q->reduce = 0; q->orig_dim = orig_dim; }
int na_get_result_dimension(VALUE self, int argc, VALUE *argv, ssize_t stride, size_t *pos_idx) { int i, j; int count_new=0; int count_rest=0; ssize_t x, s, m, pos, *idx; narray_t *na; narray_view_t *nv; stridx_t sdx; VALUE a; GetNArray(self,na); if (na->size == 0) { rb_raise(nary_eShapeError, "cannot get element of empty array"); } idx = ALLOCA_N(ssize_t, argc); for (i=j=0; i<argc; i++) { a = argv[i]; switch(TYPE(a)) { case T_FIXNUM: idx[j++] = FIX2LONG(a); break; case T_BIGNUM: case T_FLOAT: idx[j++] = NUM2SSIZET(a); break; case T_FALSE: case T_SYMBOL: if (a==sym_rest || a==sym_tilde || a==Qfalse) { argv[i] = Qfalse; count_rest++; break; } else if (a==sym_new || a==sym_minus) { argv[i] = sym_new; count_new++; } } } if (j != argc) { return check_index_count(argc, na->ndim, count_new, count_rest); } switch(na->type) { case NARRAY_VIEW_T: GetNArrayView(self,nv); pos = nv->offset; if (j == na->ndim) { for (i=j-1; i>=0; i--) { x = na_range_check(idx[i], na->shape[i], i); sdx = nv->stridx[i]; if (SDX_IS_INDEX(sdx)) { pos += SDX_GET_INDEX(sdx)[x]; } else { pos += SDX_GET_STRIDE(sdx)*x; } } *pos_idx = pos; return 0; } if (j == 1) { x = na_range_check(idx[0], na->size, 0); for (i=na->ndim-1; i>=0; i--) { s = na->shape[i]; m = x % s; x = x / s; sdx = nv->stridx[i]; if (SDX_IS_INDEX(sdx)) { pos += SDX_GET_INDEX(sdx)[m]; } else { pos += SDX_GET_STRIDE(sdx)*m; } } *pos_idx = pos; return 0; } break; default: if (!stride) { stride = nary_element_stride(self); } if (j == 1) { x = na_range_check(idx[0], na->size, 0); *pos_idx = stride * x; return 0; } if (j == na->ndim) { pos = 0; for (i=j-1; i>=0; i--) { x = na_range_check(idx[i], na->shape[i], i); pos += stride * x; stride *= na->shape[i]; } *pos_idx = pos; return 0; } } rb_raise(rb_eIndexError,"# of index(=%i) should be " "equal to ndim(=%i) or 1", argc,na->ndim); return -1; }
// Analyze *a* which is *i*-th index object and store the information to q // // a: a ruby object of i-th index // size: size of i-th dimension of original NArray // i: parse i-th index // q: parsed information is stored to *q static void na_index_parse_each(volatile VALUE a, ssize_t size, int i, na_index_arg_t *q) { switch(TYPE(a)) { case T_FIXNUM: na_index_set_scalar(q,i,size,FIX2LONG(a)); break; case T_BIGNUM: na_index_set_scalar(q,i,size,NUM2SSIZET(a)); break; case T_FLOAT: na_index_set_scalar(q,i,size,NUM2SSIZET(a)); break; case T_NIL: case T_TRUE: na_index_set_step(q,i,size,0,1); break; case T_SYMBOL: if (a==sym_all || a==sym_ast) { na_index_set_step(q,i,size,0,1); } else if (a==sym_reverse) { na_index_set_step(q,i,size,size-1,-1); } else if (a==sym_new) { na_index_set_step(q,i,1,0,1); } else if (a==sym_reduce || a==sym_sum || a==sym_plus) { na_index_set_step(q,i,size,0,1); q->reduce = 1; } else { rb_raise(rb_eIndexError, "invalid symbol for index"); } break; case T_ARRAY: na_parse_array(a, i, size, q); break; default: if (rb_obj_is_kind_of(a, rb_cRange)) { na_parse_range(a, 1, i, size, q); } else if (rb_obj_is_kind_of(a, rb_cEnumerator)) { na_parse_enumerator(a, i, size, q); } else if (rb_obj_is_kind_of(a, na_cStep)) { ssize_t beg, step, n; nary_step_array_index(a, size, (size_t*)(&n), &beg, &step); na_index_set_step(q,i,n,beg,step); } // NArray index else if (NA_IsNArray(a)) { na_parse_narray_index(a, i, size, q); } else { rb_raise(rb_eIndexError, "not allowed type"); } } }