/* * call-seq: * Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) * => new map * * Allocates a new Map container. This constructor may be called with 2, 3, or 4 * arguments. The first two arguments are always present and are symbols (taking * on the same values as field-type symbols in message descriptors) that * indicate the type of the map key and value fields. * * The supported key types are: :int32, :int64, :uint32, :uint64, :bool, * :string, :bytes. * * The supported value types are: :int32, :int64, :uint32, :uint64, :bool, * :string, :bytes, :enum, :message. * * The third argument, value_typeclass, must be present if value_type is :enum * or :message. As in RepeatedField#new, this argument must be a message class * (for :message) or enum module (for :enum). * * The last argument, if present, provides initial content for map. Note that * this may be an ordinary Ruby hashmap or another Map instance with identical * key and value types. Also note that this argument may be present whether or * not value_typeclass is present (and it is unambiguously separate from * value_typeclass because value_typeclass's presence is strictly determined by * value_type). The contents of this initial hashmap or Map instance are * shallow-copied into the new Map: the original map is unmodified, but * references to underlying objects will be shared if the value type is a * message type. */ VALUE Map_init(int argc, VALUE* argv, VALUE _self) { Map* self = ruby_to_Map(_self); int init_value_arg; // We take either two args (:key_type, :value_type), three args (:key_type, // :value_type, "ValueMessageType"), or four args (the above plus an initial // hashmap). if (argc < 2 || argc > 4) { rb_raise(rb_eArgError, "Map constructor expects 2, 3 or 4 arguments."); } self->key_type = ruby_to_fieldtype(argv[0]); self->value_type = ruby_to_fieldtype(argv[1]); // Check that the key type is an allowed type. switch (self->key_type) { case UPB_TYPE_INT32: case UPB_TYPE_INT64: case UPB_TYPE_UINT32: case UPB_TYPE_UINT64: case UPB_TYPE_BOOL: case UPB_TYPE_STRING: case UPB_TYPE_BYTES: // These are OK. break; default: rb_raise(rb_eArgError, "Invalid key type for map."); } init_value_arg = 2; if (needs_typeclass(self->value_type) && argc > 2) { self->value_type_class = argv[2]; validate_type_class(self->value_type, self->value_type_class); init_value_arg = 3; } // Table value type is always UINT64: this ensures enough space to store the // native_slot value. if (!upb_strtable_init(&self->table, UPB_CTYPE_UINT64)) { rb_raise(rb_eRuntimeError, "Could not allocate table."); } if (argc > init_value_arg) { Map_merge_into_self(_self, argv[init_value_arg]); } return Qnil; }
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: * FieldDescriptor.type = type * * Sets this field's type. Cannot be called if field is part of a message type * already in a pool. */ VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) { DEFINE_SELF(FieldDescriptor, self, _self); upb_fielddef* mut_def = check_field_notfrozen(self->fielddef); upb_fielddef_settype(mut_def, ruby_to_fieldtype(type)); return Qnil; }