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