dlist.c
上传用户:knt0001
上传日期:2022-01-28
资源大小:264k
文件大小:3k
源码类别:

Email客户端

开发平台:

C/C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include "dutil.h"
  6. #include "dlist.h"
  7. struct dlistnode {
  8. void *data;
  9. size_t size;
  10. struct dlistnode *next;
  11. };
  12. /**
  13.  * Creates a linked list and allows you to specify a
  14.  * destroy function for the data that is input into the list.
  15.  *
  16.  * Params
  17.  *  destroy - a function that the caller created for destroying data
  18.  *
  19.  * Return
  20.  *  A new dlist structure
  21.  */
  22. dlist
  23. dlInit(dlistDestroyFunc destroy)
  24. {
  25. dlist ptr = xmalloc(sizeof(struct _dlist));
  26. ptr->size = 0;
  27. ptr->list = NULL;
  28. ptr->save = NULL;
  29. ptr->destroy = destroy;
  30. return ptr;
  31. }
  32. /**
  33.  * Create a new node and and link it up with the rest
  34.  */
  35. void
  36. dlInsertTop(dlist ref, void *data)
  37. {
  38. struct dlistnode *ret = xmalloc(sizeof(struct dlistnode));
  39. assert(ref != NULL);
  40. ret->next = NULL;
  41. if (data) {
  42. ret->data = data;
  43. } else {
  44. ret->data = NULL;
  45. }
  46. // The next pointer should point to what's currently
  47. // at the top of the list. Then, point the top of the list
  48. // to this node we just created.
  49. ret->next = ref->list;
  50. ref->list = ret;
  51. // Reset the "save" pointer to point to our new node.
  52. ref->save = ref->list;
  53. ref->size++;
  54. }
  55. void
  56. dlInsertEnd(dlist ref, void *data)
  57. {
  58. struct dlistnode *current;
  59. struct dlistnode *ret = xmalloc(sizeof(struct dlistnode));
  60. assert(ref != NULL);
  61. ret->next = NULL;
  62. if (data) {
  63. ret->data = data;
  64. } else {
  65. ret->data = NULL;
  66. }
  67. for (current = ref->list; current->next; current = current->next) {
  68. ; /* Just get to the end of the list. */
  69. }
  70. current->next = ret;
  71. ref->size++;
  72. }
  73. /**
  74.  * Copy 'from' list to 'to' list
  75.  */
  76. void
  77. dlCopy(dlist to, dlist from)
  78. {
  79. struct dlistnode *current = NULL;
  80. for (current = from->list; current; current = current->next) {
  81. dlInsertTop(to, current->data);
  82. }
  83. }
  84. /**
  85.  * Resets the save pointer so that when calling GetNext, 
  86.  * you won't be starting from mid list.
  87.  */
  88. void
  89. dlReset(dlist ref)
  90. {
  91. ref->save = ref->list;
  92. }
  93. /**
  94.  * Returns the next element in a list.
  95.  *
  96.  * Params
  97.  *  ref - The dlist to get the next element from.
  98.  *
  99.  * Return
  100.  *  the next element in the dlist, or
  101.  *  null if at the end of the list.
  102.  */
  103. void *
  104. dlGetNext(dlist ref)
  105. {
  106. void *data = NULL;
  107. if (ref) {
  108. if (ref->save) {
  109. data = ref->save->data;
  110. ref->save = ref->save->next;
  111. } else {
  112. data = NULL;
  113. ref->save = ref->list;
  114. }
  115. }
  116. return data;
  117. }
  118. /**
  119.  * Free the entire list 
  120.  */
  121. void
  122. dlDestroy(dlist ref)
  123. {
  124. struct dlistnode *tmp = NULL;
  125. struct dlistnode *first = ref->list;
  126. for (; first; first = tmp) {
  127. tmp = first->next;
  128. if (first->data && ref->destroy) {
  129. ref->destroy(first->data);
  130. }
  131. xfree(first);
  132. }
  133. xfree(ref);
  134. }
  135. /**
  136.  * Removes the top element from the list
  137.  */
  138. void
  139. dlPop(dlist ref)
  140. {
  141. struct dlistnode *hold=NULL, *tmp=ref->list;
  142. hold = tmp->next;
  143. if (ref->destroy && tmp->data) {
  144. ref->destroy(tmp->data);
  145. }
  146. xfree(tmp);
  147. ref->list = hold;
  148. ref->save = ref->list;
  149. ref->size--;
  150. }
  151. void *
  152. dlGetTop(dlist ref)
  153. {
  154. return ref->list->data;
  155. }