1 /* $NetBSD: dict_ht.c,v 1.1.1.2 2010/06/17 18:07:12 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* dict_ht 3 6 /* SUMMARY 7 /* dictionary manager interface to hash tables 8 /* SYNOPSIS 9 /* #include <dict_ht.h> 10 /* 11 /* DICT *dict_ht_open(name, open_flags, dict_flags) 12 /* const char *name; 13 /* int open_flags; 14 /* int dict_flags; 15 /* DESCRIPTION 16 /* dict_ht_open() creates a memory-resident hash table and 17 /* makes it accessible via the generic dictionary operations 18 /* documented in dict_open(3). The open_flags argument is 19 /* ignored. 20 /* SEE ALSO 21 /* dict(3) generic dictionary manager 22 /* LICENSE 23 /* .ad 24 /* .fi 25 /* The Secure Mailer license must be distributed with this software. 26 /* AUTHOR(S) 27 /* Wietse Venema 28 /* IBM T.J. Watson Research 29 /* P.O. Box 704 30 /* Yorktown Heights, NY 10598, USA 31 /*--*/ 32 33 /* System library. */ 34 35 #include "sys_defs.h" 36 37 /* Utility library. */ 38 39 #include "mymalloc.h" 40 #include "htable.h" 41 #include "dict.h" 42 #include "dict_ht.h" 43 #include "stringops.h" 44 #include "vstring.h" 45 46 /* Application-specific. */ 47 48 typedef struct { 49 DICT dict; /* generic members */ 50 HTABLE *table; /* hash table */ 51 } DICT_HT; 52 53 /* dict_ht_lookup - find hash-table entry */ 54 55 static const char *dict_ht_lookup(DICT *dict, const char *name) 56 { 57 DICT_HT *dict_ht = (DICT_HT *) dict; 58 59 dict_errno = 0; 60 61 /* 62 * Optionally fold the key. 63 */ 64 if (dict->flags & DICT_FLAG_FOLD_FIX) { 65 if (dict->fold_buf == 0) 66 dict->fold_buf = vstring_alloc(10); 67 vstring_strcpy(dict->fold_buf, name); 68 name = lowercase(vstring_str(dict->fold_buf)); 69 } 70 return (htable_find(dict_ht->table, name)); 71 } 72 73 /* dict_ht_update - add or update hash-table entry */ 74 75 static void dict_ht_update(DICT *dict, const char *name, const char *value) 76 { 77 DICT_HT *dict_ht = (DICT_HT *) dict; 78 HTABLE_INFO *ht; 79 80 /* 81 * Optionally fold the key. 82 */ 83 if (dict->flags & DICT_FLAG_FOLD_FIX) { 84 if (dict->fold_buf == 0) 85 dict->fold_buf = vstring_alloc(10); 86 vstring_strcpy(dict->fold_buf, name); 87 name = lowercase(vstring_str(dict->fold_buf)); 88 } 89 if ((ht = htable_locate(dict_ht->table, name)) != 0) { 90 myfree(ht->value); 91 } else { 92 ht = htable_enter(dict_ht->table, name, (char *) 0); 93 } 94 ht->value = mystrdup(value); 95 } 96 97 /* dict_ht_sequence - first/next iterator */ 98 99 static int dict_ht_sequence(DICT *dict, int how, const char **name, 100 const char **value) 101 { 102 DICT_HT *dict_ht = (DICT_HT *) dict; 103 HTABLE_INFO *ht; 104 105 ht = htable_sequence(dict_ht->table, 106 how == DICT_SEQ_FUN_FIRST ? HTABLE_SEQ_FIRST : 107 how == DICT_SEQ_FUN_NEXT ? HTABLE_SEQ_NEXT : 108 HTABLE_SEQ_STOP); 109 if (ht != 0) { 110 *name = ht->key; 111 *value = ht->value; 112 return (0); 113 } else { 114 *name = 0; 115 *value = 0; 116 return (1); 117 } 118 } 119 120 /* dict_ht_close - disassociate from hash table */ 121 122 static void dict_ht_close(DICT *dict) 123 { 124 DICT_HT *dict_ht = (DICT_HT *) dict; 125 126 htable_free(dict_ht->table, myfree); 127 if (dict_ht->dict.fold_buf) 128 vstring_free(dict_ht->dict.fold_buf); 129 dict_free(dict); 130 } 131 132 /* dict_ht_open - create association with hash table */ 133 134 DICT *dict_ht_open(const char *name, int unused_open_flags, int dict_flags) 135 { 136 DICT_HT *dict_ht; 137 138 dict_ht = (DICT_HT *) dict_alloc(DICT_TYPE_HT, name, sizeof(*dict_ht)); 139 dict_ht->dict.lookup = dict_ht_lookup; 140 dict_ht->dict.update = dict_ht_update; 141 dict_ht->dict.sequence = dict_ht_sequence; 142 dict_ht->dict.close = dict_ht_close; 143 dict_ht->dict.flags = dict_flags | DICT_FLAG_FIXED; 144 if (dict_flags & DICT_FLAG_FOLD_FIX) 145 dict_ht->dict.fold_buf = vstring_alloc(10); 146 dict_ht->table = htable_create(0); 147 return (&dict_ht->dict); 148 } 149