Advertisement
Guest User

Untitled

a guest
Jan 18th, 2014
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.82 KB | None | 0 0
  1. #include <stddef.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define list_empty(plist) ((plist)->head ? 0 : 1)
  6.  
  7. struct ListNode {
  8.     struct ListNode *next;
  9.     struct ListNode *prev;
  10.     void *data;
  11. };
  12.  
  13. struct List {
  14.     struct ListNode *head;
  15.     struct ListNode *tail;
  16. };
  17.  
  18. struct ListNode *list_node_new(void *data, size_t size) {
  19.     struct ListNode *result = malloc(sizeof(struct ListNode));
  20.     memset(result, 0, sizeof(struct ListNode));
  21.  
  22.     result->data = malloc(size);
  23.     memcpy(result->data, data, size);
  24.  
  25.     return result;
  26. }
  27.  
  28. void list_init(struct List *plist) {
  29.     memset(plist, 0, sizeof(struct List));
  30. }
  31.  
  32. void list_destroy(struct List *plist) {
  33.     struct ListNode *itr = plist->head;
  34.  
  35.     for (; itr; itr = itr->next) {
  36.         free(itr->data);
  37.         if (itr->prev) {
  38.             free(itr->prev);
  39.         }
  40.     }
  41.  
  42.     free(plist->tail);
  43.     list_init(plist);
  44. }
  45.  
  46. size_t list_size(struct List *plist) {
  47.     size_t result = 0;
  48.     struct ListNode *itr = plist->head;
  49.  
  50.     for (; itr; itr = itr->next) {
  51.         ++result;
  52.     }
  53.  
  54.     return result;
  55. }
  56.  
  57. void *list_at(struct List *plist, size_t pos) {
  58.     struct ListNode *itr = plist->head;
  59.  
  60.     for (; pos && itr; itr = itr->next) {
  61.         --pos;
  62.     }
  63.  
  64.     return pos ? NULL : itr->data;
  65. }
  66.  
  67. void *list_next(struct ListNode **pitr, void *buffer, size_t size) {
  68.     if (*pitr) {
  69.         void *pdata = (*pitr)->data;
  70.         memcpy(buffer, pdata, size);
  71.         *pitr = (*pitr)->next;
  72.  
  73.         return pdata;
  74.     }
  75.  
  76.     return NULL;
  77. }
  78.  
  79. void *list_prev(struct ListNode **pitr, void *buffer, size_t size) {
  80.     if (*pitr) {
  81.         void *pdata = (*pitr)->data;
  82.         memcpy(buffer, pdata, size);
  83.         *pitr = (*pitr)->prev;
  84.  
  85.         return pdata;
  86.     }
  87.  
  88.     return NULL;
  89. }
  90.  
  91. void list_push_front(struct List *plist, void *data, size_t size) {
  92.     if (plist->head == NULL) {
  93.         plist->head = list_node_new(data, size);
  94.         plist->tail = plist->head;
  95.     } else {
  96.         plist->head->prev = list_node_new(data, size);
  97.         plist->head->prev->next = plist->head;
  98.         plist->head = plist->head->prev;
  99.     }
  100. }
  101.  
  102. void list_push_back(struct List *plist, void *data, size_t size) {
  103.     if (plist->head == NULL) {
  104.         plist->head = list_node_new(data, size);
  105.         plist->tail = plist->head;
  106.     } else {
  107.         plist->tail->next = list_node_new(data, size);
  108.         plist->tail->next->prev = plist->tail;
  109.         plist->tail = plist->tail->next;
  110.     }
  111. }
  112.  
  113. void list_insert(struct List *plist, size_t pos, void* data, size_t size) {
  114.     struct ListNode *itr = plist->head;
  115.  
  116.     for (; pos && itr; itr = itr->next) {
  117.         --pos;
  118.     }
  119.  
  120.     if (itr && pos == 0) {
  121.         if (plist->head == plist->tail) {
  122.             list_push_front(plist, data, size);
  123.         } else {
  124.             if (itr == plist->head) {
  125.                 list_push_front(plist, data, size);
  126.             } else if (itr == plist->tail) {
  127.                 list_push_back(plist, data, size);
  128.             } else {
  129.                 struct ListNode *plnode = list_node_new(data, size);
  130.  
  131.                 plnode->next = itr;
  132.                 plnode->prev = itr->prev;
  133.  
  134.                 itr->prev->next = plnode;
  135.                 itr->prev = plnode;
  136.             }
  137.         }
  138.     } else if (pos == 0) {
  139.         list_push_back(plist, data, size);
  140.     }
  141. }
  142.  
  143. void list_pop_front(struct List *plist) {
  144.     if (plist->head) {
  145.         struct ListNode *temp = plist->head;
  146.  
  147.         plist->head = plist->head->next;
  148.         if (plist->head) {
  149.             plist->head->prev = NULL;
  150.         } else {
  151.             plist->tail = NULL;
  152.         }
  153.  
  154.         free(temp->data);
  155.         free(temp);
  156.     }
  157. }
  158.  
  159. void list_pop_back(struct List *plist) {
  160.     if (plist->head) {
  161.         struct ListNode *temp = plist->tail;
  162.  
  163.         plist->tail = plist->tail->prev;
  164.         if (plist->tail) {
  165.             plist->tail->next = NULL;
  166.         } else {
  167.             plist->head = NULL;
  168.         }
  169.  
  170.         free(temp->data);
  171.         free(temp);
  172.     }
  173. }
  174.  
  175. void list_remove(struct List *plist, size_t pos) {
  176.     struct ListNode *itr = plist->head;
  177.  
  178.     for (; pos && itr; itr = itr->next) {
  179.         --pos;
  180.     }
  181.  
  182.     if (itr && pos == 0) {
  183.         if (plist->head == plist->tail) {
  184.             list_pop_back(plist);
  185.         } else {
  186.             if (itr == plist->head) {
  187.                 plist->head = plist->head->next;
  188.                 plist->head->prev = NULL;
  189.             } else if (itr == plist->tail) {
  190.                 plist->tail = plist->tail->prev;
  191.                 plist->tail->next = NULL;
  192.             } else {
  193.                 struct ListNode *prev = itr->prev;
  194.                 prev->next = itr->next;
  195.                 itr->next->prev = prev;
  196.             }
  197.  
  198.             free(itr->data);
  199.             free(itr);
  200.         }
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement