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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "conditions.h"
32 /* container for condition classes */
33 static GHashTable
* classes
= NULL
;
35 /* condition data structure declaration */
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
;
48 _cnd_reset reset_func
;
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
, ...){
57 condition
*cnd
= NULL
, *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
) 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
);
83 /* check for successful construction */
91 void cnd_delete(condition
*cnd
){
92 _cnd_class
*cls
= NULL
;
94 /* check for valid pointer */
95 if(cnd
== NULL
) return;
97 class_id
= cnd
->class_id
;
98 /* check if hash table is already initialized */
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
);
105 g_free(cnd
->class_id
);
106 /* free basic structure */
108 } /* END cnd_delete() */
110 gboolean
cnd_eval(condition
*cnd
, ...){
112 gboolean ret_val
= FALSE
;
114 if(cnd
== NULL
) return FALSE
;
115 /* call specific handler */
117 ret_val
= (cnd
->eval_func
)(cnd
, ap
);
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
,
138 _cnd_reset reset_func
){
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
))
145 /* check if hash table is already initialized */
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
);
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
){
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
);
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 */
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
,
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
);
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
,
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() */
220 * indent-tabs-mode: nil
223 * ex: set shiftwidth=2 tabstop=8 expandtab:
224 * :indentSize=2:tabSize=8:noTabs=true: