#include "sys_defs.h"
#include "mymalloc.h"
#include "htable.h"
#include "dict.h"
#include "dict_ht.h"
#include "stringops.h"
#include "vstring.h"
typedef struct {
DICT dict;
HTABLE *table;
} DICT_HT;
static const char *dict_ht_lookup(DICT *dict, const char *name)
{
DICT_HT *dict_ht = (DICT_HT *) dict;
if (dict->flags & DICT_FLAG_FOLD_FIX) {
if (dict->fold_buf == 0)
dict->fold_buf = vstring_alloc(10);
vstring_strcpy(dict->fold_buf, name);
name = lowercase(vstring_str(dict->fold_buf));
}
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, htable_find(dict_ht->table, name));
}
static int dict_ht_update(DICT *dict, const char *name, const char *value)
{
DICT_HT *dict_ht = (DICT_HT *) dict;
HTABLE_INFO *ht;
char *saved_value = mystrdup(value);
if (dict->flags & DICT_FLAG_FOLD_FIX) {
if (dict->fold_buf == 0)
dict->fold_buf = vstring_alloc(10);
vstring_strcpy(dict->fold_buf, name);
name = lowercase(vstring_str(dict->fold_buf));
}
if ((ht = htable_locate(dict_ht->table, name)) != 0) {
myfree(ht->value);
} else {
ht = htable_enter(dict_ht->table, name, (char *) 0);
}
ht->value = saved_value;
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_SUCCESS);
}
static int dict_ht_sequence(DICT *dict, int how, const char **name,
const char **value)
{
DICT_HT *dict_ht = (DICT_HT *) dict;
HTABLE_INFO *ht;
ht = htable_sequence(dict_ht->table,
how == DICT_SEQ_FUN_FIRST ? HTABLE_SEQ_FIRST :
how == DICT_SEQ_FUN_NEXT ? HTABLE_SEQ_NEXT :
HTABLE_SEQ_STOP);
if (ht != 0) {
*name = ht->key;
*value = ht->value;
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_SUCCESS);
} else {
*name = 0;
*value = 0;
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_FAIL);
}
}
static void dict_ht_close(DICT *dict)
{
DICT_HT *dict_ht = (DICT_HT *) dict;
htable_free(dict_ht->table, myfree);
if (dict_ht->dict.fold_buf)
vstring_free(dict_ht->dict.fold_buf);
dict_free(dict);
}
DICT *dict_ht_open(const char *name, int unused_open_flags, int dict_flags)
{
DICT_HT *dict_ht;
dict_ht = (DICT_HT *) dict_alloc(DICT_TYPE_HT, name, sizeof(*dict_ht));
dict_ht->dict.lookup = dict_ht_lookup;
dict_ht->dict.update = dict_ht_update;
dict_ht->dict.sequence = dict_ht_sequence;
dict_ht->dict.close = dict_ht_close;
dict_ht->dict.flags = dict_flags | DICT_FLAG_FIXED;
if (dict_flags & DICT_FLAG_FOLD_FIX)
dict_ht->dict.fold_buf = vstring_alloc(10);
dict_ht->table = htable_create(0);
dict_ht->dict.owner.status = DICT_OWNER_TRUSTED;
return (&dict_ht->dict);
}