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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * container_list_sl.c
  3.  * $Id: container_list_ssll.c,v 1.7 2004/09/09 10:43:40 slif Exp $
  4.  *
  5.  */
  6. #include <net-snmp/net-snmp-config.h>
  7. #include <stdio.h>
  8. #if HAVE_STDLIB_H
  9. #include <stdlib.h>
  10. #endif
  11. #if HAVE_MALLOC_H
  12. #include <malloc.h>
  13. #endif
  14. #include <sys/types.h>
  15. #if HAVE_STRING_H
  16. #include <string.h>
  17. #else
  18. #include <strings.h>
  19. #endif
  20. #include <net-snmp/net-snmp-includes.h>
  21. #include <net-snmp/types.h>
  22. #include <net-snmp/library/snmp_api.h>
  23. #include <net-snmp/library/container.h>
  24. #include <net-snmp/library/tools.h>
  25. #include <net-snmp/library/snmp_assert.h>
  26. #include <net-snmp/library/container_list_ssll.h>
  27. typedef struct sl_node {
  28.    void           *data;
  29.    struct sl_node *next;
  30. } sl_node;
  31. typedef struct sl_container_s {
  32.    netsnmp_container          c;
  33.    
  34.    size_t                     count;      /* Index of the next free entry */
  35.    sl_node                   *head;       /* head of list */
  36.    int                        unsorted;   /* unsorted list? */
  37.    int                        fifo;       /* lifo or fifo? */
  38. } sl_container;
  39. static void *
  40. _get(netsnmp_container *c, const void *key, int exact)
  41. {
  42.     sl_container *sl = (sl_container*)c;
  43.     sl_node  *curr = sl->head;
  44.     int rc = 0;
  45.     
  46.     /*
  47.      * note: get-next on unsorted list is meaningless. we
  48.      * don't try to search whole array, looking for the next highest.
  49.      */
  50.     if( (NULL != curr) && (NULL != key)) {
  51.         while (curr) {
  52.             rc = sl->c.compare(curr->data, key);
  53.             if (rc == 0)
  54.                 break;
  55.             else if (rc > 0) {
  56.                 if (0 == sl->unsorted) {
  57.                     /*
  58.                      * if sorted, we can stop.
  59.                      */
  60.                     break;
  61.                 }
  62.             }
  63.             curr = curr->next;
  64.         }
  65.         
  66.         if((curr) && (!exact) && (rc == 0)) {
  67.             curr = curr->next;
  68.         }
  69.     }
  70.     
  71.     return curr ? curr->data : NULL;
  72. }
  73. /**********************************************************************
  74.  *
  75.  *
  76.  *
  77.  **********************************************************************/
  78. static void
  79. _ssll_free(netsnmp_container *c)
  80. {
  81.     if(c) {
  82.         free(c);
  83.     }
  84. }
  85. static void *
  86. _ssll_find(netsnmp_container *c, const void *data)
  87. {
  88.     if((NULL == c) || (NULL == data))
  89.         return NULL;
  90.     return _get(c, data, 1);
  91. }
  92. static void *
  93. _ssll_find_next(netsnmp_container *c, const void *data)
  94. {
  95.     if(NULL == c)
  96.         return NULL;
  97.     return _get(c, data, 0);
  98. }
  99. static int
  100. _ssll_insert(netsnmp_container *c, const void *data)
  101. {
  102.     sl_container *sl = (sl_container*)c;
  103.     sl_node  *new_node, *curr = sl->head;
  104.     
  105.     if(NULL == c)
  106.         return -1;
  107.     
  108.     new_node = SNMP_MALLOC_TYPEDEF(sl_node);
  109.     if(NULL == new_node)
  110.         return -1;
  111.     new_node->data = (void *)data;
  112.     ++sl->count;
  113.     /*
  114.      * first node?
  115.      */
  116.     if(NULL == sl->head) {
  117.         sl->head = new_node;
  118.         return 0;
  119.     }
  120.     /*
  121.      * sorted or unsorted insert?
  122.      */
  123.     if (1 == sl->unsorted) {
  124.         /*
  125.          * unsorted: fifo, or lifo?
  126.          */
  127.         if (1 == sl->fifo) {
  128.             /*
  129.              * fifo: insert at tail
  130.              */
  131.             while(NULL != curr->next)
  132.                 curr = curr->next;
  133.             curr->next = new_node;
  134.         }
  135.         else {
  136.             /*
  137.              * lifo: insert at head
  138.              */
  139.             new_node->next = sl->head;
  140.             sl->head = new_node;
  141.         }
  142.     }
  143.     else {
  144.         /*
  145.          * sorted
  146.          */
  147.         sl_node *last = NULL;
  148.         for( ; curr; last = curr, curr = curr->next) {
  149.             if(sl->c.compare(curr->data, data) > 0)
  150.                 break;
  151.         }
  152.         if(NULL == last) {
  153.             new_node->next = sl->head;
  154.             sl->head = new_node;
  155.         }
  156.         else {
  157.             new_node->next = last->next;
  158.             last->next = new_node;
  159.         }
  160.     }
  161.     
  162.     return 0;
  163. }
  164. static int
  165. _ssll_remove(netsnmp_container *c, const void *data)
  166. {
  167.     sl_container *sl = (sl_container*)c;
  168.     sl_node  *curr = sl->head;
  169.     
  170.     if((NULL == c) || (NULL == curr))
  171.         return -1;
  172.     
  173.     /*
  174.      * special case for NULL data, act like stack
  175.      */
  176.     if ((NULL == data) ||
  177.         (sl->c.compare(sl->head->data, data) == 0)) {
  178.         curr = sl->head;
  179.         sl->head = sl->head->next;
  180.     }
  181.     else {
  182.         sl_node *last = sl->head;
  183.         int rc;
  184.         for(curr = sl->head->next ; curr; last = curr, curr = curr->next) {
  185.             rc = sl->c.compare(curr->data, data);
  186.             if (rc == 0) {
  187.                 last->next = curr->next;
  188.                 break;
  189.             }
  190.             else if ((rc > 0) && (0 == sl->unsorted)) {
  191.                 /*
  192.                  * if sorted and rc > 0, didn't find entry
  193.                  */
  194.                 curr = NULL;
  195.                 break;
  196.             }
  197.         }
  198.     }
  199.     if(NULL == curr)
  200.         return -2;
  201.     
  202.     /*
  203.      * free our node structure, but not the data
  204.      */
  205.     free(curr);
  206.     --sl->count;
  207.     
  208.     return 0;
  209. }
  210. static size_t
  211. _ssll_size(netsnmp_container *c)
  212. {
  213.     sl_container *sl = (sl_container*)c;
  214.     
  215.     if(NULL == c)
  216.         return 0;
  217.     return sl->count;
  218. }
  219. static void
  220. _ssll_for_each(netsnmp_container *c, netsnmp_container_obj_func *f,
  221.              void *context)
  222. {
  223.     sl_container *sl = (sl_container*)c;
  224.     sl_node  *curr;
  225.     
  226.     if(NULL == c)
  227.         return;
  228.     
  229.     for(curr = sl->head; curr; curr = curr->next)
  230.         (*f) ((void *)curr->data, context);
  231. }
  232. static void
  233. _ssll_clear(netsnmp_container *c, netsnmp_container_obj_func *f,
  234.              void *context)
  235. {
  236.     sl_container *sl = (sl_container*)c;
  237.     sl_node  *curr, *next;
  238.     
  239.     if(NULL == c)
  240.         return;
  241.     
  242.     for(curr = sl->head; curr; curr = next) {
  243.         next = curr->next;
  244.         if( NULL != f ) {
  245.             curr->next = NULL;
  246.             (*f) ((void *)curr->data, context);
  247.         }
  248.         /*
  249.          * free our node structure, but not the data
  250.          */
  251.         free(curr);
  252.     }
  253.     sl->head = NULL;
  254.     sl->count = 0;
  255. }
  256. /**********************************************************************
  257.  *
  258.  *
  259.  *
  260.  **********************************************************************/
  261. netsnmp_container *
  262. netsnmp_container_get_ssll(void)
  263. {
  264.     /*
  265.      * allocate memory
  266.      */
  267.     sl_container *sl = SNMP_MALLOC_TYPEDEF(sl_container);
  268.     if (NULL==sl) {
  269.         snmp_log(LOG_ERR, "couldn't allocate memoryn");
  270.         return NULL;
  271.     }
  272.     sl->c.cfree = (netsnmp_container_rc*)_ssll_free;
  273.         
  274.     sl->c.get_size = _ssll_size;
  275.     sl->c.init = NULL;
  276.     sl->c.insert = _ssll_insert;
  277.     sl->c.remove = _ssll_remove;
  278.     sl->c.find = _ssll_find;
  279.     sl->c.find_next = _ssll_find_next;
  280.     sl->c.get_subset = NULL;
  281.     sl->c.get_iterator = NULL;
  282.     sl->c.for_each = _ssll_for_each;
  283.     sl->c.clear = _ssll_clear;
  284.        
  285.     return (netsnmp_container*)sl;
  286. }
  287. netsnmp_factory *
  288. netsnmp_container_get_ssll_factory(void)
  289. {
  290.     static netsnmp_factory f = {"sorted_singly_linked_list",
  291.                                 (netsnmp_factory_produce_f*)
  292.                                 netsnmp_container_get_ssll };
  293.     
  294.     return &f;
  295. }
  296. netsnmp_container *
  297. netsnmp_container_get_usll(void)
  298. {
  299.     /*
  300.      * allocate memory
  301.      */
  302.     sl_container *sl = (sl_container *)netsnmp_container_get_ssll();
  303.     if (NULL==sl)
  304.         return NULL; /* msg already logged */
  305.     sl->unsorted = 1;
  306.     return (netsnmp_container*)sl;
  307. }
  308. netsnmp_container *
  309. netsnmp_container_get_singly_linked_list(int fifo)
  310. {
  311.     sl_container *sl = (sl_container *)netsnmp_container_get_usll();
  312.     if (NULL == sl)
  313.         return NULL; /* error already logged */
  314.     sl->fifo = fifo;
  315.     return (netsnmp_container *)sl;
  316. }
  317. netsnmp_container *
  318. netsnmp_container_get_fifo(void)
  319. {
  320.     return netsnmp_container_get_singly_linked_list(1);
  321. }
  322. netsnmp_factory *
  323. netsnmp_container_get_usll_factory(void)
  324. {
  325.     static netsnmp_factory f = {"unsorted_singly_linked_list-lifo",
  326.                                 (netsnmp_factory_produce_f*)
  327.                                 netsnmp_container_get_usll };
  328.     
  329.     return &f;
  330. }
  331. netsnmp_factory *
  332. netsnmp_container_get_fifo_factory(void)
  333. {
  334.     static netsnmp_factory f = {"unsorted_singly_linked_list-fifo",
  335.                                 (netsnmp_factory_produce_f*)
  336.                                 netsnmp_container_get_fifo };
  337.     
  338.     return &f;
  339. }
  340. void
  341. netsnmp_container_ssll_init(void)
  342. {
  343.     netsnmp_container_register("sorted_singly_linked_list",
  344.                                netsnmp_container_get_ssll_factory());
  345.     netsnmp_container_register("unsorted_singly_linked_list",
  346.                                netsnmp_container_get_usll_factory());
  347.     netsnmp_container_register("lifo",
  348.                                netsnmp_container_get_usll_factory());
  349.     netsnmp_container_register("fifo",
  350.                                netsnmp_container_get_fifo_factory());
  351. }