00001 #ifndef NETSNMP_CONTAINER_H
00002 #define NETSNMP_CONTAINER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef NET_SNMP_CONFIG_H
00014 #error "Please include <net-snmp/net-snmp-config.h> before this file"
00015 #endif
00016
00017 #include <net-snmp/types.h>
00018 #include <net-snmp/library/factory.h>
00019 #include <net-snmp/library/snmp_logging.h>
00020
00021 #ifdef __cplusplus
00022 extern "C" {
00023 #endif
00024
00025
00026
00027
00028
00029
00030 struct netsnmp_iterator_s;
00031 struct netsnmp_container_s;
00033
00034
00035
00036 typedef int (netsnmp_container_option)(struct netsnmp_container_s *,
00037 int set, u_int flags);
00038
00039
00040
00041
00042 typedef int (netsnmp_container_rc)(struct netsnmp_container_s *);
00043
00044
00045
00046
00047 typedef struct netsnmp_iterator_s * (netsnmp_container_it)
00048 (struct netsnmp_container_s *);
00049
00050
00051
00052
00053 typedef size_t (netsnmp_container_size)(struct netsnmp_container_s *);
00054
00055
00056
00057
00058
00059 typedef int (netsnmp_container_op)(struct netsnmp_container_s *,
00060 const void *data);
00061
00062
00063
00064
00065
00066 typedef void * (netsnmp_container_rtn)(struct netsnmp_container_s *,
00067 const void *data);
00068
00069
00070
00071
00072 typedef void (netsnmp_container_obj_func)(void *data, void *context);
00073
00074
00075
00076
00077 typedef void (netsnmp_container_func)(struct netsnmp_container_s *,
00078 netsnmp_container_obj_func *,
00079 void *context);
00080
00081
00082
00083
00084
00085 typedef netsnmp_void_array * (netsnmp_container_set)
00086 (struct netsnmp_container_s *, void *data);
00087
00088
00089
00090
00091 typedef int (netsnmp_container_compare)(const void *lhs,
00092 const void *rhs);
00093
00094
00095
00096
00097
00098
00099 typedef struct netsnmp_container_s {
00100
00101
00102
00103
00104 void * container_data;
00105
00106
00107
00108
00109 netsnmp_container_size *get_size;
00110
00111
00112
00113
00114 netsnmp_container_rc *init;
00115
00116
00117
00118
00119
00120
00121
00122
00123 netsnmp_container_rc *cfree;
00124
00125
00126
00127
00128 netsnmp_container_op *insert;
00129
00130
00131
00132
00133 netsnmp_container_op *remove;
00134
00135
00136
00137
00138 netsnmp_container_op *release;
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 netsnmp_container_rtn *find;
00151
00152
00153
00154
00155
00156
00157 netsnmp_container_rtn *find_next;
00158
00159
00160
00161
00162
00163
00164
00165
00166 netsnmp_container_set *get_subset;
00167
00168
00169
00170
00171 netsnmp_container_it *get_iterator;
00172
00173
00174
00175
00176 netsnmp_container_func *for_each;
00177
00178
00179
00180
00181
00182 netsnmp_container_func *clear;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 netsnmp_container_op *insert_filter;
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 netsnmp_container_compare *compare;
00204
00205
00206
00207
00208 netsnmp_container_compare *ncompare;
00209
00210
00211
00212
00213 netsnmp_container_option *options;
00214
00215
00216
00217
00218 char *container_name;
00219
00220
00221
00222
00223
00224 u_long sync;
00225
00226
00227
00228
00229 struct netsnmp_container_s *next, *prev;
00230
00231 } netsnmp_container;
00232
00233
00234
00235
00236
00237 void netsnmp_container_init_list(void);
00238 void netsnmp_container_free_list(void);
00239
00240
00241
00242
00243 int netsnmp_container_register_with_compare(const char* name,
00244 netsnmp_factory *f,
00245 netsnmp_container_compare *c);
00246 int netsnmp_container_register(const char* name, netsnmp_factory *f);
00247
00248
00249
00250
00251
00252 netsnmp_container * netsnmp_container_find(const char *type_list);
00253 netsnmp_container * netsnmp_container_get(const char *type);
00254
00255
00256
00257
00258 void netsnmp_container_add_index(netsnmp_container *primary,
00259 netsnmp_container *new_index);
00260
00261
00262 netsnmp_factory *netsnmp_container_get_factory(const char *type);
00263
00264
00265
00266
00268 int netsnmp_compare_netsnmp_index(const void *lhs, const void *rhs);
00269 int netsnmp_ncompare_netsnmp_index(const void *lhs, const void *rhs);
00270
00272 int netsnmp_compare_cstring(const void * lhs, const void * rhs);
00273 int netsnmp_ncompare_cstring(const void * lhs, const void * rhs);
00274
00276 int netsnmp_compare_mem(const char * lhs, size_t lhs_len,
00277 const char * rhs, size_t rhs_len);
00278
00280 void netsnmp_container_simple_free(void *data, void *context);
00281
00282
00283
00284
00285 #define CONTAINER_KEY_ALLOW_DUPLICATES 0x00000001
00286 #define CONTAINER_KEY_UNSORTED 0x00000002
00287
00288 #define CONTAINER_SET_OPTIONS(x,o,rc) do { \
00289 if (NULL==(x)->options) \
00290 rc = -1; \
00291 else \
00292 rc = (x)->options(x, 1, o); \
00293 } while(0)
00294
00295 #define CONTAINER_CHECK_OPTION(x,o,rc) do { \
00296 if (NULL==(x)->options) \
00297 rc = -1; \
00298 else \
00299 rc = (x)->options(x,0, o); \
00300 } while(0)
00301
00302
00303
00304
00305
00306 #define CONTAINER_FIRST(x) (x)->find_next(x,NULL)
00307 #define CONTAINER_FIND(x,k) (x)->find(x,k)
00308 #define CONTAINER_NEXT(x,k) (x)->find_next(x,k)
00309
00310
00311
00312
00313
00314
00315 #define CONTAINER_GET_SUBSET(x,k) (x)->get_subset(x,k)
00316 #define CONTAINER_SIZE(x) (x)->get_size(x)
00317 #define CONTAINER_ITERATOR(x) (x)->get_iterator(x)
00318 #define CONTAINER_COMPARE(x,l,r) (x)->compare(l,r)
00319 #define CONTAINER_FOR_EACH(x,f,c) (x)->for_each(x,f,c)
00320
00321
00322
00323
00324
00325
00326 #ifndef NETSNMP_USE_INLINE
00327
00328
00329
00330 int CONTAINER_INSERT(netsnmp_container *x, const void *k);
00331
00332
00333
00334
00335 int CONTAINER_REMOVE(netsnmp_container *x, const void *k);
00336
00337
00338
00339
00340
00341
00342 void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f,
00343 void *c);
00344
00345
00346
00347 int CONTAINER_FREE(netsnmp_container *x);
00348 #else
00349
00350
00351
00352
00353 NETSNMP_STATIC_INLINE
00354 int CONTAINER_INSERT(netsnmp_container *x, const void *k)
00355 {
00356 int rc2, rc = 0;
00357
00359 while(x->prev)
00360 x = x->prev;
00361 for(; x; x = x->next) {
00362 if ((NULL != x->insert_filter) &&
00363 (x->insert_filter(x,k) == 1))
00364 continue;
00365 rc2 = x->insert(x,k);
00366 if (rc2) {
00367 snmp_log(LOG_ERR,"error on subcontainer '%s' insert (%d)\n",
00368 x->container_name ? x->container_name : "", rc2);
00369 rc = rc2;
00370 }
00371 }
00372 return rc;
00373 }
00374
00375
00376
00377
00378
00379 NETSNMP_STATIC_INLINE
00380 int CONTAINER_REMOVE(netsnmp_container *x, const void *k)
00381 {
00382 int rc2, rc = 0;
00383
00385 while(x->next)
00386 x = x->next;
00387 while(x) {
00388 rc2 = x->remove(x,k);
00390 if ((rc2) && (NULL == x->insert_filter)) {
00391 snmp_log(LOG_ERR,"error on subcontainer remove (%d)\n", rc2);
00392 rc = rc2;
00393 }
00394 x = x->prev;
00395
00396 }
00397 return rc;
00398 }
00399
00400
00401
00402
00403
00404 NETSNMP_STATIC_INLINE
00405 int CONTAINER_FREE(netsnmp_container *x)
00406 {
00407 int rc2, rc = 0;
00408
00410 while(x->next)
00411 x = x->next;
00412 while(x) {
00413 netsnmp_container *tmp;
00414 tmp = x->prev;
00415 if (NULL != x->container_name)
00416 SNMP_FREE(x->container_name);
00417 rc2 = x->cfree(x);
00418 if (rc2) {
00419 snmp_log(LOG_ERR,"error on subcontainer cfree (%d)\n", rc2);
00420 rc = rc2;
00421 }
00422 x = tmp;
00423 }
00424 return rc;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 NETSNMP_STATIC_INLINE
00437 void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f,
00438 void *c)
00439 {
00441 while(x->next)
00442 x = x->next;
00443 while(x->prev) {
00444 x->clear(x, NULL, c);
00445 x = x->prev;
00446 }
00447 x->clear(x, f, c);
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457 NETSNMP_STATIC_INLINE
00458 netsnmp_container *SUBCONTAINER_FIND(netsnmp_container *x,
00459 const char* name)
00460 {
00461 if ((NULL == x) || (NULL == name))
00462 return NULL;
00463
00465 while(x->prev)
00466 x = x->prev;
00467 while(x) {
00468 if ((NULL != x->container_name) &&
00469 (0 == strcmp(name,x->container_name)))
00470 break;
00471 x = x->next;
00472 }
00473 return x;
00474 }
00475
00476 #endif
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 typedef int (netsnmp_iterator_rc)(struct netsnmp_iterator_s *);
00487
00488
00489
00490
00491 typedef void * (netsnmp_iterator_rtn)(struct netsnmp_iterator_s *);
00492
00493
00494
00495
00496
00497 typedef struct netsnmp_iterator_s {
00498
00499 netsnmp_container *container;
00500
00501
00502
00503
00504
00505 u_long sync;
00506
00507
00508
00509
00510 netsnmp_iterator_rc *reset;
00511
00512
00513
00514
00515 netsnmp_iterator_rc *release;
00516
00517
00518
00519
00520 netsnmp_iterator_rtn *first;
00521 netsnmp_iterator_rtn *curr;
00522 netsnmp_iterator_rtn *last;
00523
00524 netsnmp_iterator_rtn *next;
00525
00526 } netsnmp_iterator;
00527
00528
00529 #define ITERATOR_FIRST(x) x->first(x)
00530 #define ITERATOR_NEXT(x) x->next(x)
00531 #define ITERATOR_LAST(x) x->last(x)
00532 #define ITERATOR_RELEASE(x) do { x->release(x); x = NULL; } while(0)
00533
00534 #ifdef __cplusplus
00535 }
00536 #endif
00537
00538 #endif