2 * Implementation for condition handler.
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
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.
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.
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.
28 #include "conditions.h"
29 #include "ws_attributes.h"
31 /* container for condition classes */
32 static GHashTable *classes = NULL;
34 /* condition data structure declaration */
39 _cnd_reset reset_func;
42 /* structure used to store class functions in GHashTable */
43 typedef struct _cnd_class{
44 _cnd_constr constr_func;
45 _cnd_destr destr_func;
47 _cnd_reset reset_func;
50 /* helper function prototypes */
51 static void _cnd_init(void);
52 static void _cnd_find_hash_key_for_class_id(gpointer, gpointer, gpointer);
54 condition *cnd_new(const char *class_id, ...) {
56 condition *cnd = NULL;
57 condition *cnd_ref = NULL;
58 _cnd_class *cls = NULL;
61 /* check if hash table is already initialized */
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);
70 /* initialize the basic structure */
71 if ((cnd_ref = (condition *)g_malloc(sizeof(condition))) == NULL)
73 cnd_ref->user_data = NULL;
74 cnd_ref->eval_func = cls->eval_func;
75 cnd_ref->reset_func = cls->reset_func;
77 cnd_ref->class_id = g_strdup(class_id);
79 /* perform class specific initialization */
80 va_start(ap, class_id);
81 cnd = (cls->constr_func)(cnd_ref, ap);
84 /* check for successful construction */
92 void cnd_delete(condition *cnd) {
93 _cnd_class *cls = NULL;
95 /* check for valid pointer */
99 class_id = cnd->class_id;
100 /* check if hash table is already initialized */
102 /* get the condition class */
103 cls = (_cnd_class *)g_hash_table_lookup(classes, class_id);
104 /* call class specific destructor */
106 (cls->destr_func)(cnd);
108 g_free(cnd->class_id);
109 /* free basic structure */
111 } /* END cnd_delete() */
113 gboolean cnd_eval(condition *cnd, ...) {
115 gboolean ret_val = FALSE;
119 /* call specific handler */
121 ret_val = (cnd->eval_func)(cnd, ap);
124 } /* END cnd_eval() */
126 void cnd_reset(condition *cnd) {
128 (cnd->reset_func)(cnd);
129 } /* END cnd_reset() */
131 void* cnd_get_user_data(condition *cnd) {
132 return cnd->user_data;
133 } /* END cnd_get_user_data() */
135 void cnd_set_user_data(condition *cnd, void *user_data) {
136 cnd->user_data = user_data;
137 } /* END cnd_set_user_data() */
139 gboolean cnd_register_class(const char *class_id,
140 _cnd_constr constr_func,
141 _cnd_destr destr_func,
143 _cnd_reset reset_func) {
145 _cnd_class *cls = NULL;
146 /* check for valid parameters */
147 if ((constr_func == NULL) || (destr_func == NULL) ||
148 (eval_func == NULL) || (reset_func == NULL) || (class_id == NULL))
150 /* check if hash table is already initialized */
152 /* check for unique class id */
153 if (g_hash_table_lookup(classes, class_id) != NULL) {
154 g_warning("cnd_register_class: Duplicate class ID \"%s\"", class_id);
157 /* GHashTable keys need to be persistent for the lifetime of the hash
158 table. Allocate memory and copy the class id which we use as key. */
159 key = g_strdup(class_id);
160 /* initialize class structure */
161 if ((cls = (_cnd_class*)g_malloc(sizeof(_cnd_class))) == NULL) {
165 cls->constr_func = constr_func;
166 cls->destr_func = destr_func;
167 cls->eval_func = eval_func;
168 cls->reset_func = reset_func;
169 /* insert new class */
170 g_hash_table_insert(classes, key, cls);
172 } /* END cnd_register_class() */
174 static char *pkey = NULL;
175 void cnd_unregister_class(const char* class_id) {
176 const char *key = (const char*)class_id;
177 _cnd_class *cls = NULL;
178 /* check if hash table is already initialized */
180 /* find the key for this class id and store it in 'pkey' */
181 g_hash_table_foreach(classes,
182 _cnd_find_hash_key_for_class_id,
184 /* find the class structure for this class id */
185 cls = (_cnd_class*)g_hash_table_lookup(classes, class_id);
186 /* remove constructor from hash table */
187 g_hash_table_remove(classes, class_id);
193 } /* END cnd_unregister_class() */
196 * Initialize hash table.
198 static void _cnd_init(void) {
201 /* create hash table, we use strings as keys */
202 classes = g_hash_table_new(g_str_hash, g_str_equal);
203 } /* END _cnd_init() */
206 * Callback for function 'g_hash_table_foreach()'.
207 * We don't keep references to hash table keys. Keys have memory allocated
208 * which must be freed when they are not used anymore. This function finds
209 * the reference to a key corresponding to a particular class id. The reference
210 * to the key is stored in a global variable.
212 void _cnd_find_hash_key_for_class_id(gpointer key,
214 gpointer user_data) {
215 char *class_id = (char *)user_data;
216 char *key_value = (char *)key;
217 if (strcmp(class_id, key_value) == 0)
219 } /* END _cnd_find_hash_key_for_class_id() */
227 * indent-tabs-mode: nil
230 * ex: set shiftwidth=2 tabstop=8 expandtab:
231 * :indentSize=2:tabSize=8:noTabs=true: