summaryrefslogtreecommitdiff
path: root/upb/table.int.h
diff options
context:
space:
mode:
authorChris Fallin <cfallin@c1f.net>2014-12-16 15:23:29 -0800
committerChris Fallin <cfallin@c1f.net>2014-12-18 14:10:07 -0800
commitfd1cc566253819100a416b5be37547c75fecf314 (patch)
tree888da194f176a6d00c003971e2c2a4acf5e5773e /upb/table.int.h
parent0ab8d5e1bbfb7de8582b1a58d680593c15a9cc1f (diff)
Modified strtable to support length-delimited string keys. Allows for
arbitrary binary data, e.g., to support strings from other languages as key values.
Diffstat (limited to 'upb/table.int.h')
-rw-r--r--upb/table.int.h38
1 files changed, 34 insertions, 4 deletions
diff --git a/upb/table.int.h b/upb/table.int.h
index 049ad3a..e851e90 100644
--- a/upb/table.int.h
+++ b/upb/table.int.h
@@ -97,6 +97,9 @@ typedef struct {
// Like strdup(), which isn't always available since it's not ANSI C.
char *upb_strdup(const char *s);
+// Variant that works with a length-delimited rather than NULL-delimited string,
+// as supported by strtable.
+char *upb_strdup2(const char *s, size_t len);
UPB_INLINE void _upb_value_setval(upb_value *v, _upb_value val,
upb_ctype_t ctype) {
@@ -151,12 +154,24 @@ FUNCS(fptr, fptr, upb_func*, UPB_CTYPE_FPTR);
typedef union {
uintptr_t num;
- const char *str; // We own, nullz.
+ struct {
+ // We own this. NULL-terminated but may also contain binary data; see
+ // explicit length below.
+ // TODO: move the length to the start of the string in order to reduce
+ // tabkey's size (to one machine word) in a way that supports static
+ // initialization.
+ const char *str;
+ size_t length;
+ } s;
} upb_tabkey;
#define UPB_TABKEY_NUM(n) {n}
#ifdef UPB_C99
-#define UPB_TABKEY_STR(s) {.str = s}
+// Given that |s| is a string literal, sizeof(s) gives us a
+// compile-time-constant strlen(). We must ensure that this works for static
+// data initializers.
+#define UPB_TABKEY_STR(strval) { .s = { .str = strval, \
+ .length = sizeof(strval) - 1 } }
#endif
// TODO(haberman): C++
#define UPB_TABKEY_NONE {0}
@@ -262,7 +277,14 @@ UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) {
// If a table resize was required but memory allocation failed, false is
// returned and the table is unchanged.
bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val);
-bool upb_strtable_insert(upb_strtable *t, const char *key, upb_value val);
+bool upb_strtable_insert2(upb_strtable *t, const char *key, size_t len,
+ upb_value val);
+
+// For NULL-terminated strings.
+UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key,
+ upb_value val) {
+ return upb_strtable_insert2(t, key, strlen(key), val);
+}
// 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.
@@ -279,7 +301,14 @@ UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key,
// 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_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val);
-bool upb_strtable_remove(upb_strtable *t, const char *key, upb_value *val);
+bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
+ upb_value *val);
+
+// For NULL-terminated strings.
+UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key,
+ upb_value *v) {
+ return upb_strtable_remove2(t, key, strlen(key), v);
+}
// Updates an existing entry in an inttable. If the entry does not exist,
// returns false and does nothing. Unlike insert/remove, this does not
@@ -373,6 +402,7 @@ 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);
const char *upb_strtable_iter_key(upb_strtable_iter *i);
+size_t upb_strtable_iter_keylength(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,
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback