/* * call-seq: * RepeatedField.+(other) => repeated field * * Returns a new repeated field that contains the concatenated list of this * repeated field's elements and other's elements. The other (second) list may * be either another repeated field or a Ruby array. */ VALUE RepeatedField_plus(VALUE _self, VALUE list) { VALUE dupped = RepeatedField_dup(_self); if (TYPE(list) == T_ARRAY) { for (int i = 0; i < RARRAY_LEN(list); i++) { VALUE elem = rb_ary_entry(list, i); RepeatedField_push(dupped, elem); } } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) && RTYPEDDATA_TYPE(list) == &RepeatedField_type) { RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* list_rptfield = ruby_to_RepeatedField(list); if (self->field_type != list_rptfield->field_type || self->field_type_class != list_rptfield->field_type_class) { rb_raise(rb_eArgError, "Attempt to append RepeatedField with different element type."); } for (int i = 0; i < list_rptfield->size; i++) { void* mem = RepeatedField_index_native(list, i); RepeatedField_push_native(dupped, mem); } } else { rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); } return dupped; }
static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink, int depth) { upb_sink subsink; upb_fieldtype_t type = upb_fielddef_type(f); upb_selector_t sel = 0; int size; if (ary == Qnil) return; upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); if (upb_fielddef_isprimitive(f)) { sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); } size = NUM2INT(RepeatedField_length(ary)); for (int i = 0; i < size; i++) { void* memory = RepeatedField_index_native(ary, i); switch (type) { #define T(upbtypeconst, upbtype, ctype) \ case upbtypeconst: \ upb_sink_put##upbtype(&subsink, sel, *((ctype *)memory)); \ break; T(UPB_TYPE_FLOAT, float, float) T(UPB_TYPE_DOUBLE, double, double) T(UPB_TYPE_BOOL, bool, int8_t) case UPB_TYPE_ENUM: T(UPB_TYPE_INT32, int32, int32_t) T(UPB_TYPE_UINT32, uint32, uint32_t) T(UPB_TYPE_INT64, int64, int64_t) T(UPB_TYPE_UINT64, uint64, uint64_t) case UPB_TYPE_STRING: case UPB_TYPE_BYTES: putstr(*((VALUE *)memory), f, &subsink); break; case UPB_TYPE_MESSAGE: putsubmsg(*((VALUE *)memory), f, &subsink, depth); break; #undef T } } upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); }