1 #ifndef NETSNMP_CONTAINER_H
2 #define NETSNMP_CONTAINER_H
5 * WARNING: This is a recently created file, and all of it's contents are
6 * subject to change at any time.
8 * A basic container template. A generic way for code to store and
9 * retrieve data. Allows for interchangable storage algorithms.
11 #ifndef NET_SNMP_CONFIG_H
12 #error "Please include <net-snmp/net-snmp-config.h> before this file"
15 #include <net-snmp/types.h>
16 #include <net-snmp/library/factory.h>
22 /*************************************************************************
24 * function pointer definitions
26 *************************************************************************/
27 struct netsnmp_iterator_s
; /** forward declare */
28 struct netsnmp_container_s
; /** forward declare */
31 * function returning an int for an operation on a container
33 typedef int (netsnmp_container_rc
)(struct netsnmp_container_s
*);
36 * function returning an int for an operation on a container
38 typedef struct netsnmp_iterator_s
* (netsnmp_container_it
)
39 (struct netsnmp_container_s
*);
42 * function returning a size_t for an operation on a container
44 typedef size_t (netsnmp_container_size
)(struct netsnmp_container_s
*);
47 * function returning an int for an operation on an object and
50 typedef int (netsnmp_container_op
)(struct netsnmp_container_s
*,
54 * function returning an oject for an operation on an object and a
57 typedef void * (netsnmp_container_rtn
)(struct netsnmp_container_s
*,
61 * function with no return which acts on an object
63 typedef void (netsnmp_container_obj_func
)(void *data
, void *context
);
66 * function with no return which acts on an object
68 typedef void (netsnmp_container_func
)(struct netsnmp_container_s
*,
69 netsnmp_container_obj_func
*,
73 * function returning an array of objects for an operation on an
74 * ojbect and a container
76 typedef netsnmp_void_array
* (netsnmp_container_set
)
77 (struct netsnmp_container_s
*, void *data
);
80 * function returning an int for a comparison between two objects
82 typedef int (netsnmp_container_compare
)(const void *lhs
,
85 /*************************************************************************
89 *************************************************************************/
90 typedef struct netsnmp_container_s
{
93 * pointer for container
98 * returns the number of items in a container
100 netsnmp_container_size
*get_size
;
103 * initialize a container
105 netsnmp_container_rc
*init
;
108 * release memory used by a container.
110 * Note: if your data structures contained allcoated
111 * memory, you are responsible for releasing that
112 * memory before calling this function!
114 netsnmp_container_rc
*cfree
;
117 * add an entry to the container
119 netsnmp_container_op
*insert
;
122 * remove an entry from the container
124 netsnmp_container_op
*remove
;
127 * Note: do not change the key! If you need to
128 * change a key, remove the entry, change the key,
129 * and the re-add the entry.
133 * find the entry in the container with the same key
136 netsnmp_container_rtn
*find
;
139 * find the first entry in the container with a key greater than
142 * If the key is NULL, return the first item in the container.
144 netsnmp_container_rtn
*find_next
;
147 * find all entries iin the container which match the partial key
149 netsnmp_container_set
*get_subset
;
152 * function to return an iterator for the container
154 struct netsnmp_container_it
*get_iterator
;
157 * function to call another function for each object in the container
159 netsnmp_container_func
*for_each
;
162 * function to compare two object stored in the container.
170 netsnmp_container_compare
*compare
;
173 * same as compare, but RHS will be a partial key
175 netsnmp_container_compare
*ncompare
;
178 * containers can contain other containers (additional indexes)
180 struct netsnmp_container_s
*next
, *prev
;
185 * initialize a container of container factories. used by
186 * netsnmp_container_find* functions.
188 void netsnmp_container_init_list(void);
191 * register a new container factory
193 int netsnmp_container_register(const char* name
, netsnmp_factory
*f
);
196 * search for and create a container from a list of types or a
199 netsnmp_container
* netsnmp_container_find(const char *type_list
);
200 netsnmp_container
* netsnmp_container_get(const char *type
);
203 * search for and create a container from a list of types or a
204 * specific type, using the provided container structure
206 int netsnmp_container_find_noalloc(const char *type_list
,
207 netsnmp_container
* c
);
208 int netsnmp_container_get_noalloc(const char *type
, netsnmp_container
* c
);
213 void netsnmp_container_add_index(netsnmp_container
*primary
,
214 netsnmp_container
*new_index
);
218 * commone comparison routines
220 /** first data element is a 'netsnmp_index' */
221 int netsnmp_compare_netsnmp_index(const void *lhs
, const void *rhs
);
222 int netsnmp_ncompare_netsnmp_index(const void *lhs
, const void *rhs
);
224 /** first data element is a 'char *' */
225 int netsnmp_compare_cstring(const void * lhs
, const void * rhs
);
226 int netsnmp_ncompare_cstring(const void * lhs
, const void * rhs
);
228 /** useful for octet strings */
229 int netsnmp_compare_mem(const char * lhs
, size_t lhs_len
,
230 const char * rhs
, size_t rhs_len
);
236 #define CONTAINER_FIRST(x) (x)->find(x,NULL)
237 #define CONTAINER_FIND(x,k) (x)->find(x,k)
238 #define CONTAINER_NEXT(x,k) (x)->find_next(x,k)
239 #define CONTAINER_GET_SUBSET(x,k) (x)->get_subset(x,k)
240 #define CONTAINER_SIZE(x) (x)->get_size(x)
241 #define CONTAINER_ITERATOR(x) (x)->get_iterator(x)
242 #define CONTAINER_COMPARE(x,l,r) (x)->compare(l,r)
243 #define CONTAINER_FOR_EACH(x,f,c) (x)->for_each(x,f,c)
246 * if you are getting multiple definitions of these three
247 * inline functions, you most likely have optimizations turned off for your
248 * compiler (-O flag). Either turn them back on, or make sure that
249 * NETSNMP_INLINE is not defined in net-snmp-config.h.
251 #ifdef NETSNMP_NO_INLINE
252 int CONTAINER_INSERT(netsnmp_container
*x
, const void *k
);
253 int CONTAINER_REMOVE(netsnmp_container
*x
, const void *k
);
254 int CONTAINER_FREE(netsnmp_container
*x
);
256 /*------------------------------------------------------------------
257 * These functions should EXACTLY match the function version in
258 * container.c. If you change one, change them both.
260 static NETSNMP_INLINE
/* gcc docs recommend static w/inline */
261 int CONTAINER_INSERT(netsnmp_container
*x
, const void *k
)
266 if (NULL
!= x
->next
) {
267 netsnmp_container
*tmp
= x
->next
;
270 rc2
= tmp
->insert(tmp
,k
);
272 snmp_log(LOG_ERR
,"error on subcontainer insert (%d)\n", rc2
);
279 /*------------------------------------------------------------------
280 * These functions should EXACTLY match the function version in
281 * container.c. If you change one, change them both.
283 static NETSNMP_INLINE
/* gcc docs recommend static w/inline */
284 int CONTAINER_REMOVE(netsnmp_container
*x
, const void *k
)
286 if (NULL
!= x
->next
) {
287 netsnmp_container
*tmp
= x
->next
;
292 rc
= tmp
->remove(tmp
,k
);
294 snmp_log(LOG_ERR
,"error on subcontainer remove (%d)\n", rc
);
298 return x
->remove(x
,k
);
301 /*------------------------------------------------------------------
302 * These functions should EXACTLY match the function version in
303 * container.c. If you change one, change them both.
305 static NETSNMP_INLINE
/* gcc docs recommend static w/inline */
306 int CONTAINER_FREE(netsnmp_container
*x
)
308 if (NULL
!= x
->next
) {
309 netsnmp_container
*prev
, *tmp
= x
->next
;
315 rc
= tmp
->cfree(tmp
);
317 snmp_log(LOG_ERR
,"error on subcontainer cfree (%d)\n", rc
);
325 /*************************************************************************
329 *************************************************************************/
331 * function returning an int for an operation on an iterator
333 typedef int (netsnmp_iterator_rc
)(struct netsnmp_iterator_s
*);
336 * function returning an int for an operation on an iterator and
337 * an object in the container.
339 typedef int (netsnmp_iterator_rc_op
)(struct netsnmp_iterator_s
*,
343 * function returning an oject for an operation on an iterator
345 typedef void * (netsnmp_iterator_rtn
)(struct netsnmp_iterator_s
*);
347 typedef struct netsnmp_iterator_s
{
349 netsnmp_container
*container
;
353 netsnmp_iterator_rc
*init
;
354 netsnmp_iterator_rc_op
*position
;
355 netsnmp_iterator_rtn
*first
;
356 netsnmp_iterator_rtn
*next
;
357 netsnmp_iterator_rtn
*last
;
362 #define ITERATOR_FIRST(x) x->first(x)
363 #define ITERATOR_NEXT(x) x->next(x)
364 #define ITERATOR_LAST(x) x->last(x)
367 /*************************************************************************
371 *************************************************************************/
372 typedef struct netsnmp_sorted_container_s
{
374 netsnmp_container bc
;
377 * methods to manipulate container
380 netsnmp_container_rtn
*first
;
381 netsnmp_container_rtn
*next
;
382 netsnmp_container_set
*subset
;
384 } netsnmp_sorted_container
;
388 netsnmp_init_sorted_container(netsnmp_sorted_container
*sc
,
389 netsnmp_container_rtn
*first
,
390 netsnmp_container_rtn
*next
,
391 netsnmp_container_set
*subset
);
399 #endif /** NETSNMP_CONTAINER_H */