diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
commit | f7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch) | |
tree | a3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/lib/str-table.c | |
parent | Initial commit. (diff) | |
download | dovecot-upstream.tar.xz dovecot-upstream.zip |
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/lib/str-table.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/lib/str-table.c b/src/lib/str-table.c new file mode 100644 index 0000000..10eddd6 --- /dev/null +++ b/src/lib/str-table.c @@ -0,0 +1,78 @@ +/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "hash.h" +#include "str-table.h" + +struct str_table { + HASH_TABLE(char *, void *) hash; +}; + +struct str_table *str_table_init(void) +{ + struct str_table *table; + + table = i_new(struct str_table, 1); + hash_table_create(&table->hash, default_pool, 0, str_hash, strcmp); + return table; +} + +void str_table_deinit(struct str_table **_table) +{ + struct str_table *table = *_table; + struct hash_iterate_context *iter; + char *key; + void *value; + + *_table = NULL; + + iter = hash_table_iterate_init(table->hash); + while (hash_table_iterate(iter, table->hash, &key, &value)) + i_free(key); + hash_table_iterate_deinit(&iter); + hash_table_destroy(&table->hash); + i_free(table); +} + +bool str_table_is_empty(struct str_table *table) +{ + return hash_table_count(table->hash) == 0; +} + +const char *str_table_ref(struct str_table *table, const char *str) +{ + char *key; + void *value; + unsigned int ref; + + if (!hash_table_lookup_full(table->hash, str, &key, &value)) { + key = i_strdup(str); + ref = 1; + } else { + ref = POINTER_CAST_TO(value, unsigned int); + i_assert(ref > 0); + ref++; + } + hash_table_update(table->hash, key, POINTER_CAST(ref)); + return key; +} + +void str_table_unref(struct str_table *table, const char **str) +{ + char *key; + void *value; + unsigned int ref; + + if (!hash_table_lookup_full(table->hash, *str, &key, &value)) + i_unreached(); + + ref = POINTER_CAST_TO(value, unsigned int); + i_assert(ref > 0); + if (--ref > 0) + hash_table_update(table->hash, key, POINTER_CAST(ref)); + else { + hash_table_remove(table->hash, key); + i_free(key); + } + *str = NULL; +} |