1 /* $NetBSD: dict_ht.c,v 1.1.1.3 2011/03/02 19:32:42 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 char *saved_value = mystrdup(value); 80 81 /* 82 * Optionally fold the key. 83 */ 84 if (dict->flags & DICT_FLAG_FOLD_FIX) { 85 if (dict->fold_buf == 0) 86 dict->fold_buf = vstring_alloc(10); 87 vstring_strcpy(dict->fold_buf, name); 88 name = lowercase(vstring_str(dict->fold_buf)); 89 } 90 if ((ht = htable_locate(dict_ht->table, name)) != 0) { 91 myfree(ht->value); 92 } else { 93 ht = htable_enter(dict_ht->table, name, (char *) 0); 94 } 95 ht->value = saved_value; 96 } 97 98 /* dict_ht_sequence - first/next iterator */ 99 100 static int dict_ht_sequence(DICT *dict, int how, const char **name, 101 const char **value) 102 { 103 DICT_HT *dict_ht = (DICT_HT *) dict; 104 HTABLE_INFO *ht; 105 106 ht = htable_sequence(dict_ht->table, 107 how == DICT_SEQ_FUN_FIRST ? HTABLE_SEQ_FIRST : 108 how == DICT_SEQ_FUN_NEXT ? HTABLE_SEQ_NEXT : 109 HTABLE_SEQ_STOP); 110 if (ht != 0) { 111 *name = ht->key; 112 *value = ht->value; 113 return (0); 114 } else { 115 *name = 0; 116 *value = 0; 117 return (1); 118 } 119 } 120 121 /* dict_ht_close - disassociate from hash table */ 122 123 static void dict_ht_close(DICT *dict) 124 { 125 DICT_HT *dict_ht = (DICT_HT *) dict; 126 127 htable_free(dict_ht->table, myfree); 128 if (dict_ht->dict.fold_buf) 129 vstring_free(dict_ht->dict.fold_buf); 130 dict_free(dict); 131 } 132 133 /* dict_ht_open - create association with hash table */ 134 135 DICT *dict_ht_open(const char *name, int unused_open_flags, int dict_flags) 136 { 137 DICT_HT *dict_ht; 138 139 dict_ht = (DICT_HT *) dict_alloc(DICT_TYPE_HT, name, sizeof(*dict_ht)); 140 dict_ht->dict.lookup = dict_ht_lookup; 141 dict_ht->dict.update = dict_ht_update; 142 dict_ht->dict.sequence = dict_ht_sequence; 143 dict_ht->dict.close = dict_ht_close; 144 dict_ht->dict.flags = dict_flags | DICT_FLAG_FIXED; 145 if (dict_flags & DICT_FLAG_FOLD_FIX) 146 dict_ht->dict.fold_buf = vstring_alloc(10); 147 dict_ht->table = htable_create(0); 148 return (&dict_ht->dict); 149 } 150