Obj.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /*****************************************************************************/
  2. /* Obj.c - A library for object list. */
  3. /* */
  4. /* Obj.c Copyright (c) 2000 Sakai Hiroaki. */
  5. /* All Rights Reserved. */
  6. /*****************************************************************************/
  7. #include "ObjP.h"
  8. /*****************************************************************************/
  9. /* ObjListData 型の操作 */
  10. /*****************************************************************************/
  11. static ObjListData ObjListData_Create(Obj obj, Obj (*destructor)())
  12. {
  13. ObjListData list_data;
  14. list_data = (ObjListData)malloc(sizeof(_ObjListData));
  15. list_data->obj = obj;
  16. list_data->destructor = destructor;
  17. return (list_data);
  18. }
  19. static ObjListData ObjListData_Destroy(ObjListData list_data)
  20. {
  21. if (list_data == NULL) return (NULL);
  22. /* デストラクタの実行 */
  23. if (list_data->destructor)
  24. (*(list_data->destructor))(list_data->obj);
  25. free(list_data);
  26. return (NULL);
  27. }
  28. /*****************************************************************************/
  29. /* ObjList 型オブジェクトの操作 */
  30. /*****************************************************************************/
  31. Obj ObjListData_GetObj(ObjListData data)
  32. {
  33. if (data == NULL) return (NULL);
  34. return (data->obj);
  35. }
  36. ObjListData ObjListData_GetPrev(ObjListData data)
  37. {
  38. if (data == NULL) return (NULL);
  39. return (data->prev);
  40. }
  41. ObjListData ObjListData_GetNext(ObjListData data)
  42. {
  43. if (data == NULL) return (NULL);
  44. return (data->next);
  45. }
  46. int ObjList_GetLength(ObjList list)
  47. {
  48. if (list == NULL) return (-1);
  49. return (list->length);
  50. }
  51. ObjListData ObjList_GetStartEdge(ObjList list)
  52. {
  53. if (list == NULL) return (NULL);
  54. return (list->start_edge);
  55. }
  56. ObjListData ObjList_GetEndEdge(ObjList list)
  57. {
  58. if (list == NULL) return (NULL);
  59. return (list->end_edge);
  60. }
  61. ObjListData ObjList_GetStart(ObjList list)
  62. {
  63. if (list == NULL) return (NULL);
  64. return (list->start_edge->next);
  65. }
  66. ObjListData ObjList_GetEnd(ObjList list)
  67. {
  68. if (list == NULL) return (NULL);
  69. return (list->end_edge->prev);
  70. }
  71. int ObjList_IsEmpty(ObjList list)
  72. {
  73. if (list == NULL) return (1);
  74. return (list->start_edge->next == list->end_edge);
  75. }
  76. int ObjList_IsStartEdge(ObjList list, ObjListData data)
  77. {
  78. if (list == NULL) return (0);
  79. return (data == list->start_edge);
  80. }
  81. int ObjList_IsEndEdge(ObjList list, ObjListData data)
  82. {
  83. if (list == NULL) return (0);
  84. return (data == list->end_edge);
  85. }
  86. int ObjList_IsStart(ObjList list, ObjListData data)
  87. {
  88. if (list == NULL) return (0);
  89. return (data == list->start_edge->next);
  90. }
  91. int ObjList_IsEnd(ObjList list, ObjListData data)
  92. {
  93. if (list == NULL) return (0);
  94. return (data == list->end_edge->prev);
  95. }
  96. ObjListData ObjList_InsertObjToPrev(ObjList list, ObjListData current,
  97. Obj obj, Obj (*destructor)())
  98. {
  99. ObjListData data;
  100. if (list == NULL) return (NULL);
  101. if (ObjList_IsStartEdge(list, current)) return (NULL);
  102. data = ObjListData_Create(obj, destructor);
  103. if (data == NULL) return (NULL);
  104. data->prev = current->prev;
  105. data->next = current;
  106. current->prev->next = data;
  107. current->prev = data;
  108. (list->length)++;
  109. return (data);
  110. }
  111. ObjListData ObjList_InsertObjToNext(ObjList list, ObjListData current,
  112. Obj obj, Obj (*destructor)())
  113. {
  114. ObjListData data;
  115. if (list == NULL) return (NULL);
  116. if (ObjList_IsEndEdge(list, current)) return (NULL);
  117. data = ObjListData_Create(obj, destructor);
  118. if (data == NULL) return (NULL);
  119. data->next = current->next;
  120. data->prev = current;
  121. current->next->prev = data;
  122. current->next = data;
  123. (list->length)++;
  124. return (data);
  125. }
  126. ObjListData ObjList_InsertObjToStart(ObjList list, Obj obj,
  127. Obj (*destructor)())
  128. {
  129. ObjListData current;
  130. current = ObjList_GetStart(list);
  131. return (ObjList_InsertObjToPrev(list, current, obj, destructor));
  132. }
  133. ObjListData ObjList_InsertObjToEnd(ObjList list, Obj obj,
  134. Obj (*destructor)())
  135. {
  136. ObjListData current;
  137. current = ObjList_GetEnd(list);
  138. return (ObjList_InsertObjToNext(list, current, obj, destructor));
  139. }
  140. ObjListData ObjList_DeleteObjToPrev(ObjList list, ObjListData current)
  141. {
  142. ObjListData ret;
  143. if (list == NULL) return (NULL);
  144. if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
  145. return (NULL);
  146. current->prev->next = current->next;
  147. current->next->prev = current->prev;
  148. ret = current->prev;
  149. ObjListData_Destroy(current);
  150. (list->length)--;
  151. return (ret);
  152. }
  153. ObjListData ObjList_DeleteObjToNext(ObjList list, ObjListData current)
  154. {
  155. ObjListData ret;
  156. if (list == NULL) return (NULL);
  157. if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
  158. return (NULL);
  159. current->prev->next = current->next;
  160. current->next->prev = current->prev;
  161. ret = current->next;
  162. ObjListData_Destroy(current);
  163. (list->length)--;
  164. return (ret);
  165. }
  166. ObjListData ObjList_DeleteObjFromStart(ObjList list)
  167. {
  168. ObjListData current;
  169. if (list == NULL) return (NULL);
  170. current = ObjList_GetStart(list);
  171. return (ObjList_DeleteObjToNext(list, current));
  172. }
  173. ObjListData ObjList_DeleteObjFromEnd(ObjList list)
  174. {
  175. ObjListData current;
  176. if (list == NULL) return (NULL);
  177. current = ObjList_GetEnd(list);
  178. return (ObjList_DeleteObjToPrev(list, current));
  179. }
  180. ObjListData ObjList_MoveObjToPrev(ObjList list,
  181. ObjListData current,
  182. ObjListData to)
  183. {
  184. if (list == NULL) return (NULL);
  185. return (ObjList_MoveObjToPrevOfOtherList(list, current, list, to));
  186. }
  187. ObjListData ObjList_MoveObjToNext(ObjList list,
  188. ObjListData current,
  189. ObjListData to)
  190. {
  191. if (list == NULL) return (NULL);
  192. return (ObjList_MoveObjToNextOfOtherList(list, current, list, to));
  193. }
  194. ObjListData ObjList_MoveObjToStart(ObjList list, ObjListData current)
  195. {
  196. if (list == NULL) return (NULL);
  197. return (ObjList_MoveObjToStartOfOtherList(list, current, list));
  198. }
  199. ObjListData ObjList_MoveObjToEnd(ObjList list, ObjListData current)
  200. {
  201. if (list == NULL) return (NULL);
  202. return (ObjList_MoveObjToEndOfOtherList(list, current, list));
  203. }
  204. ObjList ObjList_Create() /* ObjList 型オブジェクトを作成する */
  205. {
  206. ObjList list;
  207. list = (ObjList)malloc(sizeof(_ObjList));
  208. if (list == NULL) return (NULL);
  209. list->start_edge = ObjListData_Create(NULL, NULL);
  210. list->end_edge = ObjListData_Create(NULL, NULL);
  211. list->length = 0; /* 現在存在しているデータの数 */
  212. list->start_edge->prev = NULL;
  213. list->start_edge->next = list->end_edge;
  214. list->end_edge->prev = list->start_edge;
  215. list->end_edge->next = NULL;
  216. return (list);
  217. }
  218. ObjList ObjList_Destroy(ObjList list) /* */
  219. {
  220. if (list == NULL) return (NULL);
  221. while (!ObjList_IsEmpty(list))
  222. ObjList_DeleteObjFromStart(list);
  223. if (list->start_edge)
  224. list->start_edge = ObjListData_Destroy(list->start_edge);
  225. if (list->end_edge)
  226. list->end_edge = ObjListData_Destroy(list->end_edge);
  227. free(list);
  228. return (NULL);
  229. }
  230. /*===========================================================================*/
  231. /* 複数のリスト間での操作 */
  232. /*===========================================================================*/
  233. ObjListData ObjList_MoveObjToPrevOfOtherList(ObjList list, ObjListData current,
  234. ObjList to_list, ObjListData to)
  235. {
  236. if (list == NULL) return (NULL);
  237. if (to_list == NULL) return (NULL);
  238. if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
  239. return (NULL);
  240. if (ObjList_IsStartEdge(to_list, to)) return (NULL);
  241. if ((list == to_list) && (current == to)) return (current);
  242. current->prev->next = current->next;
  243. current->next->prev = current->prev;
  244. current->prev = to->prev;
  245. current->next = to;
  246. to->prev->next = current;
  247. to->prev = current;
  248. (list->length)--;
  249. (to_list->length)++;
  250. return (current);
  251. }
  252. ObjListData ObjList_MoveObjToNextOfOtherList(ObjList list, ObjListData current,
  253. ObjList to_list, ObjListData to)
  254. {
  255. if (list == NULL) return (NULL);
  256. if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
  257. return (NULL);
  258. if (ObjList_IsEndEdge(to_list, to)) return (NULL);
  259. if ((list == to_list) && (current == to)) return (current);
  260. current->prev->next = current->next;
  261. current->next->prev = current->prev;
  262. current->next = to->next;
  263. current->prev = to;
  264. to->next->prev = current;
  265. to->next = current;
  266. (list->length)--;
  267. (to_list->length)++;
  268. return (current);
  269. }
  270. ObjListData ObjList_MoveObjToStartOfOtherList(ObjList list,
  271. ObjListData current,
  272. ObjList to_list)
  273. {
  274. ObjListData to;
  275. if (list == NULL) return (NULL);
  276. if (to_list == NULL) return (NULL);
  277. to = ObjList_GetStart(to_list);
  278. return (ObjList_MoveObjToPrevOfOtherList(list, current, to_list, to));
  279. }
  280. ObjListData ObjList_MoveObjToEndOfOtherList(ObjList list,
  281. ObjListData current,
  282. ObjList to_list)
  283. {
  284. ObjListData to;
  285. if (list == NULL) return (NULL);
  286. if (to_list == NULL) return (NULL);
  287. to = ObjList_GetEnd(to_list);
  288. return (ObjList_MoveObjToNextOfOtherList(list, current, to_list, to));
  289. }
  290. ObjList ObjList_Concatenate(ObjList list1, ObjList list2)
  291. {
  292. ObjListData tmp;
  293. if (list1 == NULL) {
  294. list1 = list2;
  295. return (list1);
  296. }
  297. if (list2 == NULL) return (list1);
  298. list1->end_edge->prev->next = list2->start_edge->next;
  299. list2->start_edge->next->prev = list1->end_edge->prev;
  300. tmp = list1->end_edge;
  301. list1->end_edge = list2->end_edge;
  302. list2->end_edge = tmp;
  303. list2->start_edge->next = list2->end_edge;
  304. list2->end_edge->prev = list2->start_edge;
  305. list1->length += list2->length;
  306. list2->length = 0;
  307. ObjList_Destroy(list2);
  308. return (list1);
  309. }
  310. /* End of File. */