bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen#include "lib.h"
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen#include "hash.h"
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen#include "str-table.h"
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainenstruct str_table {
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen HASH_TABLE(char *, void *) hash;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen};
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainenstruct str_table *str_table_init(void)
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen{
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen struct str_table *table;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen table = i_new(struct str_table, 1);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen hash_table_create(&table->hash, default_pool, 0, str_hash, strcmp);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen return table;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen}
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainenvoid str_table_deinit(struct str_table **_table)
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen{
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen struct str_table *table = *_table;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen struct hash_iterate_context *iter;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen char *key;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen void *value;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen *_table = NULL;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen iter = hash_table_iterate_init(table->hash);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen while (hash_table_iterate(iter, table->hash, &key, &value))
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen i_free(key);
087272dde587c41c2605fe59340d7fa7021b6892Phil Carmody hash_table_iterate_deinit(&iter);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen hash_table_destroy(&table->hash);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen i_free(table);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen}
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainenbool str_table_is_empty(struct str_table *table)
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen{
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen return hash_table_count(table->hash) == 0;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen}
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainenconst char *str_table_ref(struct str_table *table, const char *str)
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen{
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen char *key;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen void *value;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen unsigned int ref;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen if (!hash_table_lookup_full(table->hash, str, &key, &value)) {
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen key = i_strdup(str);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen ref = 1;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen } else {
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen ref = POINTER_CAST_TO(value, unsigned int);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen i_assert(ref > 0);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen ref++;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen }
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen hash_table_update(table->hash, key, POINTER_CAST(ref));
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen return key;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen}
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainenvoid str_table_unref(struct str_table *table, const char **str)
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen{
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen char *key;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen void *value;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen unsigned int ref;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen if (!hash_table_lookup_full(table->hash, *str, &key, &value))
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen i_unreached();
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen ref = POINTER_CAST_TO(value, unsigned int);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen i_assert(ref > 0);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen if (--ref > 0)
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen hash_table_update(table->hash, key, POINTER_CAST(ref));
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen else {
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen hash_table_remove(table->hash, key);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen i_free(key);
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen }
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen *str = NULL;
639587335dfe5d66dc7034817b3e685458ecbee1Timo Sirainen}