Postfix3.3.1
dict_ht.c
[詳解]
1 /*++
2 /* NAME
3 /* dict_ht 3
4 /* SUMMARY
5 /* dictionary manager interface to hash tables
6 /* SYNOPSIS
7 /* #include <dict_ht.h>
8 /*
9 /* DICT *dict_ht_open(name, open_flags, dict_flags)
10 /* const char *name;
11 /* int open_flags;
12 /* int dict_flags;
13 /* DESCRIPTION
14 /* dict_ht_open() creates a memory-resident hash table and
15 /* makes it accessible via the generic dictionary operations
16 /* documented in dict_open(3). The open_flags argument is
17 /* ignored.
18 /* SEE ALSO
19 /* dict(3) generic dictionary manager
20 /* LICENSE
21 /* .ad
22 /* .fi
23 /* The Secure Mailer license must be distributed with this software.
24 /* AUTHOR(S)
25 /* Wietse Venema
26 /* IBM T.J. Watson Research
27 /* P.O. Box 704
28 /* Yorktown Heights, NY 10598, USA
29 /*--*/
30 
31 /* System library. */
32 
33 #include "sys_defs.h"
34 
35 /* Utility library. */
36 
37 #include "mymalloc.h"
38 #include "htable.h"
39 #include "dict.h"
40 #include "dict_ht.h"
41 #include "stringops.h"
42 #include "vstring.h"
43 
44 /* Application-specific. */
45 
46 typedef struct {
47  DICT dict; /* generic members */
48  HTABLE *table; /* hash table */
49 } DICT_HT;
50 
51 /* dict_ht_delete - delete hash-table entry */
52 
53 static int dict_ht_delete(DICT *dict, const char *name)
54 {
55  DICT_HT *dict_ht = (DICT_HT *) dict;
56 
57  /*
58  * Optionally fold the key.
59  */
60  if (dict->flags & DICT_FLAG_FOLD_FIX) {
61  if (dict->fold_buf == 0)
62  dict->fold_buf = vstring_alloc(10);
63  vstring_strcpy(dict->fold_buf, name);
64  name = lowercase(vstring_str(dict->fold_buf));
65  }
66  if (htable_locate(dict_ht->table, name) == 0) {
68  } else {
69  htable_delete(dict_ht->table, name, myfree);
71  }
72 }
73 
74 /* dict_ht_lookup - find hash-table entry */
75 
76 static const char *dict_ht_lookup(DICT *dict, const char *name)
77 {
78  DICT_HT *dict_ht = (DICT_HT *) dict;
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  DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, htable_find(dict_ht->table, name));
90 }
91 
92 /* dict_ht_update - add or update hash-table entry */
93 
94 static int dict_ht_update(DICT *dict, const char *name, const char *value)
95 {
96  DICT_HT *dict_ht = (DICT_HT *) dict;
97  HTABLE_INFO *ht;
98  char *saved_value = mystrdup(value);
99 
100  /*
101  * Optionally fold the key.
102  */
103  if (dict->flags & DICT_FLAG_FOLD_FIX) {
104  if (dict->fold_buf == 0)
105  dict->fold_buf = vstring_alloc(10);
106  vstring_strcpy(dict->fold_buf, name);
107  name = lowercase(vstring_str(dict->fold_buf));
108  }
109  if ((ht = htable_locate(dict_ht->table, name)) != 0) {
110  myfree(ht->value);
111  } else {
112  ht = htable_enter(dict_ht->table, name, (void *) 0);
113  }
114  ht->value = saved_value;
116 }
117 
118 /* dict_ht_sequence - first/next iterator */
119 
120 static int dict_ht_sequence(DICT *dict, int how, const char **name,
121  const char **value)
122 {
123  DICT_HT *dict_ht = (DICT_HT *) dict;
124  HTABLE_INFO *ht;
125 
126  ht = htable_sequence(dict_ht->table,
130  if (ht != 0) {
131  *name = ht->key;
132  *value = ht->value;
134  } else {
135  *name = 0;
136  *value = 0;
138  }
139 }
140 
141 /* dict_ht_close - disassociate from hash table */
142 
143 static void dict_ht_close(DICT *dict)
144 {
145  DICT_HT *dict_ht = (DICT_HT *) dict;
146 
147  htable_free(dict_ht->table, myfree);
148  if (dict_ht->dict.fold_buf)
149  vstring_free(dict_ht->dict.fold_buf);
150  dict_free(dict);
151 }
152 
153 /* dict_ht_open - create association with hash table */
154 
155 DICT *dict_ht_open(const char *name, int unused_open_flags, int dict_flags)
156 {
157  DICT_HT *dict_ht;
158 
159  dict_ht = (DICT_HT *) dict_alloc(DICT_TYPE_HT, name, sizeof(*dict_ht));
160  dict_ht->dict.lookup = dict_ht_lookup;
161  dict_ht->dict.update = dict_ht_update;
162  dict_ht->dict.delete = dict_ht_delete;
163  dict_ht->dict.sequence = dict_ht_sequence;
164  dict_ht->dict.close = dict_ht_close;
165  dict_ht->dict.flags = dict_flags | DICT_FLAG_FIXED;
166  if (dict_flags & DICT_FLAG_FOLD_FIX)
167  dict_ht->dict.fold_buf = vstring_alloc(10);
168  dict_ht->table = htable_create(0);
169  dict_ht->dict.owner.status = DICT_OWNER_TRUSTED;
170  return (&dict_ht->dict);
171 }
void htable_free(HTABLE *table, void(*free_fn)(void *))
Definition: htable.c:287
void * value
Definition: htable.h:18
void myfree(void *ptr)
Definition: mymalloc.c:207
HTABLE_INFO * htable_locate(HTABLE *table, const char *key)
Definition: htable.c:242
char * mystrdup(const char *str)
Definition: mymalloc.c:225
#define DICT_TYPE_HT
Definition: dict_ht.h:23
void(* close)(struct DICT *)
Definition: dict.h:87
#define DICT_SEQ_FUN_FIRST
Definition: dict.h:200
#define HTABLE_SEQ_FIRST
Definition: htable.h:43
int(* delete)(struct DICT *, const char *)
Definition: dict.h:84
#define vstring_str(vp)
Definition: vstring.h:71
#define DICT_FLAG_FIXED
Definition: dict.h:114
#define DICT_SEQ_FUN_NEXT
Definition: dict.h:201
int flags
Definition: dict.h:81
#define DICT_STAT_FAIL
Definition: dict.h:185
#define HTABLE_SEQ_STOP
Definition: htable.h:45
Definition: htable.h:25
#define DICT_FLAG_FOLD_FIX
Definition: dict.h:124
#define DICT_ERR_NONE
Definition: dict.h:177
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
HTABLE * htable_create(ssize_t size)
Definition: htable.c:179
Definition: dict.h:78
int(* update)(struct DICT *, const char *, const char *)
Definition: dict.h:83
#define DICT_STAT_SUCCESS
Definition: dict.h:186
#define DICT_OWNER_TRUSTED
Definition: dict.h:46
HTABLE_INFO * htable_sequence(HTABLE *table, int how)
Definition: htable.c:351
#define HTABLE_SEQ_NEXT
Definition: htable.h:44
char * key
Definition: htable.h:17
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
DICT dict
Definition: dict_ht.c:47
void * htable_find(HTABLE *table, const char *key)
Definition: htable.c:227
DICT * dict_ht_open(const char *name, int unused_open_flags, int dict_flags)
Definition: dict_ht.c:155
char * lowercase(char *string)
Definition: lowercase.c:34
const char *(* lookup)(struct DICT *, const char *)
Definition: dict.h:82
#define DICT_ERR_VAL_RETURN(dict, err, val)
Definition: dict.h:192
int status
Definition: dict.h:38
void dict_free(DICT *)
Definition: dict_alloc.c:163
HTABLE * table
Definition: dict_ht.c:48
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
int(* sequence)(struct DICT *, int, const char **, const char **)
Definition: dict.h:85
DICT * dict_alloc(const char *, const char *, ssize_t)
Definition: dict_alloc.c:135
VSTRING * fold_buf
Definition: dict.h:92
void htable_delete(HTABLE *table, const char *key, void(*free_fn)(void *))
Definition: htable.c:257
DICT_OWNER owner
Definition: dict.h:93
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
Definition: htable.c:212