and added files
[bcm963xx.git] / userapps / opensource / net-snmp / include / net-snmp / library / container.h
1 #ifndef NETSNMP_CONTAINER_H
2 #define NETSNMP_CONTAINER_H
3
4 /*
5  * WARNING: This is a recently created file, and all of it's contents are
6  *          subject to change at any time.
7  *
8  * A basic container template. A generic way for code to store and
9  * retrieve data. Allows for interchangable storage algorithms.
10  */
11 #ifndef NET_SNMP_CONFIG_H
12 #error "Please include <net-snmp/net-snmp-config.h> before this file"
13 #endif
14
15 #include <net-snmp/types.h>
16 #include <net-snmp/library/factory.h>
17
18 #ifdef  __cplusplus
19 extern "C" {
20 #endif
21
22     /*************************************************************************
23      *
24      * function pointer definitions
25      *
26      *************************************************************************/
27     struct netsnmp_iterator_s; /** forward declare */
28     struct netsnmp_container_s; /** forward declare */
29
30     /*
31      * function returning an int for an operation on a container
32      */
33     typedef int (netsnmp_container_rc)(struct netsnmp_container_s *);
34
35     /*
36      * function returning an int for an operation on a container
37      */
38     typedef struct netsnmp_iterator_s * (netsnmp_container_it)
39         (struct netsnmp_container_s *);
40
41     /*
42      * function returning a size_t for an operation on a container
43      */
44     typedef size_t (netsnmp_container_size)(struct netsnmp_container_s *);
45
46     /*
47      * function returning an int for an operation on an object and
48      * a container
49      */
50     typedef int (netsnmp_container_op)(struct netsnmp_container_s *,
51                                        const void *data);
52
53     /*
54      * function returning an oject for an operation on an object and a
55      * container
56      */
57     typedef void * (netsnmp_container_rtn)(struct netsnmp_container_s *,
58                                            const void *data);
59
60     /*
61      * function with no return which acts on an object
62      */
63     typedef void (netsnmp_container_obj_func)(void *data, void *context);
64
65     /*
66      * function with no return which acts on an object
67      */
68     typedef void (netsnmp_container_func)(struct netsnmp_container_s *,
69                                           netsnmp_container_obj_func *,
70                                           void *context);
71
72     /*
73      * function returning an array of objects for an operation on an
74      * ojbect and a container
75      */
76     typedef netsnmp_void_array * (netsnmp_container_set)
77         (struct netsnmp_container_s *, void *data);
78
79     /*
80      * function returning an int for a comparison between two objects
81      */
82     typedef int (netsnmp_container_compare)(const void *lhs,
83                                             const void *rhs);
84
85     /*************************************************************************
86      *
87      * Basic container
88      *
89      *************************************************************************/
90     typedef struct netsnmp_container_s {
91        
92        /*
93         * pointer for container
94         */
95        void *         private;
96
97        /*
98         * returns the number of items in a container
99         */
100        netsnmp_container_size  *get_size;
101        
102        /*
103         * initialize a container
104         */
105        netsnmp_container_rc    *init;
106
107        /*
108         * release memory used by a container.
109         *
110         * Note: if your data structures contained allcoated
111         * memory, you are responsible for releasing that
112         * memory before calling this function!
113         */
114        netsnmp_container_rc    *cfree;
115
116        /*
117         * add an entry to the container
118         */
119        netsnmp_container_op    *insert;
120
121        /*
122         * remove an entry from the container
123         */
124        netsnmp_container_op    *remove;
125
126        /*
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.
130         */
131
132        /*
133         * find the entry in the container with the same key
134         *
135         */
136        netsnmp_container_rtn   *find;
137
138        /*
139         * find the first entry in the container with a key greater than
140         * the specified key.
141         *
142         * If the key is NULL, return the first item in the container.
143         */
144        netsnmp_container_rtn   *find_next;
145
146        /*
147         * find all entries iin the container which match the partial key
148         */
149        netsnmp_container_set            *get_subset;
150
151        /*
152         * function to return an iterator for the container
153         */
154        struct netsnmp_container_it    *get_iterator;
155
156        /*
157         * function to call another function for each object in the container
158         */
159        netsnmp_container_func         *for_each;
160
161        /*
162         * function to compare two object stored in the container.
163         *
164         * Returns:
165         *
166         *   -1  LHS < RHS
167         *    0  LHS = RHS
168         *    1  LHS > RHS
169         */
170        netsnmp_container_compare        *compare;
171
172        /*
173         * same as compare, but RHS will be a partial key
174         */
175        netsnmp_container_compare        *ncompare;
176
177        /*
178         * containers can contain other containers (additional indexes)
179         */
180        struct netsnmp_container_s *next, *prev;
181
182     } netsnmp_container;
183
184     /*
185      * initialize a container of container factories. used by
186      * netsnmp_container_find* functions.
187      */
188     void netsnmp_container_init_list(void);
189
190     /*
191      * register a new container factory
192      */
193     int netsnmp_container_register(const char* name, netsnmp_factory *f);
194
195     /*
196      * search for and create a container from a list of types or a
197      * specific type.
198      */
199     netsnmp_container * netsnmp_container_find(const char *type_list);
200     netsnmp_container * netsnmp_container_get(const char *type);
201
202     /*
203      * search for and create a container from a list of types or a
204      * specific type, using the provided container structure
205      */
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);
209
210     /*
211      * utility routines
212      */
213     void netsnmp_container_add_index(netsnmp_container *primary,
214                                      netsnmp_container *new_index);
215
216
217     /*
218      * commone comparison routines
219      */
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);
223
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);
227
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);
231
232
233     /*
234      * useful macros
235      */
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)
244
245     /*
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.
250      */
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);
255 #else
256     /*------------------------------------------------------------------
257      * These functions should EXACTLY match the function version in
258      * container.c. If you change one, change them both.
259      */
260     static NETSNMP_INLINE /* gcc docs recommend static w/inline */
261     int CONTAINER_INSERT(netsnmp_container *x, const void *k)
262     {
263         int rc;
264         
265         rc = x->insert(x,k);
266         if (NULL != x->next) {
267             netsnmp_container *tmp = x->next;
268             int                rc2;
269             while(tmp) {
270                 rc2 = tmp->insert(tmp,k);
271                 if (rc)
272                     snmp_log(LOG_ERR,"error on subcontainer insert (%d)", rc2);
273                 tmp = tmp->next;
274             }
275         }
276         return rc;
277     }
278     
279     /*------------------------------------------------------------------
280      * These functions should EXACTLY match the function version in
281      * container.c. If you change one, change them both.
282      */
283     static NETSNMP_INLINE /* gcc docs recommend static w/inline */
284     int CONTAINER_REMOVE(netsnmp_container *x, const void *k)
285     {
286         if (NULL != x->next) {
287             netsnmp_container *tmp = x->next;
288             int                rc;
289             while(tmp->next)
290                 tmp = tmp->next;
291             while(tmp) {
292                 rc = tmp->remove(tmp,k);
293                 if (rc)
294                     snmp_log(LOG_ERR,"error on subcontainer remove (%d)", rc);
295                 tmp = tmp->prev;
296             }
297         }
298         return x->remove(x,k);
299     }
300     
301     /*------------------------------------------------------------------
302      * These functions should EXACTLY match the function version in
303      * container.c. If you change one, change them both.
304      */
305     static NETSNMP_INLINE /* gcc docs recommend static w/inline */
306     int CONTAINER_FREE(netsnmp_container *x)
307     {
308         
309         if (NULL != x->next) {
310             netsnmp_container *tmp = x->next;
311             int                rc;
312             while(tmp->next)
313                 tmp = tmp->next;
314             while(tmp) {
315                 rc = tmp->cfree(tmp);
316                 if (rc)
317                     snmp_log(LOG_ERR,"error on subcontainer cfree (%d)", rc);
318                 tmp = tmp->prev;
319             }
320         }
321         return x->cfree(x);
322     }
323 #endif
324
325     /*************************************************************************
326      *
327      * container iterator
328      *
329      *************************************************************************/
330     /*
331      * function returning an int for an operation on an iterator
332      */
333     typedef int (netsnmp_iterator_rc)(struct netsnmp_iterator_s *);
334
335     /*
336      * function returning an int for an operation on an iterator and
337      * an object in the container.
338      */
339     typedef int (netsnmp_iterator_rc_op)(struct netsnmp_iterator_s *,
340                                          void *data);
341
342     /*
343      * function returning an oject for an operation on an iterator
344      */
345     typedef void * (netsnmp_iterator_rtn)(struct netsnmp_iterator_s *);
346
347     typedef struct netsnmp_iterator_s {
348
349        netsnmp_container              *container;
350
351        void                           *context;
352
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;
358
359     } netsnmp_iterator;
360
361
362 #define ITERATOR_FIRST(x)  x->first(x)
363 #define ITERATOR_NEXT(x)   x->next(x)
364 #define ITERATOR_LAST(x)   x->last(x)
365
366
367     /*************************************************************************
368      *
369      * Sorted container
370      *
371      *************************************************************************/
372     typedef struct netsnmp_sorted_container_s {
373        
374        netsnmp_container                bc;
375        
376        /*
377         * methods to manipulate container
378         */
379
380        netsnmp_container_rtn            *first;
381        netsnmp_container_rtn            *next;
382        netsnmp_container_set            *subset;
383        
384     } netsnmp_sorted_container;
385     
386
387     void
388     netsnmp_init_sorted_container(netsnmp_sorted_container  *sc,
389                                   netsnmp_container_rtn     *first,
390                                   netsnmp_container_rtn     *next,
391                                   netsnmp_container_set     *subset);
392     
393     
394     
395 #ifdef  __cplusplus
396 };
397 #endif
398
399 #endif /** NETSNMP_CONTAINER_H */