ua_list.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "ua_list.h"
  2. #include "ua_util.h"
  3. void UA_list_defaultFreer(void *payload) {
  4. if(payload)
  5. UA_free(payload);
  6. }
  7. UA_Int32 UA_list_initElement(UA_list_Element *element) {
  8. if(element == UA_NULL) return UA_ERROR;
  9. element->next = UA_NULL;
  10. element->prev = UA_NULL;
  11. element->father = UA_NULL;
  12. element->payload = UA_NULL;
  13. return UA_NO_ERROR;
  14. }
  15. UA_Int32 UA_list_init(UA_list_List *list) {
  16. if(list == UA_NULL) return UA_ERROR;
  17. list->first = UA_NULL;
  18. list->last = UA_NULL;
  19. list->size = 0;
  20. return UA_NO_ERROR;
  21. }
  22. UA_Int32 UA_list_addElementToFront(UA_list_List *list, UA_list_Element *element) {
  23. UA_list_Element *second = UA_NULL;
  24. if(list == UA_NULL || element == UA_NULL) return UA_ERROR;
  25. second = list->first;
  26. list->first = element;
  27. element->prev = UA_NULL;
  28. element->next = second;
  29. element->father = list;
  30. if(second)
  31. second->prev = element;
  32. list->size++;
  33. if(list->size == 1)
  34. list->last = element;
  35. return UA_NO_ERROR;
  36. }
  37. UA_Int32 UA_list_addPayloadToFront(UA_list_List *list, void *const payload) {
  38. UA_list_Element *elem;
  39. if(list == UA_NULL)
  40. return UA_ERROR;
  41. UA_alloc((void **)&elem, sizeof(*elem));
  42. UA_list_initElement(elem);
  43. elem->payload = payload;
  44. UA_list_addElementToFront(list, elem);
  45. return UA_NO_ERROR;
  46. }
  47. UA_Int32 UA_list_addElementToBack(UA_list_List *list, UA_list_Element *element) {
  48. UA_list_Element *secondLast = UA_NULL;
  49. if(list == UA_NULL || element == UA_NULL)
  50. return UA_ERROR;
  51. secondLast = list->last;
  52. list->last = element;
  53. element->prev = secondLast;
  54. element->next = UA_NULL;
  55. element->father = list;
  56. if(secondLast)
  57. secondLast->next = element;
  58. list->size++;
  59. if(list->size == 1)
  60. list->first = element;
  61. return UA_NO_ERROR;
  62. }
  63. UA_Int32 UA_list_addPayloadToBack(UA_list_List *list, void *const payload) {
  64. UA_list_Element *elem;
  65. if(list == UA_NULL)
  66. return UA_ERROR;
  67. UA_alloc((void **)&elem, sizeof(*elem));
  68. UA_list_initElement(elem);
  69. elem->payload = payload;
  70. UA_list_addElementToBack(list, elem);
  71. return UA_NO_ERROR;
  72. }
  73. UA_Int32 UA_list_removeFirst(UA_list_List *list, UA_list_PayloadVisitor visitor) {
  74. UA_list_Element *temp = UA_NULL;
  75. if(list == UA_NULL)
  76. return UA_ERROR;
  77. if(list->first) {
  78. temp = list->first->next;
  79. if(visitor)
  80. (*visitor)(list->first->payload);
  81. UA_free(list->first);
  82. list->first = temp;
  83. if(temp)
  84. temp->prev = UA_NULL;
  85. list->size--;
  86. if(list->size == 1)
  87. list->last = temp;
  88. else if(list->size == 0)
  89. list->last = UA_NULL;
  90. }
  91. return UA_NO_ERROR;
  92. }
  93. UA_Int32 UA_list_removeLast(UA_list_List *list, UA_list_PayloadVisitor visitor) {
  94. UA_list_Element *temp = UA_NULL;
  95. if(list == UA_NULL)
  96. return UA_ERROR;
  97. if(list->last) {
  98. temp = list->last->prev;
  99. if(visitor)
  100. (*visitor)(list->last->payload);
  101. UA_free(list->last);
  102. list->last = temp;
  103. if(temp)
  104. temp->next = UA_NULL;
  105. list->size--;
  106. if(list->size == 1)
  107. list->first = temp;
  108. else if(list->size == 0)
  109. list->first = UA_NULL;
  110. }
  111. return UA_NO_ERROR;
  112. }
  113. UA_Int32 UA_list_removeElement(UA_list_Element *const elem, UA_list_PayloadVisitor visitor) {
  114. if(elem == UA_NULL)
  115. return UA_ERROR;
  116. if(elem == elem->father->first)
  117. return UA_list_removeFirst(elem->father, visitor);
  118. else if(elem == elem->father->last)
  119. return UA_list_removeLast(elem->father, visitor);
  120. else{
  121. UA_list_Element *prev = elem->prev;
  122. UA_list_Element *next = elem->next;
  123. prev->next = next;
  124. next->prev = prev;
  125. if(visitor)
  126. (*visitor)(elem->payload);
  127. (elem->father)->size--;
  128. UA_free(elem);
  129. }
  130. return UA_NO_ERROR;
  131. }
  132. UA_Int32 UA_list_destroy(UA_list_List *list, UA_list_PayloadVisitor visitor) {
  133. UA_list_Element *current = UA_NULL;
  134. if(list == UA_NULL)
  135. return UA_ERROR;
  136. current = list->first;
  137. while(current) {
  138. UA_list_Element *next = current->next;
  139. if(visitor)
  140. (*visitor)(current->payload);
  141. UA_free(current);
  142. current = next;
  143. }
  144. UA_list_init(list);
  145. return UA_NO_ERROR;
  146. }
  147. UA_Int32 UA_list_iterateElement(UA_list_List *const list, UA_list_ElementVisitor visitor) {
  148. UA_list_Element *current;
  149. UA_list_Element *next = UA_NULL;
  150. if(list == UA_NULL)
  151. return UA_ERROR;
  152. current = list->first;
  153. while(current) {
  154. next = current->next;
  155. if(visitor)
  156. (*visitor)(current);
  157. current = next;
  158. }
  159. return UA_NO_ERROR;
  160. }
  161. /*Int32 UA_list_iteratePayload(UA_list_list* const list, UA_payloadVisitor visitor){
  162. void visitorTemp(UA_list_element* element){
  163. if(visitor){
  164. (*visitor)(element->payload);
  165. }
  166. }
  167. if(list==NULL)return UA_ERROR;
  168. UA_list_iterateElement(list, visitorTemp);
  169. return UA_NO_ERROR;
  170. }*/
  171. /** ANSI C forbids function nesting - reworked ugly version **/
  172. UA_Int32 UA_list_iteratePayload(UA_list_List *const list, UA_list_PayloadVisitor visitor) {
  173. UA_list_Element *current;
  174. UA_list_Element *next = UA_NULL;
  175. if(list == UA_NULL)
  176. return UA_ERROR;
  177. current = list->first;
  178. while(current) {
  179. next = current->next;
  180. if(visitor)
  181. (*visitor)(current->payload);
  182. current = next;
  183. }
  184. return UA_NO_ERROR;
  185. }
  186. UA_list_Element *UA_list_find(UA_list_List *const list, UA_list_PayloadMatcher matcher) {
  187. if(list == UA_NULL) return UA_NULL;
  188. if(matcher) {
  189. UA_list_Element *current = list->first;
  190. while(current) {
  191. if(matcher && (*matcher)(current->payload) == TRUE)
  192. return current;
  193. current = current->next;
  194. }
  195. }
  196. /* nothing found */
  197. return UA_NULL;
  198. }
  199. UA_list_Element *UA_list_search(UA_list_List *const list, UA_list_PayloadComparer compare, void *payload) {
  200. if(list == UA_NULL) return UA_NULL;
  201. if(compare) {
  202. UA_list_Element *current = list->first;
  203. while(current) {
  204. if(compare && (*compare)(current->payload, payload) == TRUE)
  205. return current;
  206. current = current->next;
  207. }
  208. }
  209. /* nothing found */
  210. return UA_NULL;
  211. }
  212. UA_list_Element *UA_list_getFirst(UA_list_List *const list) {
  213. if(list == UA_NULL) return UA_NULL;
  214. return list->first;
  215. }
  216. UA_list_Element *UA_list_getLast(UA_list_List *const list) {
  217. if(list == UA_NULL) return UA_NULL;
  218. return list->last;
  219. }