xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_ht.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
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