2 * Implementation for condition handler.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include "conditions.h"
30 /* container for condition classes */
31 static GHashTable* classes = NULL;
33 /* condition data structure declaration */
38 _cnd_reset reset_func;
41 /* structure used to store class functions in GHashTable */
42 typedef struct _cnd_class{
43 _cnd_constr constr_func;
44 _cnd_destr destr_func;
46 _cnd_reset reset_func;
49 /* helper function prototypes */
50 static void _cnd_init(void);
51 static void _cnd_find_hash_key_for_class_id(gpointer, gpointer, gpointer);
53 condition* cnd_new(const char* class_id, ...){
55 condition *cnd = NULL, *cnd_ref = NULL;
56 _cnd_class *cls = NULL;
58 /* check if hash table is already initialized */
60 /* get class structure for this id */
61 if((cls = (_cnd_class*)g_hash_table_lookup(classes, class_id)) == NULL)
63 /* initialize the basic structure */
64 if((cnd_ref = (condition*)g_malloc(sizeof(condition))) == NULL) return NULL;
65 cnd_ref->user_data = NULL;
66 cnd_ref->eval_func = cls->eval_func;
67 cnd_ref->reset_func = cls->reset_func;
68 /* copy the class id */
69 if((id = (char*)g_malloc(strlen(class_id)+1)) == NULL){
74 cnd_ref->class_id = id;
75 /* perform class specific initialization */
76 va_start(ap, class_id);
77 cnd = (cls->constr_func)(cnd_ref, ap);
79 /* check for successful construction */
87 void cnd_delete(condition *cnd){
88 _cnd_class *cls = NULL;
90 /* check for valid pointer */
91 if(cnd == NULL) return;
93 class_id = cnd->class_id;
94 /* check if hash table is already initialized */
96 /* get the condition class */
97 cls = (_cnd_class*)g_hash_table_lookup(classes, class_id);
98 /* call class specific destructor */
99 if(cls != NULL) (cls->destr_func)(cnd);
101 g_free(cnd->class_id);
102 /* free basic structure */
104 } /* END cnd_delete() */
106 gboolean cnd_eval(condition *cnd, ...){
108 gboolean ret_val = FALSE;
110 if(cnd == NULL) return FALSE;
111 /* call specific handler */
113 ret_val = (cnd->eval_func)(cnd, ap);
116 } /* END cnd_eval() */
118 void cnd_reset(condition *cnd){
119 if(cnd != NULL) (cnd->reset_func)(cnd);
120 } /* END cnd_reset() */
122 void* cnd_get_user_data(condition *cnd){
123 return cnd->user_data;
124 } /* END cnd_get_user_data() */
126 void cnd_set_user_data(condition *cnd, void* user_data){
127 cnd->user_data = user_data;
128 } /* END cnd_set_user_data() */
130 gboolean cnd_register_class(const char* class_id,
131 _cnd_constr constr_func,
132 _cnd_destr destr_func,
134 _cnd_reset reset_func){
136 _cnd_class *cls = NULL;
137 /* check for valid parameters */
138 if((constr_func == NULL) || (destr_func == NULL) ||
139 (eval_func == NULL) || (reset_func == NULL) || (class_id == NULL))
141 /* check if hash table is already initialized */
143 /* check for unique class id */
144 if((cls = (_cnd_class*)g_hash_table_lookup(classes, class_id)) != NULL)
146 /* GHashTable keys need to be persistent for the lifetime of the hash
147 table. Allocate memory and copy the class id which we use as key. */
148 if((key = (char*)g_malloc(strlen(class_id)+1)) == NULL) return FALSE;
149 strcpy(key, class_id);
150 /* initialize class structure */
151 if((cls = (_cnd_class*)g_malloc(sizeof(_cnd_class))) == NULL){
155 cls->constr_func = constr_func;
156 cls->destr_func = destr_func;
157 cls->eval_func = eval_func;
158 cls->reset_func = reset_func;
159 /* insert new class */
160 g_hash_table_insert(classes, key, cls);
162 } /* END cnd_register_class() */
164 static char* pkey = NULL;
165 void cnd_unregister_class(const char* class_id){
166 const char *key = (const char*)class_id;
167 _cnd_class *cls = NULL;
168 /* check if hash table is already initialized */
170 /* find the key for this class id and store it in 'pkey' */
171 g_hash_table_foreach(classes,
172 _cnd_find_hash_key_for_class_id,
174 /* find the class structure for this class id */
175 cls = (_cnd_class*)g_hash_table_lookup(classes, class_id);
176 /* remove constructor from hash table */
177 g_hash_table_remove(classes, class_id);
183 } /* END cnd_unregister_class() */
186 * Initialize hash table.
188 static void _cnd_init(void){
189 if(classes != NULL) return;
190 /* create hash table, we use strings as keys */
191 classes = g_hash_table_new(g_str_hash, g_str_equal);
192 } /* END _cnd_init() */
195 * Callback for function 'g_hash_table_foreach()'.
196 * We don't keep references to hash table keys. Keys have memory allocated
197 * which must be freed when they are not used anymore. This function finds
198 * the reference to a key corresponding to a particular class id. The reference
199 * to the key is stored in a global variable.
201 void _cnd_find_hash_key_for_class_id(gpointer key,
204 char* class_id = (char*)user_data;
205 char* key_value = (char*)key;
206 if(strcmp(class_id, key_value) == 0) pkey = key;
207 } /* END _cnd_find_hash_key_for_class_id() */