2 * Implementation for condition handler.
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "conditions.h"
17 #include "ws_attributes.h"
19 /* container for condition classes */
20 static GHashTable *classes = NULL;
22 /* condition data structure declaration */
27 _cnd_reset reset_func;
30 /* structure used to store class functions in GHashTable */
31 typedef struct _cnd_class{
32 _cnd_constr constr_func;
33 _cnd_destr destr_func;
35 _cnd_reset reset_func;
38 /* helper function prototypes */
39 static void _cnd_init(void);
40 static void _cnd_find_hash_key_for_class_id(gpointer, gpointer, gpointer);
42 condition *cnd_new(const char *class_id, ...) {
44 condition *cnd = NULL;
45 condition *cnd_ref = NULL;
46 _cnd_class *cls = NULL;
49 /* check if hash table is already initialized */
52 /* get class structure for this id */
53 if ((cls = (_cnd_class *)g_hash_table_lookup(classes, class_id)) == NULL) {
54 g_warning("cnd_new: Couldn't find class ID \"%s\"", class_id);
58 /* initialize the basic structure */
59 if ((cnd_ref = (condition *)g_malloc(sizeof(condition))) == NULL)
61 cnd_ref->user_data = NULL;
62 cnd_ref->eval_func = cls->eval_func;
63 cnd_ref->reset_func = cls->reset_func;
65 cnd_ref->class_id = g_strdup(class_id);
67 /* perform class specific initialization */
68 va_start(ap, class_id);
69 cnd = (cls->constr_func)(cnd_ref, ap);
72 /* check for successful construction */
80 void cnd_delete(condition *cnd) {
81 _cnd_class *cls = NULL;
83 /* check for valid pointer */
87 class_id = cnd->class_id;
88 /* check if hash table is already initialized */
90 /* get the condition class */
91 cls = (_cnd_class *)g_hash_table_lookup(classes, class_id);
92 /* call class specific destructor */
94 (cls->destr_func)(cnd);
96 g_free(cnd->class_id);
97 /* free basic structure */
99 } /* END cnd_delete() */
101 gboolean cnd_eval(condition *cnd, ...) {
103 gboolean ret_val = FALSE;
107 /* call specific handler */
109 ret_val = (cnd->eval_func)(cnd, ap);
112 } /* END cnd_eval() */
114 void cnd_reset(condition *cnd) {
116 (cnd->reset_func)(cnd);
117 } /* END cnd_reset() */
119 void* cnd_get_user_data(condition *cnd) {
120 return cnd->user_data;
121 } /* END cnd_get_user_data() */
123 void cnd_set_user_data(condition *cnd, void *user_data) {
124 cnd->user_data = user_data;
125 } /* END cnd_set_user_data() */
127 gboolean cnd_register_class(const char *class_id,
128 _cnd_constr constr_func,
129 _cnd_destr destr_func,
131 _cnd_reset reset_func) {
133 _cnd_class *cls = NULL;
134 /* check for valid parameters */
135 if ((constr_func == NULL) || (destr_func == NULL) ||
136 (eval_func == NULL) || (reset_func == NULL) || (class_id == NULL))
138 /* check if hash table is already initialized */
140 /* check for unique class id */
141 if (g_hash_table_lookup(classes, class_id) != NULL) {
142 g_warning("cnd_register_class: Duplicate class ID \"%s\"", class_id);
145 /* GHashTable keys need to be persistent for the lifetime of the hash
146 table. Allocate memory and copy the class id which we use as key. */
147 key = g_strdup(class_id);
148 /* initialize class structure */
149 if ((cls = (_cnd_class*)g_malloc(sizeof(_cnd_class))) == NULL) {
153 cls->constr_func = constr_func;
154 cls->destr_func = destr_func;
155 cls->eval_func = eval_func;
156 cls->reset_func = reset_func;
157 /* insert new class */
158 g_hash_table_insert(classes, key, cls);
160 } /* END cnd_register_class() */
162 static char *pkey = NULL;
163 void cnd_unregister_class(const char* class_id) {
164 const char *key = (const char*)class_id;
165 _cnd_class *cls = NULL;
166 /* check if hash table is already initialized */
168 /* find the key for this class id and store it in 'pkey' */
169 g_hash_table_foreach(classes,
170 _cnd_find_hash_key_for_class_id,
172 /* find the class structure for this class id */
173 cls = (_cnd_class*)g_hash_table_lookup(classes, class_id);
174 /* remove constructor from hash table */
175 g_hash_table_remove(classes, class_id);
181 } /* END cnd_unregister_class() */
184 * Initialize hash table.
186 static void _cnd_init(void) {
189 /* create hash table, we use strings as keys */
190 classes = g_hash_table_new(g_str_hash, g_str_equal);
191 } /* END _cnd_init() */
194 * Callback for function 'g_hash_table_foreach()'.
195 * We don't keep references to hash table keys. Keys have memory allocated
196 * which must be freed when they are not used anymore. This function finds
197 * the reference to a key corresponding to a particular class id. The reference
198 * to the key is stored in a global variable.
200 void _cnd_find_hash_key_for_class_id(gpointer key,
202 gpointer user_data) {
203 char *class_id = (char *)user_data;
204 char *key_value = (char *)key;
205 if (strcmp(class_id, key_value) == 0)
207 } /* END _cnd_find_hash_key_for_class_id() */
215 * indent-tabs-mode: nil
218 * ex: set shiftwidth=2 tabstop=8 expandtab:
219 * :indentSize=2:tabSize=8:noTabs=true: