nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* conditions.c
2 * Implementation for condition handler.
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22  
23 #include <config.h>
24  
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include "conditions.h"
29  
30 /* container for condition classes */
31 static GHashTable *classes = NULL;
32  
33 /* condition data structure declaration */
34 struct condition{
35 char *class_id;
36 void *user_data;
37 _cnd_eval eval_func;
38 _cnd_reset reset_func;
39 };
40  
41 /* structure used to store class functions in GHashTable */
42 typedef struct _cnd_class{
43 _cnd_constr constr_func;
44 _cnd_destr destr_func;
45 _cnd_eval eval_func;
46 _cnd_reset reset_func;
47 } _cnd_class;
48  
49 /* helper function prototypes */
50 static void _cnd_init(void);
51 static void _cnd_find_hash_key_for_class_id(gpointer, gpointer, gpointer);
52  
53 condition *cnd_new(const char *class_id, ...) {
54 va_list ap;
55 condition *cnd = NULL;
56 condition *cnd_ref = NULL;
57 _cnd_class *cls = NULL;
58 char *id = NULL;
59  
60 /* check if hash table is already initialized */
61 _cnd_init();
62  
63 /* get class structure for this id */
64 if ((cls = (_cnd_class *)g_hash_table_lookup(classes, class_id)) == NULL) {
65 g_warning("cnd_new: Couldn't find class ID \"%s\"", class_id);
66 return NULL;
67 }
68  
69 /* initialize the basic structure */
70 if ((cnd_ref = (condition *)g_malloc(sizeof(condition))) == NULL)
71 return NULL;
72 cnd_ref->user_data = NULL;
73 cnd_ref->eval_func = cls->eval_func;
74 cnd_ref->reset_func = cls->reset_func;
75  
76 cnd_ref->class_id = g_strdup(class_id);
77  
78 /* perform class specific initialization */
79 va_start(ap, class_id);
80 cnd = (cls->constr_func)(cnd_ref, ap);
81 va_end(ap);
82  
83 /* check for successful construction */
84 if (cnd == NULL) {
85 g_free(cnd_ref);
86 g_free(id);
87 }
88 return cnd;
89 } /* END cnd_new() */
90  
91 void cnd_delete(condition *cnd) {
92 _cnd_class *cls = NULL;
93 const char* class_id;
94 /* check for valid pointer */
95 if (cnd == NULL)
96 return;
97  
98 class_id = cnd->class_id;
99 /* check if hash table is already initialized */
100 _cnd_init();
101 /* get the condition class */
102 cls = (_cnd_class *)g_hash_table_lookup(classes, class_id);
103 /* call class specific destructor */
104 if (cls != NULL)
105 (cls->destr_func)(cnd);
106 /* free memory */
107 g_free(cnd->class_id);
108 /* free basic structure */
109 g_free(cnd);
110 } /* END cnd_delete() */
111  
112 gboolean cnd_eval(condition *cnd, ...) {
113 va_list ap;
114 gboolean ret_val = FALSE;
115 /* validate cnd */
116 if (cnd == NULL)
117 return FALSE;
118 /* call specific handler */
119 va_start(ap, cnd);
120 ret_val = (cnd->eval_func)(cnd, ap);
121 va_end(ap);
122 return ret_val;
123 } /* END cnd_eval() */
124  
125 void cnd_reset(condition *cnd) {
126 if (cnd != NULL)
127 (cnd->reset_func)(cnd);
128 } /* END cnd_reset() */
129  
130 void* cnd_get_user_data(condition *cnd) {
131 return cnd->user_data;
132 } /* END cnd_get_user_data() */
133  
134 void cnd_set_user_data(condition *cnd, void *user_data) {
135 cnd->user_data = user_data;
136 } /* END cnd_set_user_data() */
137  
138 gboolean cnd_register_class(const char *class_id,
139 _cnd_constr constr_func,
140 _cnd_destr destr_func,
141 _cnd_eval eval_func,
142 _cnd_reset reset_func) {
143 char *key = NULL;
144 _cnd_class *cls = NULL;
145 /* check for valid parameters */
146 if ((constr_func == NULL) || (destr_func == NULL) ||
147 (eval_func == NULL) || (reset_func == NULL) || (class_id == NULL))
148 return FALSE;
149 /* check if hash table is already initialized */
150 _cnd_init();
151 /* check for unique class id */
152 if (g_hash_table_lookup(classes, class_id) != NULL) {
153 g_warning("cnd_register_class: Duplicate class ID \"%s\"", class_id);
154 return FALSE;
155 }
156 /* GHashTable keys need to be persistent for the lifetime of the hash
157 table. Allocate memory and copy the class id which we use as key. */
158 key = g_strdup(class_id);
159 /* initialize class structure */
160 if ((cls = (_cnd_class*)g_malloc(sizeof(_cnd_class))) == NULL) {
161 g_free(key);
162 return FALSE;
163 }
164 cls->constr_func = constr_func;
165 cls->destr_func = destr_func;
166 cls->eval_func = eval_func;
167 cls->reset_func = reset_func;
168 /* insert new class */
169 g_hash_table_insert(classes, key, cls);
170 return TRUE;
171 } /* END cnd_register_class() */
172  
173 static char *pkey = NULL;
174 void cnd_unregister_class(const char* class_id) {
175 const char *key = (const char*)class_id;
176 _cnd_class *cls = NULL;
177 /* check if hash table is already initialized */
178 _cnd_init();
179 /* find the key for this class id and store it in 'pkey' */
180 g_hash_table_foreach(classes,
181 _cnd_find_hash_key_for_class_id,
182 (gpointer)key);
183 /* find the class structure for this class id */
184 cls = (_cnd_class*)g_hash_table_lookup(classes, class_id);
185 /* remove constructor from hash table */
186 g_hash_table_remove(classes, class_id);
187 /* free the key */
188 g_free(pkey);
189 pkey = NULL;
190 /* free the value */
191 g_free(cls);
192 } /* END cnd_unregister_class() */
193  
194 /*
195 * Initialize hash table.
196 */
197 static void _cnd_init(void) {
198 if (classes != NULL)
199 return;
200 /* create hash table, we use strings as keys */
201 classes = g_hash_table_new(g_str_hash, g_str_equal);
202 } /* END _cnd_init() */
203  
204 /*
205 * Callback for function 'g_hash_table_foreach()'.
206 * We don't keep references to hash table keys. Keys have memory allocated
207 * which must be freed when they are not used anymore. This function finds
208 * the reference to a key corresponding to a particular class id. The reference
209 * to the key is stored in a global variable.
210 */
211 void _cnd_find_hash_key_for_class_id(gpointer key,
212 gpointer value _U_,
213 gpointer user_data) {
214 char *class_id = (char *)user_data;
215 char *key_value = (char *)key;
216 if (strcmp(class_id, key_value) == 0)
217 pkey = key_value;
218 } /* END _cnd_find_hash_key_for_class_id() */
219  
220 /*
221 * Editor modelines
222 *
223 * Local Variables:
224 * c-basic-offset: 2
225 * tab-width: 8
226 * indent-tabs-mode: nil
227 * End:
228 *
229 * ex: set shiftwidth=2 tabstop=8 expandtab:
230 * :indentSize=2:tabSize=8:noTabs=true:
231 */