container.h
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:15k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #ifndef NETSNMP_CONTAINER_H
  2. #define NETSNMP_CONTAINER_H
  3. /*
  4.  * $Id: container.h,v 1.25 2004/09/14 02:29:16 rstory Exp $
  5.  *
  6.  * WARNING: This is a recently created file, and all of it's contents are
  7.  *          subject to change at any time.
  8.  *
  9.  * A basic container template. A generic way for code to store and
  10.  * retrieve data. Allows for interchangable storage algorithms.
  11.  */
  12. #ifndef NET_SNMP_CONFIG_H
  13. #error "Please include <net-snmp/net-snmp-config.h> before this file"
  14. #endif
  15. #include <net-snmp/types.h>
  16. #include <net-snmp/library/factory.h>
  17. #include <net-snmp/library/snmp_logging.h>
  18. #ifdef  __cplusplus
  19. extern "C" {
  20. #endif
  21.     /*************************************************************************
  22.      *
  23.      * function pointer definitions
  24.      *
  25.      *************************************************************************/
  26.     struct netsnmp_iterator_s; /** forward declare */
  27.     struct netsnmp_container_s; /** forward declare */
  28.     /*
  29.      * function returning an int for an operation on a container
  30.      */
  31.     typedef int (netsnmp_container_rc)(struct netsnmp_container_s *);
  32.     /*
  33.      * function returning an int for an operation on a container
  34.      */
  35.     typedef struct netsnmp_iterator_s * (netsnmp_container_it)
  36.         (struct netsnmp_container_s *);
  37.     /*
  38.      * function returning a size_t for an operation on a container
  39.      */
  40.     typedef size_t (netsnmp_container_size)(struct netsnmp_container_s *);
  41.     /*
  42.      * function returning an int for an operation on an object and
  43.      * a container
  44.      */
  45.     typedef int (netsnmp_container_op)(struct netsnmp_container_s *,
  46.                                        const void *data);
  47.     /*
  48.      * function returning an oject for an operation on an object and a
  49.      * container
  50.      */
  51.     typedef void * (netsnmp_container_rtn)(struct netsnmp_container_s *,
  52.                                            const void *data);
  53.     /*
  54.      * function with no return which acts on an object
  55.      */
  56.     typedef void (netsnmp_container_obj_func)(void *data, void *context);
  57.     /*
  58.      * function with no return which acts on an object
  59.      */
  60.     typedef void (netsnmp_container_func)(struct netsnmp_container_s *,
  61.                                           netsnmp_container_obj_func *,
  62.                                           void *context);
  63.     /*
  64.      * function returning an array of objects for an operation on an
  65.      * ojbect and a container
  66.      */
  67.     typedef netsnmp_void_array * (netsnmp_container_set)
  68.         (struct netsnmp_container_s *, void *data);
  69.     /*
  70.      * function returning an int for a comparison between two objects
  71.      */
  72.     typedef int (netsnmp_container_compare)(const void *lhs,
  73.                                             const void *rhs);
  74.     /*************************************************************************
  75.      *
  76.      * Basic container
  77.      *
  78.      *************************************************************************/
  79.     typedef struct netsnmp_container_s {
  80.        
  81.        /*
  82.         * pointer for container implementation
  83.         */
  84.        void *         container_data;
  85.        /*
  86.         * returns the number of items in a container
  87.         */
  88.        netsnmp_container_size  *get_size;
  89.        
  90.        /*
  91.         * initialize a container
  92.         */
  93.        netsnmp_container_rc    *init;
  94.        /*
  95.         * release memory used by a container.
  96.         *
  97.         * Note: if your data structures contained allocated
  98.         * memory, you are responsible for releasing that
  99.         * memory before calling this function!
  100.         */
  101.        netsnmp_container_rc    *cfree;
  102.        /*
  103.         * add an entry to the container
  104.         */
  105.        netsnmp_container_op    *insert;
  106.        /*
  107.         * remove an entry from the container
  108.         */
  109.        netsnmp_container_op    *remove;
  110.        /*
  111.         * release memory for an entry from the container
  112.         */
  113.        netsnmp_container_op    *release;
  114.        /*
  115.         * Note: do not change the key!  If you need to
  116.         * change a key, remove the entry, change the key,
  117.         * and the re-add the entry.
  118.         */
  119.        /*
  120.         * find the entry in the container with the same key
  121.         *
  122.         */
  123.        netsnmp_container_rtn   *find;
  124.        /*
  125.         * find the entry in the container with the next highest key
  126.         *
  127.         * If the key is NULL, return the first item in the container.
  128.         */
  129.        netsnmp_container_rtn   *find_next;
  130.        /*
  131.         * find all entries in the container which match the partial key
  132.         * returns allocated memory (netsnmp_void_array). User is responsible
  133.         * for releasing this memory (free(array->array), free(array)).
  134.         * DO NOT FREE ELEMENTS OF THE ARRAY, because they are the same pointers
  135.         * stored in the container.
  136.         */
  137.        netsnmp_container_set            *get_subset;
  138.        /*
  139.         * function to return an iterator for the container
  140.         */
  141.        netsnmp_container_it           *get_iterator;
  142.        /*
  143.         * function to call another function for each object in the container
  144.         */
  145.        netsnmp_container_func         *for_each;
  146.        /*
  147.         * specialized version of for_each used to optimize cleanup.
  148.         * clear the container, optionally calling a function for each item.
  149.         */
  150.        netsnmp_container_func         *clear;
  151.        /*
  152.         * function to compare two object stored in the container.
  153.         *
  154.         * Returns:
  155.         *
  156.         *   -1  LHS < RHS
  157.         *    0  LHS = RHS
  158.         *    1  LHS > RHS
  159.         */
  160.        netsnmp_container_compare        *compare;
  161.        /*
  162.         * same as compare, but RHS will be a partial key
  163.         */
  164.        netsnmp_container_compare        *ncompare;
  165.        /*
  166.         * unique name for finding a particular container in a list
  167.         */
  168.        char *container_name;
  169.        /*
  170.         * containers can contain other containers (additional indexes)
  171.         */
  172.        struct netsnmp_container_s *next, *prev;
  173.     } netsnmp_container;
  174.     /*
  175.      * initialize/free a container of container factories. used by
  176.      * netsnmp_container_find* functions.
  177.      */
  178.     void netsnmp_container_init_list(void);
  179.     void netsnmp_container_free_list(void);
  180.     /*
  181.      * register a new container factory
  182.      */
  183.     int netsnmp_container_register(const char* name, netsnmp_factory *f);
  184.     /*
  185.      * search for and create a container from a list of types or a
  186.      * specific type.
  187.      */
  188.     netsnmp_container * netsnmp_container_find(const char *type_list);
  189.     netsnmp_container * netsnmp_container_get(const char *type);
  190.     /*
  191.      * utility routines
  192.      */
  193.     void netsnmp_container_add_index(netsnmp_container *primary,
  194.                                      netsnmp_container *new_index);
  195.     netsnmp_factory *netsnmp_container_get_factory(const char *type);
  196.     /*
  197.      * common comparison routines
  198.      */
  199.     /** first data element is a 'netsnmp_index' */
  200.     int netsnmp_compare_netsnmp_index(const void *lhs, const void *rhs);
  201.     int netsnmp_ncompare_netsnmp_index(const void *lhs, const void *rhs);
  202.     /** first data element is a 'char *' */
  203.     int netsnmp_compare_cstring(const void * lhs, const void * rhs);
  204.     int netsnmp_ncompare_cstring(const void * lhs, const void * rhs);
  205.     /** useful for octet strings */
  206.     int netsnmp_compare_mem(const char * lhs, size_t lhs_len,
  207.                             const char * rhs, size_t rhs_len);
  208.     /** for_each callback to call free on data item */
  209.     void  netsnmp_container_simple_free(void *data, void *context);
  210.     /*
  211.      * useful macros (x = container; k = key; c = user context)
  212.      */
  213. #define CONTAINER_FIRST(x)          (x)->find_next(x,NULL)
  214. #define CONTAINER_FIND(x,k)         (x)->find(x,k)
  215. #define CONTAINER_NEXT(x,k)         (x)->find_next(x,k)
  216. /*
  217.  * GET_SUBSET returns allocated memory (netsnmp_void_array). User is responsible
  218.  * for releasing this memory (free(array->array), free(array)).
  219.  * DO NOT FREE ELEMENTS OF THE ARRAY, because they are the same pointers
  220.  * stored in the container.
  221.  */
  222. #define CONTAINER_GET_SUBSET(x,k)   (x)->get_subset(x,k)
  223. #define CONTAINER_SIZE(x)           (x)->get_size(x)
  224. #define CONTAINER_ITERATOR(x)       (x)->get_iterator(x)
  225. #define CONTAINER_COMPARE(x,l,r)    (x)->compare(l,r)
  226. #define CONTAINER_FOR_EACH(x,f,c)   (x)->for_each(x,f,c)
  227.     /*
  228.      * if you are getting multiple definitions of these three
  229.      * inline functions, you most likely have optimizations turned off.
  230.      * Either turn them back on, or define NETSNMP_NO_INLINE
  231.      */
  232. #ifndef NETSNMP_USE_INLINE /* default is to inline */
  233.     /*
  234.      * insert k into all containers
  235.      */
  236.     int CONTAINER_INSERT(netsnmp_container *x, const void *k);
  237.     /*
  238.      * remove k from all containers
  239.      */
  240.     int CONTAINER_REMOVE(netsnmp_container *x, const void *k);
  241.     /*
  242.      * clear all containers. When clearing the *first* container, and
  243.      * *only* the first container, call the function f for each item.
  244.      * After calling this function, all containers should be empty.
  245.      */
  246.     void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f,
  247.                         void *c);
  248.     /*
  249.      * free all containers
  250.      */
  251.     int CONTAINER_FREE(netsnmp_container *x);
  252. #else
  253.     /*------------------------------------------------------------------
  254.      * These functions should EXACTLY match the function version in
  255.      * container.c. If you change one, change them both.
  256.      */
  257.     NETSNMP_STATIC_INLINE /* gcc docs recommend static w/inline */
  258.     int CONTAINER_INSERT(netsnmp_container *x, const void *k)
  259.     {
  260.         int rc2, rc = 0;
  261.         
  262.         /** start at first container */
  263.         while(x->prev)
  264.             x = x->prev;
  265.         while(x) {
  266.             rc2 = x->insert(x,k);
  267.             if (rc2) {
  268.                 snmp_log(LOG_ERR,"error on subcontainer insert (%d)n", rc2);
  269.                 rc = rc2;
  270.             }
  271.             x = x->next;
  272.         }
  273.         return rc;
  274.     }
  275.     
  276.     /*------------------------------------------------------------------
  277.      * These functions should EXACTLY match the function version in
  278.      * container.c. If you change one, change them both.
  279.      */
  280.     NETSNMP_STATIC_INLINE /* gcc docs recommend static w/inline */
  281.     int CONTAINER_REMOVE(netsnmp_container *x, const void *k)
  282.     {
  283.         int rc2, rc = 0;
  284.         
  285.         /** start at last container */
  286.         while(x->next)
  287.             x = x->next;
  288.         while(x) {
  289.             rc2 = x->remove(x,k);
  290.             if (rc2) {
  291.                 snmp_log(LOG_ERR,"error on subcontainer remove (%d)n", rc2);
  292.                 rc = rc2;
  293.             }
  294.             x = x->prev;
  295.             
  296.         }
  297.         return rc;
  298.     }
  299.     
  300.     /*------------------------------------------------------------------
  301.      * These functions should EXACTLY match the function version in
  302.      * container.c. If you change one, change them both.
  303.      */
  304.     NETSNMP_STATIC_INLINE /* gcc docs recommend static w/inline */
  305.     int CONTAINER_FREE(netsnmp_container *x)
  306.     {
  307. int  rc2, rc = 0;
  308.         
  309.         /** start at last container */
  310.         while(x->next)
  311.             x = x->next;
  312.         while(x) {
  313.             netsnmp_container *tmp;
  314.             tmp = x->prev;
  315.             if (NULL != x->container_name)
  316.                 SNMP_FREE(x->container_name);
  317.             rc2 = x->cfree(x);
  318.             if (rc2) {
  319.                 snmp_log(LOG_ERR,"error on subcontainer cfree (%d)n", rc2);
  320.                 rc = rc2;
  321.             }
  322.             x = tmp;
  323.         }
  324.         return rc;
  325.     }
  326.     /*------------------------------------------------------------------
  327.      * These functions should EXACTLY match the function version in
  328.      * container.c. If you change one, change them both.
  329.      */
  330.     /*
  331.      * clear all containers. When clearing the *first* container, and
  332.      * *only* the first container, call the function f for each item.
  333.      * After calling this function, all containers should be empty.
  334.      */
  335.     NETSNMP_STATIC_INLINE /* gcc docs recommend static w/inline */
  336.     void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f,
  337.                         void *c)
  338.     {
  339.         /** start at last container */
  340.         while(x->next)
  341.             x = x->next;
  342.         while(x->prev) {
  343.             x->clear(x, NULL, c);
  344.             x = x->prev;
  345.         }
  346.         x->clear(x, f, c);
  347.     }
  348.     /*------------------------------------------------------------------
  349.      * These functions should EXACTLY match the function version in
  350.      * container.c. If you change one, change them both.
  351.      */
  352.     /*
  353.      * Find a sub-container with the given name
  354.      */
  355.     NETSNMP_STATIC_INLINE /* gcc docs recommend static w/inline */
  356.     netsnmp_container *SUBCONTAINER_FIND(netsnmp_container *x,
  357.                                          const char* name)
  358.     {
  359.         if ((NULL == x) || (NULL == name))
  360.             return NULL;
  361.         /** start at first container */
  362.         while(x->prev)
  363.             x = x->prev;
  364.         while(x) {
  365.             if ((NULL != x->container_name) &&
  366.                 (0 == strcmp(name,x->container_name)))
  367.                 break;
  368.             x = x->next;
  369.         }
  370.         return x;
  371.     }
  372. #endif
  373.     
  374.     /*************************************************************************
  375.      *
  376.      * container iterator
  377.      *
  378.      *************************************************************************/
  379.     /*
  380.      * function returning an int for an operation on an iterator
  381.      */
  382.     typedef int (netsnmp_iterator_rc)(struct netsnmp_iterator_s *);
  383.     /*
  384.      * function returning an int for an operation on an iterator and
  385.      * an object in the container.
  386.      */
  387.     typedef int (netsnmp_iterator_rc_op)(struct netsnmp_iterator_s *,
  388.                                          void *data);
  389.     /*
  390.      * function returning an oject for an operation on an iterator
  391.      */
  392.     typedef void * (netsnmp_iterator_rtn)(struct netsnmp_iterator_s *);
  393.     typedef struct netsnmp_iterator_s {
  394.        netsnmp_container              *container;
  395.        void                           *context;
  396.        netsnmp_iterator_rc           *init;
  397.        netsnmp_iterator_rc_op        *position;
  398.        netsnmp_iterator_rtn          *first;
  399.        netsnmp_iterator_rtn          *next;
  400.        netsnmp_iterator_rtn          *last;
  401.     } netsnmp_iterator;
  402. #define ITERATOR_FIRST(x)  x->first(x)
  403. #define ITERATOR_NEXT(x)   x->next(x)
  404. #define ITERATOR_LAST(x)   x->last(x)
  405.     /*************************************************************************
  406.      *
  407.      * Sorted container
  408.      *
  409.      *************************************************************************/
  410.     typedef struct netsnmp_sorted_container_s {
  411.        
  412.        netsnmp_container                bc;
  413.        
  414.        /*
  415.         * methods to manipulate container
  416.         */
  417.        netsnmp_container_rtn            *first;
  418.        netsnmp_container_rtn            *next;
  419.        netsnmp_container_set            *subset;
  420.        
  421.     } netsnmp_sorted_container;
  422.     
  423.     void
  424.     netsnmp_init_sorted_container(netsnmp_sorted_container  *sc,
  425.                                   netsnmp_container_rtn     *first,
  426.                                   netsnmp_container_rtn     *next,
  427.                                   netsnmp_container_set     *subset);
  428.     
  429.     
  430.     
  431. #ifdef  __cplusplus
  432. }
  433. #endif
  434. #endif /** NETSNMP_CONTAINER_H */