/* * 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; }
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { MessageHeader* self; char *name; const upb_fielddef* f; TypedData_Get_Struct(_self, MessageHeader, &Message_type, self); if (TYPE(key) == T_STRING) { name = RSTRING_PTR(key); } else if (TYPE(key) == T_SYMBOL) { name = RSTRING_PTR(rb_id2str(SYM2ID(key))); } else { rb_raise(rb_eArgError, "Expected string or symbols as hash keys when initializing proto from hash."); } f = upb_msgdef_ntofz(self->descriptor->msgdef, name); if (f == NULL) { rb_raise(rb_eArgError, "Unknown field name '%s' in initialization map entry.", name); } if (TYPE(val) == T_NIL) { return 0; } if (is_map_field(f)) { VALUE map; if (TYPE(val) != T_HASH) { rb_raise(rb_eArgError, "Expected Hash object as initializer value for map field '%s'.", name); } map = layout_get(self->descriptor->layout, Message_data(self), f); Map_merge_into_self(map, val); } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) { VALUE ary; if (TYPE(val) != T_ARRAY) { rb_raise(rb_eArgError, "Expected array as initializer value for repeated field '%s'.", name); } ary = layout_get(self->descriptor->layout, Message_data(self), f); for (int i = 0; i < RARRAY_LEN(val); i++) { VALUE entry = rb_ary_entry(val, i); if (TYPE(entry) == T_HASH && upb_fielddef_issubmsg(f)) { entry = create_submsg_from_hash(f, entry); } RepeatedField_push(ary, entry); } } else { if (TYPE(val) == T_HASH && upb_fielddef_issubmsg(f)) { val = create_submsg_from_hash(f, val); } layout_set(self->descriptor->layout, Message_data(self), f, val); } return 0; }
/* * call-seq: * RepeatedField.concat(other) => self * * concats the passed in array to self. Returns a Ruby array. */ VALUE RepeatedField_concat(VALUE _self, VALUE list) { RepeatedField* self = ruby_to_RepeatedField(_self); Check_Type(list, T_ARRAY); for (int i = 0; i < RARRAY_LEN(list); i++) { RepeatedField_push(_self, rb_ary_entry(list, i)); } return _self; }
// Appends a 'bytes' string to a repeated field. static void* appendbytes_handler(void *closure, const void *hd, size_t size_hint) { VALUE ary = (VALUE)closure; VALUE str = rb_str_new2(""); rb_enc_associate(str, kRubyString8bitEncoding); RepeatedField_push(ary, str); return (void*)str; }
/* * call-seq: * RepeatedField.replace(list) * * Replaces the contents of the repeated field with the given list of elements. */ VALUE RepeatedField_replace(VALUE _self, VALUE list) { RepeatedField* self = ruby_to_RepeatedField(_self); Check_Type(list, T_ARRAY); self->size = 0; for (int i = 0; i < RARRAY_LEN(list); i++) { RepeatedField_push(_self, rb_ary_entry(list, i)); } return list; }
// Appends a submessage to a repeated field (a regular Ruby array for now). static void *appendsubmsg_handler(void *closure, const void *hd) { VALUE ary = (VALUE)closure; const submsg_handlerdata_t *submsgdata = hd; VALUE subdesc = get_def_obj((void*)submsgdata->md); VALUE subklass = Descriptor_msgclass(subdesc); MessageHeader* submsg; VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); RepeatedField_push(ary, submsg_rb); TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); return submsg; }
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { MessageHeader* self; VALUE method_str; char* name; const upb_fielddef* f; TypedData_Get_Struct(_self, MessageHeader, &Message_type, self); if (!SYMBOL_P(key)) { rb_raise(rb_eArgError, "Expected symbols as hash keys in initialization map."); } method_str = rb_id2str(SYM2ID(key)); name = RSTRING_PTR(method_str); f = upb_msgdef_ntofz(self->descriptor->msgdef, name); if (f == NULL) { rb_raise(rb_eArgError, "Unknown field name '%s' in initialization map entry.", name); } if (is_map_field(f)) { VALUE map; if (TYPE(val) != T_HASH) { rb_raise(rb_eArgError, "Expected Hash object as initializer value for map field '%s'.", name); } map = layout_get(self->descriptor->layout, Message_data(self), f); Map_merge_into_self(map, val); } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) { VALUE ary; if (TYPE(val) != T_ARRAY) { rb_raise(rb_eArgError, "Expected array as initializer value for repeated field '%s'.", name); } ary = layout_get(self->descriptor->layout, Message_data(self), f); for (int i = 0; i < RARRAY_LEN(val); i++) { RepeatedField_push(ary, rb_ary_entry(val, i)); } } else { layout_set(self->descriptor->layout, Message_data(self), f, val); } return 0; }
void RepeatedField_init_args(int argc, VALUE* argv, VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); VALUE ary = Qnil; if (argc < 1) { rb_raise(rb_eArgError, "Expected at least 1 argument."); } self->field_type = ruby_to_fieldtype(argv[0]); if (self->field_type == UPB_TYPE_MESSAGE || self->field_type == UPB_TYPE_ENUM) { if (argc < 2) { rb_raise(rb_eArgError, "Expected at least 2 arguments for message/enum."); } self->field_type_class = argv[1]; if (argc > 2) { ary = argv[2]; } validate_type_class(self->field_type, self->field_type_class); } else { if (argc > 2) { rb_raise(rb_eArgError, "Too many arguments: expected 1 or 2."); } if (argc > 1) { ary = argv[1]; } } if (ary != Qnil) { if (!RB_TYPE_P(ary, T_ARRAY)) { rb_raise(rb_eArgError, "Expected array as initialize argument"); } for (int i = 0; i < RARRAY_LEN(ary); i++) { RepeatedField_push(_self, rb_ary_entry(ary, i)); } } }
/* * call-seq: * RepeatedField.insert(*args) * * Pushes each arg in turn onto the end of the repeated field. */ VALUE RepeatedField_insert(int argc, VALUE* argv, VALUE _self) { for (int i = 0; i < argc; i++) { RepeatedField_push(_self, argv[i]); } return Qnil; }