net-snmp 5.7
|
00001 /* Portions of this file are subject to the following copyright(s). See 00002 * the Net-SNMP's COPYING file for more details and other copyrights 00003 * that may apply: 00004 */ 00005 /* 00006 * Portions of this file are copyrighted by: 00007 * Copyright (C) 2007 Apple, Inc. All rights reserved. 00008 * Use is subject to license terms specified in the COPYING file 00009 * distributed with the Net-SNMP package. 00010 */ 00011 #ifndef NETSNMP_CONTAINER_H 00012 #define NETSNMP_CONTAINER_H 00013 00014 /* 00015 * $Id$ 00016 * 00017 * WARNING: This is a recently created file, and all of it's contents are 00018 * subject to change at any time. 00019 * 00020 * A basic container template. A generic way for code to store and 00021 * retrieve data. Allows for interchangable storage algorithms. 00022 */ 00023 #ifndef NET_SNMP_CONFIG_H 00024 #error "Please include <net-snmp/net-snmp-config.h> before this file" 00025 #endif 00026 00027 #include <stdlib.h> /* free() */ 00028 #include <net-snmp/types.h> 00029 #include <net-snmp/library/factory.h> 00030 #include <net-snmp/library/snmp_logging.h> 00031 #include <net-snmp/library/tools.h> 00032 00033 #ifdef __cplusplus 00034 extern "C" { 00035 #endif 00036 00037 /************************************************************************* 00038 * 00039 * function pointer definitions 00040 * 00041 *************************************************************************/ 00042 struct netsnmp_iterator_s; 00043 struct netsnmp_container_s; 00045 /* 00046 * function for performing an operation on a container which 00047 * returns (maybe the same) container. 00048 */ 00049 typedef struct netsnmp_container_s* (netsnmp_container_mod_op) 00050 (struct netsnmp_container_s *, void *context, u_int flags); 00051 00052 /* 00053 * function for setting an option on a container 00054 */ 00055 typedef int (netsnmp_container_option)(struct netsnmp_container_s *, 00056 int set, u_int flags); 00057 00058 /* 00059 * function returning an int for an operation on a container 00060 */ 00061 typedef int (netsnmp_container_rc)(struct netsnmp_container_s *); 00062 00063 /* 00064 * function returning an iterator for a container 00065 */ 00066 typedef struct netsnmp_iterator_s * (netsnmp_container_it) 00067 (struct netsnmp_container_s *); 00068 00069 /* 00070 * function returning a size_t for an operation on a container 00071 */ 00072 typedef size_t (netsnmp_container_size)(struct netsnmp_container_s *); 00073 00074 /* 00075 * function returning an int for an operation on an object and 00076 * a container 00077 */ 00078 typedef int (netsnmp_container_op)(struct netsnmp_container_s *, 00079 const void *data); 00080 00081 /* 00082 * function returning an oject for an operation on an object and a 00083 * container 00084 */ 00085 typedef void * (netsnmp_container_rtn)(struct netsnmp_container_s *, 00086 const void *data); 00087 00088 /* 00089 * function with no return which acts on an object 00090 */ 00091 typedef void (netsnmp_container_obj_func)(void *data, void *context); 00092 00093 /* 00094 * function with no return which calls a function on an object 00095 */ 00096 typedef void (netsnmp_container_func)(struct netsnmp_container_s *, 00097 netsnmp_container_obj_func *, 00098 void *context); 00099 00100 /* 00101 * function returning an array of objects for an operation on an 00102 * ojbect and a container 00103 */ 00104 typedef netsnmp_void_array * (netsnmp_container_set) 00105 (struct netsnmp_container_s *, void *data); 00106 00107 /* 00108 * function returning an int for a comparison between two objects 00109 */ 00110 typedef int (netsnmp_container_compare)(const void *lhs, 00111 const void *rhs); 00112 00113 /************************************************************************* 00114 * 00115 * Basic container 00116 * 00117 *************************************************************************/ 00118 typedef struct netsnmp_container_s { 00119 00120 /* 00121 * pointer for container implementation 00122 */ 00123 void * container_data; 00124 00125 /* 00126 * returns the number of items in a container 00127 */ 00128 netsnmp_container_size *get_size; 00129 00130 /* 00131 * initialize a container 00132 */ 00133 netsnmp_container_rc *init; 00134 00135 /* 00136 * release memory used by a container. 00137 * 00138 * Note: if your data structures contained allocated 00139 * memory, you are responsible for releasing that 00140 * memory before calling this function! 00141 */ 00142 netsnmp_container_rc *cfree; 00143 00144 /* 00145 * add an entry to the container 00146 */ 00147 netsnmp_container_op *insert; 00148 00149 /* 00150 * remove an entry from the container 00151 */ 00152 netsnmp_container_op *remove; 00153 00154 /* 00155 * release memory for an entry from the container 00156 */ 00157 netsnmp_container_op *release; /* NOTE: deprecated. Use free_item */ 00158 netsnmp_container_obj_func *free_item; 00159 00160 /* 00161 * find the entry in the container with the same key 00162 * 00163 * Note: do not change the key! If you need to 00164 * change a key, remove the entry, change the key, 00165 * and the re-add the entry. 00166 */ 00167 netsnmp_container_rtn *find; 00168 00169 /* 00170 * find the entry in the container with the next highest key 00171 * 00172 * If the key is NULL, return the first item in the container. 00173 */ 00174 netsnmp_container_rtn *find_next; 00175 00176 /* 00177 * find all entries in the container which match the partial key 00178 * returns allocated memory (netsnmp_void_array). User is responsible 00179 * for releasing this memory (free(array->array), free(array)). 00180 * DO NOT FREE ELEMENTS OF THE ARRAY, because they are the same pointers 00181 * stored in the container. 00182 */ 00183 netsnmp_container_set *get_subset; 00184 00185 /* 00186 * function to return an iterator for the container 00187 */ 00188 netsnmp_container_it *get_iterator; 00189 00190 /* 00191 * function to call another function for each object in the container 00192 */ 00193 netsnmp_container_func *for_each; 00194 00195 /* 00196 * specialized version of for_each used to optimize cleanup. 00197 * clear the container, optionally calling a function for each item. 00198 */ 00199 netsnmp_container_func *clear; 00200 00201 /* 00202 * OPTIONAL function to filter inserts to the container 00203 * (intended for a secondary container, which only wants 00204 * a sub-set of the objects in the primary/parent container) 00205 * Returns: 00206 * 1 : filter matched (don't insert) 00207 * 0 : no match (insert) 00208 */ 00209 netsnmp_container_op *insert_filter; 00210 00211 /* 00212 * OPTIONAL function to duplicate a container. Defaults to a shallow 00213 * copy. Only the specified container is copied (i.e. sub-containers 00214 * not included). 00215 */ 00216 netsnmp_container_mod_op *duplicate; 00217 00218 00219 /* 00220 * function to compare two object stored in the container. 00221 * 00222 * Returns: 00223 * 00224 * -1 LHS < RHS 00225 * 0 LHS = RHS 00226 * 1 LHS > RHS 00227 */ 00228 netsnmp_container_compare *compare; 00229 00230 /* 00231 * same as compare, but RHS will be a partial key 00232 */ 00233 netsnmp_container_compare *ncompare; 00234 00235 /* 00236 * function to set container options 00237 */ 00238 netsnmp_container_option *options; 00239 00240 /* 00241 * unique name for finding a particular container in a list 00242 */ 00243 char *container_name; 00244 00245 /* 00246 * sort count, for iterators to track (insert/delete 00247 * bumps counter, invalidates iterator) 00248 */ 00249 u_long sync; 00250 00251 /* 00252 * flags 00253 */ 00254 u_int flags; 00255 00256 /* 00257 * containers can contain other containers (additional indexes) 00258 */ 00259 struct netsnmp_container_s *next, *prev; 00260 00261 } netsnmp_container; 00262 00263 /* 00264 * initialize/free a container of container factories. used by 00265 * netsnmp_container_find* functions. 00266 */ 00267 NETSNMP_IMPORT 00268 void netsnmp_container_init_list(void); 00269 NETSNMP_IMPORT 00270 void netsnmp_container_free_list(void); 00271 00272 /* 00273 * register a new container factory 00274 */ 00275 int netsnmp_container_register_with_compare(const char* name, 00276 netsnmp_factory *f, 00277 netsnmp_container_compare *c); 00278 int netsnmp_container_register(const char* name, netsnmp_factory *f); 00279 00280 /* 00281 * search for and create a container from a list of types or a 00282 * specific type. 00283 */ 00284 NETSNMP_IMPORT 00285 netsnmp_container * netsnmp_container_find(const char *type_list); 00286 netsnmp_container * netsnmp_container_get(const char *type); 00287 00288 /* 00289 * utility routines 00290 */ 00291 NETSNMP_IMPORT 00292 void netsnmp_container_add_index(netsnmp_container *primary, 00293 netsnmp_container *new_index); 00294 00295 00296 netsnmp_factory *netsnmp_container_get_factory(const char *type); 00297 00298 /* 00299 * common comparison routines 00300 */ 00302 NETSNMP_IMPORT 00303 int netsnmp_compare_netsnmp_index(const void *lhs, const void *rhs); 00304 NETSNMP_IMPORT 00305 int netsnmp_ncompare_netsnmp_index(const void *lhs, const void *rhs); 00306 00308 int netsnmp_compare_cstring(const void * lhs, const void * rhs); 00309 int netsnmp_ncompare_cstring(const void * lhs, const void * rhs); 00310 00312 int netsnmp_compare_mem(const char * lhs, size_t lhs_len, 00313 const char * rhs, size_t rhs_len); 00314 00316 int netsnmp_compare_direct_cstring(const void * lhs, const void * rhs); 00317 00318 int netsnmp_compare_long(const void * lhs, const void * rhs); 00319 int netsnmp_compare_ulong(const void * lhs, const void * rhs); 00320 int netsnmp_compare_int32(const void * lhs, const void * rhs); 00321 int netsnmp_compare_uint32(const void * lhs, const void * rhs); 00322 00324 NETSNMP_IMPORT 00325 void netsnmp_container_simple_free(void *data, void *context); 00326 00327 /* 00328 * container optionflags 00329 */ 00330 #define CONTAINER_KEY_ALLOW_DUPLICATES 0x00000001 00331 #define CONTAINER_KEY_UNSORTED 0x00000002 00332 00333 #define CONTAINER_SET_OPTIONS(x,o,rc) do { \ 00334 if (NULL==(x)->options) \ 00335 rc = -1; \ 00336 else { \ 00337 rc = (x)->options(x, 1, o); \ 00338 if (rc != -1 ) \ 00339 (x)->flags |= o; \ 00340 } \ 00341 } while(0) 00342 00343 #define CONTAINER_CHECK_OPTION(x,o,rc) do { \ 00344 rc = x->flags & 0; \ 00345 } while(0) 00346 00347 00348 /* 00349 * useful macros (x = container; k = key; c = user context) 00350 */ 00351 #define CONTAINER_FIRST(x) (x)->find_next(x,NULL) 00352 #define CONTAINER_FIND(x,k) (x)->find(x,k) 00353 #define CONTAINER_NEXT(x,k) (x)->find_next(x,k) 00354 /* 00355 * GET_SUBSET returns allocated memory (netsnmp_void_array). User is responsible 00356 * for releasing this memory (free(array->array), free(array)). 00357 * DO NOT FREE ELEMENTS OF THE ARRAY, because they are the same pointers 00358 * stored in the container. 00359 */ 00360 #define CONTAINER_GET_SUBSET(x,k) (x)->get_subset(x,k) 00361 #define CONTAINER_SIZE(x) (x)->get_size(x) 00362 #define CONTAINER_ITERATOR(x) (x)->get_iterator(x) 00363 #define CONTAINER_COMPARE(x,l,r) (x)->compare(l,r) 00364 #define CONTAINER_FOR_EACH(x,f,c) (x)->for_each(x,f,c) 00365 00366 /* 00367 * if you are getting multiple definitions of these three 00368 * inline functions, you most likely have optimizations turned off. 00369 * Either turn them back on, or define NETSNMP_NO_INLINE 00370 */ 00371 /* 00372 * insert k into all containers 00373 */ 00374 NETSNMP_IMPORT 00375 int CONTAINER_INSERT(netsnmp_container *x, const void *k); 00376 00377 /* 00378 * remove k from all containers 00379 */ 00380 NETSNMP_IMPORT 00381 int CONTAINER_REMOVE(netsnmp_container *x, const void *k); 00382 00383 /* 00384 * duplicate container 00385 */ 00386 NETSNMP_IMPORT 00387 netsnmp_container *CONTAINER_DUP(netsnmp_container *x, void *ctx, 00388 u_int flags); 00389 00390 /* 00391 * clear all containers. When clearing the *first* container, and 00392 * *only* the first container, call the function f for each item. 00393 * After calling this function, all containers should be empty. 00394 */ 00395 NETSNMP_IMPORT 00396 void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f, 00397 void *c); 00398 00399 /* 00400 * clear all containers. When clearing the *first* container, and 00401 * *only* the first container, call the free_item function for each item. 00402 * After calling this function, all containers should be empty. 00403 */ 00404 NETSNMP_IMPORT 00405 void CONTAINER_FREE_ALL(netsnmp_container *x, void *c); 00406 00407 /* 00408 * free all containers 00409 */ 00410 NETSNMP_IMPORT 00411 int CONTAINER_FREE(netsnmp_container *x); 00412 00413 NETSNMP_IMPORT 00414 netsnmp_container *SUBCONTAINER_FIND(netsnmp_container *x, 00415 const char* name); 00416 00417 /* 00418 * INTERNAL utility routines for container implementations 00419 */ 00420 void netsnmp_init_container(netsnmp_container *c, 00421 netsnmp_container_rc *init, 00422 netsnmp_container_rc *cfree, 00423 netsnmp_container_size *size, 00424 netsnmp_container_compare *cmp, 00425 netsnmp_container_op *ins, 00426 netsnmp_container_op *rem, 00427 netsnmp_container_rtn *fnd); 00429 int netsnmp_container_data_dup(netsnmp_container *dup, 00430 netsnmp_container *c); 00431 00432 00433 /************************************************************************* 00434 * 00435 * container iterator 00436 * 00437 *************************************************************************/ 00438 /* 00439 * function returning an int for an operation on an iterator 00440 */ 00441 typedef int (netsnmp_iterator_rc)(struct netsnmp_iterator_s *); 00442 00443 /* 00444 * function returning an oject for an operation on an iterator 00445 */ 00446 typedef void * (netsnmp_iterator_rtn)(struct netsnmp_iterator_s *); 00447 00448 00449 /* 00450 * iterator structure 00451 */ 00452 typedef struct netsnmp_iterator_s { 00453 00454 netsnmp_container *container; 00455 00456 /* 00457 * sync from container when iterator created. used to invalidate 00458 * the iterator when the container changes. 00459 */ 00460 u_long sync; 00461 00462 /* 00463 * reset iterator position to beginning of container. 00464 */ 00465 netsnmp_iterator_rc *reset; 00466 00467 /* 00468 * release iterator and memory it uses 00469 */ 00470 netsnmp_iterator_rc *release; 00471 00472 /* 00473 * first, last and current DO NOT advance the iterator 00474 */ 00475 netsnmp_iterator_rtn *first; 00476 netsnmp_iterator_rtn *curr; 00477 netsnmp_iterator_rtn *last; 00478 00479 netsnmp_iterator_rtn *next; 00480 00481 /* 00482 * remove will remove the item at the current position, then back up 00483 * the iterator to the previous item. That way next will move to the 00484 * item (the one that replaced the removed item. 00485 */ 00486 netsnmp_iterator_rc *remove; 00487 00488 } netsnmp_iterator; 00489 00490 00491 #define ITERATOR_FIRST(x) x->first(x) 00492 #define ITERATOR_NEXT(x) x->next(x) 00493 #define ITERATOR_LAST(x) x->last(x) 00494 #define ITERATOR_REMOVE(x) x->remove(x) 00495 #define ITERATOR_RELEASE(x) do { x->release(x); x = NULL; } while(0) 00496 00497 #ifdef __cplusplus 00498 } 00499 #endif 00500 00501 #endif