Class: Google::Protobuf::Map
- Inherits:
-
Object
- Object
- Google::Protobuf::Map
- Extended by:
- Internal::Convert
- Includes:
- Enumerable, Internal::Convert
- Defined in:
- lib/google/protobuf/ffi/map.rb
Class Method Summary collapse
-
.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) ⇒ Object
call-seq: Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) => new map.
Instance Method Summary collapse
-
#==(other) ⇒ Object
call-seq: Map.==(other) => boolean.
-
#[](key) ⇒ Object
call-seq: Map.[](key) => value.
-
#[]=(key, value) ⇒ Object
call-seq: Map.[]=(key, value) => value.
- #clear ⇒ Object
-
#delete(key) ⇒ Object
call-seq: Map.delete(key) => old_value.
-
#dup ⇒ Object
(also: #clone)
call-seq: Map.dup => new_map.
-
#each(&block) ⇒ Object
call-seq: Map.each(&block).
-
#freeze ⇒ Object
Freezes the map object.
-
#frozen? ⇒ Boolean
Is this object frozen? Returns true if either this Ruby wrapper or the underlying representation are frozen.
- #has_key?(key) ⇒ Boolean
- #hash ⇒ Object
- #inspect ⇒ Object
-
#keys ⇒ Object
call-seq: Map.keys => [list_of_keys].
- #length ⇒ Object (also: #size)
-
#merge(other) ⇒ Object
call-seq: Map.merge(other_map) => map.
-
#to_h ⇒ Object
call-seq: Map.to_h => {}.
-
#values ⇒ Object
call-seq: Map.values => [list_of_values].
Methods included from Internal::Convert
convert_ruby_to_upb, convert_upb_to_ruby, map_create_hash, message_value_deep_copy, repeated_field_create_array, scalar_create_hash, to_h_internal
Class Method Details
.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) ⇒ Object
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.
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/google/protobuf/ffi/map.rb', line 58 def self.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) instance = allocate # TODO This argument mangling doesn't agree with the type signature, # but does align with the text of the comments and is required to make unit tests pass. if init_hashmap.empty? and ![:enum, :message].include?(value_type) init_hashmap = value_typeclass value_typeclass = nil end instance.send(:initialize, key_type, value_type, value_type_class: value_typeclass, initial_values: init_hashmap) instance end |
Instance Method Details
#==(other) ⇒ Object
call-seq:
Map.==(other) => boolean
Compares this map to another. Maps are equal if they have identical key sets, and for each key, the values in both maps compare equal. Elements are compared as per normal Ruby semantics, by calling their :== methods (or performing a more efficient comparison for primitive types).
Maps with dissimilar key types or value types/typeclasses are never equal, even if value comparison (for example, between integers and floats) would have otherwise indicated that every element has equal value.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/google/protobuf/ffi/map.rb', line 214 def ==(other) if other.is_a? Hash other = self.class.send(:private_constructor, key_type, value_type, descriptor, initial_values: other) elsif !other.is_a? Google::Protobuf::Map return false end return true if object_id == other.object_id return false if key_type != other.send(:key_type) or value_type != other.send(:value_type) or descriptor != other.send(:descriptor) or length != other.length other_map_ptr = other.send(:map_ptr) each_msg_val do |, | other_value = Google::Protobuf::FFI::MessageValue.new return false unless Google::Protobuf::FFI.map_get(other_map_ptr, , other_value) return false unless Google::Protobuf::FFI.(, other_value, value_type, descriptor) end true end |
#[](key) ⇒ Object
call-seq:
Map.[](key) => value
Accesses the element at the given key. Throws an exception if the key type is
incorrect. Returns nil when the key is not present in the map.
104 105 106 107 108 109 110 |
# File 'lib/google/protobuf/ffi/map.rb', line 104 def [](key) value = Google::Protobuf::FFI::MessageValue.new = convert_ruby_to_upb(key, arena, key_type, nil) if Google::Protobuf::FFI.map_get(@map_ptr, , value) convert_upb_to_ruby(value, value_type, descriptor, arena) end end |
#[]=(key, value) ⇒ Object
call-seq:
Map.[]=(key, value) => value
Inserts or overwrites the value at the given key with the given new value. Throws an exception if the key type is incorrect. Returns the new value that was just inserted.
119 120 121 122 123 124 125 |
# File 'lib/google/protobuf/ffi/map.rb', line 119 def []=(key, value) raise FrozenError.new "can't modify frozen #{self.class}" if frozen? = convert_ruby_to_upb(key, arena, key_type, nil) = convert_ruby_to_upb(value, arena, value_type, descriptor) Google::Protobuf::FFI.map_set(@map_ptr, , , arena) value end |
#clear ⇒ Object
149 150 151 152 153 |
# File 'lib/google/protobuf/ffi/map.rb', line 149 def clear raise FrozenError.new "can't modify frozen #{self.class}" if frozen? Google::Protobuf::FFI.map_clear(@map_ptr) nil end |
#delete(key) ⇒ Object
call-seq:
Map.delete(key) => old_value
Deletes the value at the given key, if any, returning either the old value or nil if none was present. Throws an exception if the key is of the wrong type.
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/google/protobuf/ffi/map.rb', line 138 def delete(key) raise FrozenError.new "can't modify frozen #{self.class}" if frozen? value = Google::Protobuf::FFI::MessageValue.new = convert_ruby_to_upb(key, arena, key_type, nil) if Google::Protobuf::FFI.map_delete(@map_ptr, , value) convert_upb_to_ruby(value, value_type, descriptor, arena) else nil end end |
#dup ⇒ Object Also known as: clone
call-seq:
Map.dup => new_map
Duplicates this map with a shallow copy. References to all non-primitive element objects (e.g., submessages) are shared.
197 198 199 |
# File 'lib/google/protobuf/ffi/map.rb', line 197 def dup internal_dup end |
#each(&block) ⇒ Object
call-seq:
Map.each(&block)
Invokes &block on each |key, value| pair in the map, in unspecified order. Note that Map also includes Enumerable; map thus acts like a normal Ruby sequence.
291 292 293 294 295 296 297 298 |
# File 'lib/google/protobuf/ffi/map.rb', line 291 def each &block each_msg_val do |, | key_value = convert_upb_to_ruby(, key_type) value_value = convert_upb_to_ruby(, value_type, descriptor, arena) yield key_value, value_value end nil end |
#freeze ⇒ Object
Freezes the map object. We have to intercept this so we can freeze the underlying representation, not just the Ruby wrapper. Returns self.
177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/google/protobuf/ffi/map.rb', line 177 def freeze if method(:frozen?).super_method.call unless Google::Protobuf::FFI.map_frozen? @map_ptr raise RuntimeError.new "Underlying representation of map still mutable despite frozen wrapper" end return self end unless Google::Protobuf::FFI.map_frozen? @map_ptr mini_table = (value_type == :message) ? Google::Protobuf::FFI.get_mini_table(@descriptor) : nil Google::Protobuf::FFI.map_freeze(@map_ptr, mini_table) end super end |
#frozen? ⇒ Boolean
Is this object frozen? Returns true if either this Ruby wrapper or the underlying representation are frozen. Freezes the wrapper if the underlying representation is already frozen but this wrapper isn’t.
165 166 167 168 169 170 171 172 |
# File 'lib/google/protobuf/ffi/map.rb', line 165 def frozen? unless Google::Protobuf::FFI.map_frozen? @map_ptr raise RuntimeError.new "Ruby frozen Map with mutable representation" if super return false end method(:freeze).super_method.call unless super true end |
#has_key?(key) ⇒ Boolean
127 128 129 130 |
# File 'lib/google/protobuf/ffi/map.rb', line 127 def has_key?(key) = convert_ruby_to_upb(key, arena, key_type, nil) Google::Protobuf::FFI.map_get(@map_ptr, , nil) end |
#hash ⇒ Object
232 233 234 235 236 237 238 239 |
# File 'lib/google/protobuf/ffi/map.rb', line 232 def hash return_value = 0 each_msg_val do |, | return_value = Google::Protobuf::FFI.(, key_type, nil, return_value) return_value = Google::Protobuf::FFI.(, value_type, descriptor, return_value) end return_value end |
#inspect ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/google/protobuf/ffi/map.rb', line 257 def inspect key_value_pairs = [] each_msg_val do |, | key_string = convert_upb_to_ruby(, key_type).inspect if value_type == :message sub_msg_descriptor = Google::Protobuf::FFI.(descriptor) value_string = sub_msg_descriptor.msgclass.send(:inspect_internal, [:msg_val]) else value_string = convert_upb_to_ruby(, value_type, descriptor).inspect end key_value_pairs << "#{key_string}=>#{value_string}" end "{#{key_value_pairs.join(", ")}}" end |
#keys ⇒ Object
call-seq:
Map.keys => [list_of_keys]
Returns the list of keys contained in the map, in unspecified order.
75 76 77 78 79 80 81 82 |
# File 'lib/google/protobuf/ffi/map.rb', line 75 def keys return_value = [] internal_iterator do |iterator| = Google::Protobuf::FFI.map_key(@map_ptr, iterator) return_value << convert_upb_to_ruby(, key_type) end return_value end |
#length ⇒ Object Also known as: size
155 156 157 |
# File 'lib/google/protobuf/ffi/map.rb', line 155 def length Google::Protobuf::FFI.map_size(@map_ptr) end |
#merge(other) ⇒ Object
call-seq:
Map.merge(other_map) => map
Copies key/value pairs from other_map into a copy of this map. If a key is set in other_map and this map, the value from other_map overwrites the value in the new copy of this map. Returns the new copy of this map with merged contents.
280 281 282 |
# File 'lib/google/protobuf/ffi/map.rb', line 280 def merge(other) internal_merge(other) end |
#to_h ⇒ Object
246 247 248 249 250 251 252 253 254 255 |
# File 'lib/google/protobuf/ffi/map.rb', line 246 def to_h return {} if map_ptr.nil? or map_ptr.null? return_value = {} each_msg_val do |, | hash_key = convert_upb_to_ruby(, key_type) hash_value = scalar_create_hash(, value_type, msg_or_enum_descriptor: descriptor) return_value[hash_key] = hash_value end return_value end |
#values ⇒ Object
call-seq:
Map.values => [list_of_values]
Returns the list of values contained in the map, in unspecified order.
89 90 91 92 93 94 95 96 |
# File 'lib/google/protobuf/ffi/map.rb', line 89 def values return_value = [] internal_iterator do |iterator| = Google::Protobuf::FFI.map_value(@map_ptr, iterator) return_value << convert_upb_to_ruby(, value_type, descriptor, arena) end return_value end |