/* * call-seq: * Map.has_key?(key) => bool * * Returns true if the given key is present in the map. Throws an exception if * the key has the wrong type. */ VALUE Map_has_key(VALUE _self, VALUE key) { Map* self = ruby_to_Map(_self); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; size_t length = 0; key = table_key(self, key, keybuf, &keyval, &length); if (upb_strtable_lookup2(&self->table, keyval, length, NULL)) { return Qtrue; } else { return Qfalse; } }
/* * 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. */ VALUE Map_delete(VALUE _self, VALUE key) { Map* self = ruby_to_Map(_self); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; size_t length = 0; upb_value v; key = table_key(self, key, keybuf, &keyval, &length); if (upb_strtable_remove2(&self->table, keyval, length, &v)) { void* mem = value_memory(&v); return native_slot_get(self->value_type, self->value_type_class, mem); } else { return Qnil; } }
/* * 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. */ VALUE Map_index_set(VALUE _self, VALUE key, VALUE value) { Map* self = ruby_to_Map(_self); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; size_t length = 0; table_key(self, key, keybuf, &keyval, &length); upb_value v; void* mem = value_memory(&v); native_slot_set(self->value_type, self->value_type_class, mem, value); // Replace any existing value by issuing a 'remove' operation first. upb_strtable_remove2(&self->table, keyval, length, NULL); if (!upb_strtable_insert2(&self->table, keyval, length, v)) { rb_raise(rb_eRuntimeError, "Could not insert into table"); } // Ruby hashmap's :[]= method also returns the inserted value. return value; }