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