Example #1
0
/*
 * call-seq:
 *     db[nth]
 *     db[start..end]
 *     db[start, length]
 *
 * Element reference - with the following syntax:
 *
 * * db[nth]
 *
 *     Retrieves the +nth+ item from an array.  Index starts from
 *     zero.  If index is the negative, counts backward from the end
 *     of the array.  The index of the last element is -1. Returns
 *     +nil+, if the +nth+ element does not exist in the array.
 *
 * * db[start..end]
 *
 *     Returns an array containing the objects from +start+ to +end+,
 *     including both ends. if end is larger than the length of the
 *     array, it will be rounded to the length.  If +start+ is out of
 *     an array range , returns +nil+.  And if +start+ is larger than
 *     end with in array range, returns empty array ([]).
 *
 * * db[start, length]
 *
 *     Returns an array containing +length+ items from +start+.
 *     Returns +nil+ if +length+ is negative.
 */
static VALUE
bdb_sary_aref(int argc, VALUE *argv, VALUE obj)
{
    VALUE arg1, arg2;
    long beg, len;
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
	beg = NUM2LONG(arg1);
	len = NUM2LONG(arg2);
	if (beg < 0) {
	    beg = dbst->len + beg;
	}
	return bdb_sary_subseq(obj, beg, len);
    }

    if (FIXNUM_P(arg1)) {
	return bdb_sary_entry(obj, arg1);
    }
    else if (TYPE(arg1) == T_BIGNUM) {
	rb_raise(rb_eIndexError, "index too big");
    }
    else {
	switch (rb_range_beg_len(arg1, &beg, &len, dbst->len, 0)) {
	  case Qfalse:
	    break;
	  case Qnil:
	    return Qnil;
	  default:
	    return bdb_sary_subseq(obj, beg, len);
	}
    }
    return bdb_sary_entry(obj, arg1);
}
Example #2
0
static VALUE
range_relative_to(VALUE range, SEL sel, VALUE max)
{
    long beg, len, m = NUM2LONG(max);
    rb_range_beg_len(range, &beg, &len, m, 0);
    return rb_range_new(LONG2NUM(beg), LONG2NUM(beg + len - 1), 0);
}
Example #3
0
static VALUE
bdb_sary_slice_bang(int argc, VALUE *argv, VALUE obj)
{
    VALUE arg1, arg2;
    long pos, len;
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
	pos = NUM2LONG(arg1);
	len = NUM2LONG(arg2);
      delete_pos_len:
	if (pos < 0) {
	    pos = dbst->len + pos;
	}
	arg2 = bdb_sary_subseq(obj, pos, len);
	bdb_sary_replace(obj, pos, len, Qnil);
	return arg2;
    }

    if (!FIXNUM_P(arg1) && rb_range_beg_len(arg1, &pos, &len, dbst->len, 1)) {
	goto delete_pos_len;
    }

    pos = NUM2LONG(arg1);
    if (pos >= dbst->len) return Qnil;
    if (pos < 0) pos += dbst->len;
    if (pos < 0) return Qnil;

    arg1 = INT2NUM(pos);
    arg2 = bdb_sary_at(obj, arg1);
    if (bdb_del(obj, arg1) != Qnil) dbst->len--;
    return arg2;
}
Example #4
0
File: leds.c Project: TwP/pixel_pi
/* call-seq:
 *    fill( color )
 *    fill( color, start [, length] )
 *    fill( color, range )
 *    fill { |index| block }
 *    fill( start [, length] ) { |index| block }
 *    fill( range ) { |index| block }
 *
 * Set the selected LEDs to the given `color`. The `color` msut be given as a
 * 24-bit RGB value. You can also supply a block that receives an LED index and
 * returns a 24-bit RGB color.
 *
 * Examples:
 *    leds.fill( 0x00FF00 )
 *    leds.fill( 0xFF0000, 2, 2 )
 *    leds.fill( 0x0000FF, (4...8) )
 *    leds.fill { |i| 256 << i }
 *
 * Returns this PixelPi::Leds instance.
 */
static VALUE
pp_leds_fill( int argc, VALUE* argv, VALUE self )
{
  ws2811_t *ledstring = pp_leds_struct( self );
  ws2811_channel_t channel = ledstring->channel[0];
  ws2811_led_t color = 0;

  VALUE item, arg1, arg2, v;
  long ii, beg = 0, end = 0, len = 0;
  int block_p = 0;

  if (rb_block_given_p()) {
    block_p = 1;
    rb_scan_args( argc, argv, "02", &arg1, &arg2 );
    argc += 1;
  } else {
    rb_scan_args( argc, argv, "12", &item, &arg1, &arg2 );
    color = FIX2UINT(item);
  }

  switch (argc) {
    case 1:
      beg = 0;
      len = channel.count;
      break;
    case 2:
      if (rb_range_beg_len(arg1, &beg, &len, channel.count, 1)) {
        break;
      }
      /* fall through */
    case 3:
      beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
      if (beg < 0) {
        beg = channel.count + beg;
        if (beg < 0) beg = 0;
      }
      len = NIL_P(arg2) ? channel.count - beg : NUM2LONG(arg2);
      break;
  }

  if (len < 0) return self;

  end = beg + len;
  end = MIN((long) channel.count, end);

  for (ii=beg; ii<end; ii++) {
    if (block_p) {
      v = rb_yield(INT2NUM(ii));
      color = FIX2UINT(v);
    }
    channel.leds[ii] = color;
  }

  return self;
}
Example #5
0
/*
 * call-seq:
 *     db[nth] = val
 *     db[start..end] = val
 *     db[start, length] = val
 *
 * Element assignment - with the following syntax:
 *
 * * db[nth] = val
 *
 *     Changes the +nth+ element of the array into +val+.  If +nth+ is
 *     larger than array length, the array shall be extended
 *     automatically.  Extended region shall be initialized by +nil+.
 *
 * * db[start..end] = val
 *
 *     Replaces the items from +start+ to +end+ with +val+.  If +val+
 *     is not an array, the type of +val+ will be converted into the
 *     Array using +to_a+ method.
 *
 * * db[start, length] = val
 *
 *     Replaces the +length+ items from +start+ with +val+.  If +val+
 *     is not an array, the type of +val+ will be converted into the
 *     Array using +to_a+.
 */
static VALUE
bdb_sary_aset(int argc, VALUE *argv, VALUE obj)
{
    long  beg, len;
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (argc == 3) {
	bdb_sary_replace(obj, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
	return argv[2];
    }
    if (argc != 2) {
	rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
    }
    if (FIXNUM_P(argv[0])) {
	beg = FIX2LONG(argv[0]);
	goto fixnum;
    }
    else if (rb_range_beg_len(argv[0], &beg, &len, dbst->len, 1)) {
	bdb_sary_replace(obj, beg, len, argv[1]);
	return argv[1];
    }
    if (TYPE(argv[0]) == T_BIGNUM) {
	rb_raise(rb_eIndexError, "index too big");
    }

    beg = NUM2LONG(argv[0]);
  fixnum:
    if (beg < 0) {
	beg += dbst->len;
	if (beg < 0) {
	    rb_raise(rb_eIndexError, "index %ld out of array",
		     beg - dbst->len);
	}
    }
    if (beg > dbst->len) {
	VALUE nargv[2];
	int i;

	nargv[1] = Qnil;
	for (i = dbst->len; i < beg; i++) {
	    nargv[0] = INT2NUM(i);
	    bdb_put(2, nargv, obj);
	    dbst->len++;
	}
    }
    argv[0] = INT2NUM(beg);
    bdb_put(2, argv, obj);
    dbst->len++;
    return argv[1];
}
Example #6
0
/*
 * Document-method: []=
 *
 * call-seq:
 *   [index]= value
 *   [range]= value-array
 *
 * Element Assignment - Sets the element at _index_ or replaces the subset
 * specified by _range_. Values can be only be positive numerics. Even
 * values will be set to 0 (n % 2 = 0) and uneven values will be set to 1
 * (n % 2 = 1).
 */
static VALUE bf_bit_set(VALUE self, VALUE position, VALUE value)
{
    BitField *ptr;
    Data_Get_Struct(self, BitField, ptr);

    if(rb_obj_is_kind_of(position, rb_cRange)
            && rb_obj_is_kind_of(value, rb_cArray))
    {
        long beg, len;
        VALUE tmp;
        switch(rb_range_beg_len(position, &beg, &len, (long int)ptr->data.size()-1, 2))
        {
            case Qfalse:
            case Qnil:
                return Qfalse;
            default:
                for(long i = beg+len-1; i >= beg; i--)
                {
                    tmp = rb_ary_pop(value);
                    if(tmp != Qnil)
                    {
                        /* Is the array value a number? */
                        Check_Type(tmp, T_FIXNUM);
                        ptr->data[i] = FIX2INT(tmp) % 2;
                    }
                    else
                    {
                        rb_raise(rb_eRangeError, "Array is smaller than given range.");
                    }
                }
        }
    }
    else
    {
        /* Sanity checks for position and value */
        Check_Type(position, T_FIXNUM);
        Check_Type(value, T_FIXNUM);

        int pos = FIX2INT(position);
        if(pos < 0 || pos >= ptr->data.size())
        {
            rb_raise(rb_eRangeError, "BitField out of range with value %d.", pos);
        }
        ptr->data[pos] = FIX2INT(value) % 2;
    }
    return Qnil;
}
static VALUE
apply_actions(VALUE field, VALUE actions)
{
    long j, actions_len = RARRAY_LEN(actions);
    long beg, len;
    VALUE num = 0, modi = 0;
    for (j = 0; j < actions_len; j++) {
	VALUE action = rb_ary_entry(actions, j);
	VALUE klass = rb_class_of(action);
	if (klass == rb_cRange) {
	    /* copied from rb_str_aref */
	    len = rb_str_strlen(field);
	    if (RTEST(rb_range_beg_len(action, &beg, &len, len, 0)))
		field = rb_str_substr(field, beg, len);
	} else if (klass == rb_cArray) {
	    num = rb_str_to_inum(field, 10, 0);
	    modi = rb_ary_entry(action, 1);
	    if ( (FIXNUM_P(num) ||
		      TYPE(num) == T_BIGNUM &&
		      RBIGNUM_LEN(num) <= (SIZEOF_LONG/SIZEOF_BDIGITS)
		  ) &&
		  FIXNUM_P(modi) &&
		  FIX2LONG(modi)) {
		long modl = NUM2LONG(modi);
		long numl = (NUM2LONG(num) / modl) * modl;
		char buf[30];

		int wrtn = snprintf(buf, 30,
			RSTRING_PTR(rb_ary_entry(action, 0)),
			numl);
		if (wrtn < 30) {
		    field = rb_str_new(buf, wrtn);
		    continue;
		}
	    }
	    else {
		num = rb_funcall2(num, idDiv, 1, &modi);
		num = rb_funcall2(num, idMul, 1, &modi);
	    }
	    field = rb_str_format(1, &num, rb_ary_entry(action, 0));
	}
    }
    return field;
}
Example #8
0
/*
 * call-seq:
 *     RepeatedField.[](index) => value
 *
 * Accesses the element at the given index. Returns nil on out-of-bounds
 */
VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
  RepeatedField* self = ruby_to_RepeatedField(_self);
  int element_size = native_slot_size(self->field_type);
  upb_fieldtype_t field_type = self->field_type;
  VALUE field_type_class = self->field_type_class;

  VALUE arg = argv[0];
  long beg, len;

  if (argc == 1){
    if (FIXNUM_P(arg)) {
      /* standard case */
      int index = index_position(argv[0], self);
      if (index < 0 || index >= self->size) {
        return Qnil;
      }
      void* memory = (void *) (((uint8_t *)self->elements) +
                               index * element_size);
      return native_slot_get(field_type, field_type_class, memory);
    }else{
      /* check if idx is Range */
      size_t off;
      switch (rb_range_beg_len(arg, &beg, &len, self->size, 0)) {
        case Qfalse:
          break;
        case Qnil:
          return Qnil;
        default:
          return RepeatedField_subarray(_self, beg, len);
      }
    }
  }
  /* assume 2 arguments */
  beg = NUM2LONG(argv[0]);
  len = NUM2LONG(argv[1]);
  if (beg < 0) {
    beg += self->size;
  }
  if (beg >= self->size) {
    return Qnil;
  }
  return RepeatedField_subarray(_self, beg, len);
}
Example #9
0
/*
 * Document-method: []
 *
 * call-seq:
 *   [index] -> value
 *   [range] -> new_ary
 *
 * Element Reference - Returns the element at _index_ or the subset
 * specified by _range_. Negative or indices greater than the size of
 * the BitField will be nil.
 */
static VALUE bf_bit_get(VALUE self, VALUE position)
{
    BitField *ptr;
    Data_Get_Struct(self, BitField, ptr);

    /* Is position a range? */
    if(rb_obj_is_kind_of(position, rb_cRange))
    {
        long beg, len;
        VALUE range_ary = rb_ary_new();
        switch(rb_range_beg_len(position, &beg, &len, (long int)ptr->data.size()-1, 2))
        {
            case Qfalse:
            case Qnil:
                return Qnil;
            default:
                for(long i = beg; i < beg+len; i++)
                {
                    if(i < 0 || i >= ptr->data.size()) {
                        rb_ary_push(range_ary, Qnil);
                    } else {
                        rb_ary_push(range_ary, LONG2NUM(ptr->data[i]));
                    }
                }
        }
        return range_ary;
    }
    else
    {
        /* Sanity checks for position and value */
        Check_Type(position, T_FIXNUM);
        long pos = FIX2INT(position);
        if(pos < 0 || pos >= ptr->data.size()) {
            return Qnil;
        } else {
            return LONG2NUM(ptr->data[pos]);
        }
    }
}
Example #10
0
/*
 * Array reference - creates new memory for range rather than shared object
 * Note: Almost exactly the same as the implementation from
 * Ruby 1.9.2 p0
 */
static VALUE ary_aref(int argc, VALUE *argv, VALUE ary)
{
  VALUE arg;
  long beg, len;

  if (argc == 2)
  {
    beg = NUM2LONG(argv[0]);
    len = NUM2LONG(argv[1]);
    if (beg < 0)
    {
      beg += RARRAY_LEN(ary);
    }
    return my_ary_subseq(ary, beg, len);
  }
  if (argc != 1)
  {
    rb_scan_args(argc, argv, "11", 0, 0);
  }
  arg = argv[0];
  /* special case - speeding up */
  if (FIXNUM_P(arg))
  {
    return rb_ary_entry(ary, FIX2LONG(arg));
  }
  /* check if idx is Range */
  switch (rb_range_beg_len(arg, &beg, &len, RARRAY_LEN(ary), 0))
  {
    case Qfalse:
      break;
    case Qnil:
      return Qnil;
    default:
      return my_ary_subseq(ary, beg, len);
  }
  return rb_ary_entry(ary, NUM2LONG(arg));
}
Example #11
0
static VALUE
bdb_sary_fill(int argc, VALUE *argv, VALUE obj)
{
    VALUE item, arg1, arg2, tmp[2];
    long beg, len, i;
    bdb_DB *dbst;

    GetDB(obj, dbst);
    rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
    switch (argc) {
      case 1:
	  len = dbst->len;
	  beg = 0;
	  break;
      case 2:
	if (rb_range_beg_len(arg1, &beg, &len, dbst->len, 1)) {
	    break;
	}
	/* fall through */
      case 3:
	beg = NIL_P(arg1)?0:NUM2LONG(arg1);
	if (beg < 0) {
	    beg += dbst->len;
	    if (beg < 0) beg = 0;
	}
	len = NIL_P(arg2)?dbst->len - beg:NUM2LONG(arg2);
	break;
    }
    tmp[1] = item;
    for (i = 0; i < len; i++) {
	tmp[0] = INT2NUM(i + beg);
	bdb_put(2, tmp, obj);
	if ((i + beg) >= dbst->len) dbst->len++;
    }
    return obj;
}
Example #12
0
static VALUE
vm_backtrace_to_ary(rb_thread_t *th, int argc, const VALUE *argv, int lev_default, int lev_plus, int to_str)
{
    VALUE level, vn;
    long lev, n;
    VALUE btval = backtrace_object(th);
    VALUE r;
    rb_backtrace_t *bt;

    GetCoreDataFromValue(btval, rb_backtrace_t, bt);

    rb_scan_args(argc, argv, "02", &level, &vn);

    if (argc == 2 && NIL_P(vn)) argc--;

    switch (argc) {
      case 0:
	lev = lev_default + lev_plus;
	n = bt->backtrace_size - lev;
	break;
      case 1:
	{
	    long beg, len;
	    switch (rb_range_beg_len(level, &beg, &len, bt->backtrace_size - lev_plus, 0)) {
	      case Qfalse:
		lev = NUM2LONG(level);
		if (lev < 0) {
		    rb_raise(rb_eArgError, "negative level (%ld)", lev);
		}
		lev += lev_plus;
		n = bt->backtrace_size - lev;
		break;
	      case Qnil:
		return Qnil;
	      default:
		lev = beg + lev_plus;
		n = len;
		break;
	    }
	    break;
	}
      case 2:
	lev = NUM2LONG(level);
	n = NUM2LONG(vn);
	if (lev < 0) {
	    rb_raise(rb_eArgError, "negative level (%ld)", lev);
	}
	if (n < 0) {
	    rb_raise(rb_eArgError, "negative size (%ld)", n);
	}
	lev += lev_plus;
	break;
      default:
	lev = n = 0; /* to avoid warning */
	break;
    }

    if (n == 0) {
	return rb_ary_new();
    }

    if (to_str) {
	r = backtrace_to_str_ary(btval, lev, n);
    }
    else {
	r = backtrace_to_location_ary(btval, lev, n);
    }
    RB_GC_GUARD(btval);
    return r;
}