/* * call-seq: * RepeatedField.[]=(index, value) * * Sets the element at the given index. On out-of-bounds assignments, extends * the array and fills the hole (if any) with default values. */ VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { RepeatedField* self = ruby_to_RepeatedField(_self); upb_fieldtype_t field_type = self->field_type; VALUE field_type_class = self->field_type_class; int element_size = native_slot_size(field_type); int index = index_position(_index, self); if (index < 0 || index >= (INT_MAX - 1)) { return Qnil; } if (index >= self->size) { RepeatedField_reserve(self, index + 1); upb_fieldtype_t field_type = self->field_type; int element_size = native_slot_size(field_type); for (int i = self->size; i <= index; i++) { void* elem = (void *)(((uint8_t *)self->elements) + i * element_size); native_slot_init(field_type, elem); } self->size = index + 1; } void* memory = (void *) (((uint8_t *)self->elements) + index * element_size); native_slot_set(field_type, field_type_class, memory, val); return Qnil; }
/* * call-seq: * RepeatedField.[](index) => value * * Accesses the element at the given index. Returns nil on out-of-bounds */ VALUE RepeatedField_index(VALUE _self, VALUE _index) { 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; int index = index_position(_index, 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); }
/* * 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); }