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_TRY_INSERT(netsnmp_container *x, const void *k);
00336
00337
00338
00339
00340 int CONTAINER_REMOVE(netsnmp_container *x, const void *k);
00341
00342
00343
00344
00345
00346
00347 void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f,
00348 void *c);
00349
00350
00351
00352 int CONTAINER_FREE(netsnmp_container *x);
00353 #else
00354
00355
00356
00357
00358 NETSNMP_STATIC_INLINE
00359 int CONTAINER_INSERT(netsnmp_container *x, const void *k)
00360 {
00361 int rc2, rc = 0;
00362
00364 while(x->prev)
00365 x = x->prev;
00366 for(; x; x = x->next) {
00367 if ((NULL != x->insert_filter) &&
00368 (x->insert_filter(x,k) == 1))
00369 continue;
00370 rc2 = x->insert(x,k);
00371 if (rc2) {
00372 snmp_log(LOG_ERR,"error on subcontainer '%s' insert (%d)\n",
00373 x->container_name ? x->container_name : "", rc2);
00374 rc = rc2;
00375 }
00376 }
00377 return rc;
00378 }
00379
00380
00381 NETSNMP_STATIC_INLINE
00382 int CONTAINER_TRY_INSERT(netsnmp_container *x, const void *k)
00383 {
00384 const void *res = NULL;
00385
00386 netsnmp_container *start;
00388 while(x->prev)
00389 x = x->prev;
00390
00391 start = x;
00392
00393 for(; x; x = x->next) {
00394 if ((NULL != x->insert_filter) &&
00395 (x->insert_filter(x,k) == 1))
00396 continue;
00397 res = x->find(x,k);
00398 if (res) {
00399 return -1;
00400 }
00401 }
00402 return CONTAINER_INSERT(start, k);
00403 }
00404
00405
00406
00407
00408
00409 NETSNMP_STATIC_INLINE
00410 int CONTAINER_REMOVE(netsnmp_container *x, const void *k)
00411 {
00412 int rc2, rc = 0;
00413
00415 while(x->next)
00416 x = x->next;
00417 while(x) {
00418 rc2 = x->remove(x,k);
00420 if ((rc2) && (NULL == x->insert_filter)) {
00421 snmp_log(LOG_ERR,"error on subcontainer remove (%d)\n", rc2);
00422 rc = rc2;
00423 }
00424 x = x->prev;
00425
00426 }
00427 return rc;
00428 }
00429
00430
00431
00432
00433
00434 NETSNMP_STATIC_INLINE
00435 int CONTAINER_FREE(netsnmp_container *x)
00436 {
00437 int rc2, rc = 0;
00438
00440 while(x->next)
00441 x = x->next;
00442 while(x) {
00443 netsnmp_container *tmp;
00444 tmp = x->prev;
00445 if (NULL != x->container_name)
00446 SNMP_FREE(x->container_name);
00447 rc2 = x->cfree(x);
00448 if (rc2) {
00449 snmp_log(LOG_ERR,"error on subcontainer cfree (%d)\n", rc2);
00450 rc = rc2;
00451 }
00452 x = tmp;
00453 }
00454 return rc;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 NETSNMP_STATIC_INLINE
00467 void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f,
00468 void *c)
00469 {
00471 while(x->next)
00472 x = x->next;
00473 while(x->prev) {
00474 x->clear(x, NULL, c);
00475 x = x->prev;
00476 }
00477 x->clear(x, f, c);
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487 NETSNMP_STATIC_INLINE
00488 netsnmp_container *SUBCONTAINER_FIND(netsnmp_container *x,
00489 const char* name)
00490 {
00491 if ((NULL == x) || (NULL == name))
00492 return NULL;
00493
00495 while(x->prev)
00496 x = x->prev;
00497 while(x) {
00498 if ((NULL != x->container_name) &&
00499 (0 == strcmp(name,x->container_name)))
00500 break;
00501 x = x->next;
00502 }
00503 return x;
00504 }
00505
00506 #endif
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 typedef int (netsnmp_iterator_rc)(struct netsnmp_iterator_s *);
00517
00518
00519
00520
00521 typedef void * (netsnmp_iterator_rtn)(struct netsnmp_iterator_s *);
00522
00523
00524
00525
00526
00527 typedef struct netsnmp_iterator_s {
00528
00529 netsnmp_container *container;
00530
00531
00532
00533
00534
00535 u_long sync;
00536
00537
00538
00539
00540 netsnmp_iterator_rc *reset;
00541
00542
00543
00544
00545 netsnmp_iterator_rc *release;
00546
00547
00548
00549
00550 netsnmp_iterator_rtn *first;
00551 netsnmp_iterator_rtn *curr;
00552 netsnmp_iterator_rtn *last;
00553
00554 netsnmp_iterator_rtn *next;
00555
00556 } netsnmp_iterator;
00557
00558
00559 #define ITERATOR_FIRST(x) x->first(x)
00560 #define ITERATOR_NEXT(x) x->next(x)
00561 #define ITERATOR_LAST(x) x->last(x)
00562 #define ITERATOR_RELEASE(x) do { x->release(x); x = NULL; } while(0)
00563
00564 #ifdef __cplusplus
00565 }
00566 #endif
00567
00568 #endif