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