// Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd #ifndef UPB_HASH_STR_TABLE_H_ #define UPB_HASH_STR_TABLE_H_ #include "upb/hash/common.h" // Must be last. #include "upb/port/def.inc" typedef struct { upb_table t; } upb_strtable; #ifdef __cplusplus extern "C" { #endif // Initialize a table. If memory allocation failed, false is returned and // the table is uninitialized. bool upb_strtable_init(upb_strtable* table, size_t expected_size, upb_Arena* a); // Returns the number of values in the table. UPB_INLINE size_t upb_strtable_count(const upb_strtable* t) { return t->t.count; } void upb_strtable_clear(upb_strtable* t); // Inserts the given key into the hashtable with the given value. // The key must not already exist in the hash table. The key is not required // to be NULL-terminated, and the table will make an internal copy of the key. // // If a table resize was required but memory allocation failed, false is // returned and the table is unchanged. */ bool upb_strtable_insert(upb_strtable* t, const char* key, size_t len, upb_value val, upb_Arena* a); // Looks up key in this table, returning "true" if the key was found. // If v is non-NULL, copies the value for this key into *v. bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, upb_value* v); // For NULL-terminated strings. UPB_INLINE bool upb_strtable_lookup(const upb_strtable* t, const char* key, upb_value* v) { return upb_strtable_lookup2(t, key, strlen(key), v); } // Removes an item from the table. Returns true if the remove was successful, // and stores the removed item in *val if non-NULL. bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, upb_value* val); UPB_INLINE bool upb_strtable_remove(upb_strtable* t, const char* key, upb_value* v) { return upb_strtable_remove2(t, key, strlen(key), v); } // Exposed for testing only. bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a); /* Iteration over strtable: * * intptr_t iter = UPB_STRTABLE_BEGIN; * upb_StringView key; * upb_value val; * while (upb_strtable_next2(t, &key, &val, &iter)) { * // ... * } */ #define UPB_STRTABLE_BEGIN -1 bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, upb_value* val, intptr_t* iter); void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter); void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v); /* DEPRECATED iterators, slated for removal. * * Iterators for string tables. We are subject to some kind of unusual * design constraints: * * For high-level languages: * - we must be able to guarantee that we don't crash or corrupt memory even if * the program accesses an invalidated iterator. * * For C++11 range-based for: * - iterators must be copyable * - iterators must be comparable * - it must be possible to construct an "end" value. * * Iteration order is undefined. * * Modifying the table invalidates iterators. upb_{str,int}table_done() is * guaranteed to work even on an invalidated iterator, as long as the table it * is iterating over has not been freed. Calling next() or accessing data from * an invalidated iterator yields unspecified elements from the table, but it is * guaranteed not to crash and to return real table elements (except when done() * is true). */ /* upb_strtable_iter **********************************************************/ /* upb_strtable_iter i; * upb_strtable_begin(&i, t); * for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { * const char *key = upb_strtable_iter_key(&i); * const upb_value val = upb_strtable_iter_value(&i); * // ... * } */ typedef struct { const upb_strtable* t; size_t index; } upb_strtable_iter; UPB_INLINE const upb_tabent* str_tabent(const upb_strtable_iter* i) { return &i->t->t.entries[i->index]; } void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t); void upb_strtable_next(upb_strtable_iter* i); bool upb_strtable_done(const upb_strtable_iter* i); upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i); upb_value upb_strtable_iter_value(const upb_strtable_iter* i); void upb_strtable_iter_setdone(upb_strtable_iter* i); bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, const upb_strtable_iter* i2); #ifdef __cplusplus } /* extern "C" */ #endif #include "upb/port/undef.inc" #endif /* UPB_HASH_STR_TABLE_H_ */