00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <glib/gmem.h>
00034 #include "opensync_list.h"
00035 #include "opensync_internals.h"
00036
00037 #define _osync_list_alloc() g_slice_new (OSyncList)
00038 #define _osync_list_alloc0() g_slice_new0 (OSyncList)
00039 #define _osync_list_free1(list) g_slice_free (OSyncList, list)
00040
00041 OSyncList*
00042 osync_list_alloc (void)
00043 {
00044 return _osync_list_alloc0 ();
00045 }
00046
00047 void
00048 osync_list_free (OSyncList *list)
00049 {
00050 g_slice_free_chain (OSyncList, list, next);
00051 }
00052
00053 void
00054 osync_list_free_1 (OSyncList *list)
00055 {
00056 _osync_list_free1 (list);
00057 }
00058
00059 OSyncList*
00060 osync_list_append (OSyncList *list,
00061 void * data)
00062 {
00063 OSyncList *new_list;
00064 OSyncList *last;
00065
00066 new_list = _osync_list_alloc ();
00067 new_list->data = data;
00068 new_list->next = NULL;
00069
00070 if (list)
00071 {
00072 last = osync_list_last (list);
00073
00074 last->next = new_list;
00075 new_list->prev = last;
00076
00077 return list;
00078 }
00079 else
00080 {
00081 new_list->prev = NULL;
00082 return new_list;
00083 }
00084 }
00085
00086 OSyncList*
00087 osync_list_prepend (OSyncList *list,
00088 void * data)
00089 {
00090 OSyncList *new_list;
00091
00092 new_list = _osync_list_alloc ();
00093 new_list->data = data;
00094 new_list->next = list;
00095
00096 if (list)
00097 {
00098 new_list->prev = list->prev;
00099 if (list->prev)
00100 list->prev->next = new_list;
00101 list->prev = new_list;
00102 }
00103 else
00104 new_list->prev = NULL;
00105
00106 return new_list;
00107 }
00108
00109 OSyncList*
00110 osync_list_insert (OSyncList *list,
00111 void * data,
00112 int position)
00113 {
00114 OSyncList *new_list;
00115 OSyncList *tmp_list;
00116
00117 if (position < 0)
00118 return osync_list_append (list, data);
00119 else if (position == 0)
00120 return osync_list_prepend (list, data);
00121
00122 tmp_list = osync_list_nth (list, position);
00123 if (!tmp_list)
00124 return osync_list_append (list, data);
00125
00126 new_list = _osync_list_alloc ();
00127 new_list->data = data;
00128 new_list->prev = tmp_list->prev;
00129 if (tmp_list->prev)
00130 tmp_list->prev->next = new_list;
00131 new_list->next = tmp_list;
00132 tmp_list->prev = new_list;
00133
00134 if (tmp_list == list)
00135 return new_list;
00136 else
00137 return list;
00138 }
00139
00140 OSyncList*
00141 osync_list_insert_before (OSyncList *list,
00142 OSyncList *sibling,
00143 void * data)
00144 {
00145 if (!list)
00146 {
00147 list = osync_list_alloc ();
00148 list->data = data;
00149 g_return_val_if_fail (sibling == NULL, list);
00150 return list;
00151 }
00152 else if (sibling)
00153 {
00154 OSyncList *node;
00155
00156 node = _osync_list_alloc ();
00157 node->data = data;
00158 node->prev = sibling->prev;
00159 node->next = sibling;
00160 sibling->prev = node;
00161 if (node->prev)
00162 {
00163 node->prev->next = node;
00164 return list;
00165 }
00166 else
00167 {
00168 g_return_val_if_fail (sibling == list, node);
00169 return node;
00170 }
00171 }
00172 else
00173 {
00174 OSyncList *last;
00175
00176 last = list;
00177 while (last->next)
00178 last = last->next;
00179
00180 last->next = _osync_list_alloc ();
00181 last->next->data = data;
00182 last->next->prev = last;
00183 last->next->next = NULL;
00184
00185 return list;
00186 }
00187 }
00188
00189 OSyncList *
00190 osync_list_concat (OSyncList *list1, OSyncList *list2)
00191 {
00192 OSyncList *tmp_list;
00193
00194 if (list2)
00195 {
00196 tmp_list = osync_list_last (list1);
00197 if (tmp_list)
00198 tmp_list->next = list2;
00199 else
00200 list1 = list2;
00201 list2->prev = tmp_list;
00202 }
00203
00204 return list1;
00205 }
00206
00207 OSyncList*
00208 osync_list_remove (OSyncList *list,
00209 void * data)
00210 {
00211 OSyncList *tmp;
00212
00213 tmp = list;
00214 while (tmp)
00215 {
00216 if (tmp->data != data)
00217 tmp = tmp->next;
00218 else
00219 {
00220 if (tmp->prev)
00221 tmp->prev->next = tmp->next;
00222 if (tmp->next)
00223 tmp->next->prev = tmp->prev;
00224
00225 if (list == tmp)
00226 list = list->next;
00227
00228 _osync_list_free1 (tmp);
00229
00230 break;
00231 }
00232 }
00233 return list;
00234 }
00235
00236 OSyncList*
00237 osync_list_remove_all (OSyncList *list,
00238 void * data)
00239 {
00240 OSyncList *tmp = list;
00241
00242 while (tmp)
00243 {
00244 if (tmp->data != data)
00245 tmp = tmp->next;
00246 else
00247 {
00248 OSyncList *next = tmp->next;
00249
00250 if (tmp->prev)
00251 tmp->prev->next = next;
00252 else
00253 list = next;
00254 if (next)
00255 next->prev = tmp->prev;
00256
00257 _osync_list_free1 (tmp);
00258 tmp = next;
00259 }
00260 }
00261 return list;
00262 }
00263
00264 static inline OSyncList*
00265 _osync_list_remove_link (OSyncList *list,
00266 OSyncList *link)
00267 {
00268 if (link)
00269 {
00270 if (link->prev)
00271 link->prev->next = link->next;
00272 if (link->next)
00273 link->next->prev = link->prev;
00274
00275 if (link == list)
00276 list = list->next;
00277
00278 link->next = NULL;
00279 link->prev = NULL;
00280 }
00281
00282 return list;
00283 }
00284
00285 OSyncList*
00286 osync_list_remove_link (OSyncList *list,
00287 OSyncList *link)
00288 {
00289 return _osync_list_remove_link (list, link);
00290 }
00291
00292 OSyncList*
00293 osync_list_delete_link (OSyncList *list,
00294 OSyncList *link)
00295 {
00296 list = _osync_list_remove_link (list, link);
00297 _osync_list_free1 (link);
00298
00299 return list;
00300 }
00301
00302 OSyncList*
00303 osync_list_copy (OSyncList *list)
00304 {
00305 OSyncList *new_list = NULL;
00306
00307 if (list)
00308 {
00309 OSyncList *last;
00310
00311 new_list = _osync_list_alloc ();
00312 new_list->data = list->data;
00313 new_list->prev = NULL;
00314 last = new_list;
00315 list = list->next;
00316 while (list)
00317 {
00318 last->next = _osync_list_alloc ();
00319 last->next->prev = last;
00320 last = last->next;
00321 last->data = list->data;
00322 list = list->next;
00323 }
00324 last->next = NULL;
00325 }
00326
00327 return new_list;
00328 }
00329
00330 OSyncList*
00331 osync_list_reverse (OSyncList *list)
00332 {
00333 OSyncList *last;
00334
00335 last = NULL;
00336 while (list)
00337 {
00338 last = list;
00339 list = last->next;
00340 last->next = last->prev;
00341 last->prev = list;
00342 }
00343
00344 return last;
00345 }
00346
00347 OSyncList*
00348 osync_list_nth (OSyncList *list,
00349 unsigned int n)
00350 {
00351 while ((n-- > 0) && list)
00352 list = list->next;
00353
00354 return list;
00355 }
00356
00357 OSyncList*
00358 osync_list_nth_prev (OSyncList *list,
00359 unsigned int n)
00360 {
00361 while ((n-- > 0) && list)
00362 list = list->prev;
00363
00364 return list;
00365 }
00366
00367 void *
00368 osync_list_nth_data (OSyncList *list,
00369 unsigned int n)
00370 {
00371 while ((n-- > 0) && list)
00372 list = list->next;
00373
00374 return list ? list->data : NULL;
00375 }
00376
00377 OSyncList*
00378 osync_list_find (OSyncList *list,
00379 const void *data)
00380 {
00381 while (list)
00382 {
00383 if (list->data == data)
00384 break;
00385 list = list->next;
00386 }
00387
00388 return list;
00389 }
00390
00391 OSyncList*
00392 osync_list_find_custom (OSyncList *list,
00393 const void *data,
00394 OSyncCompareFunc func)
00395 {
00396 g_return_val_if_fail (func != NULL, list);
00397
00398 while (list)
00399 {
00400 if (! func (list->data, data))
00401 return list;
00402 list = list->next;
00403 }
00404
00405 return NULL;
00406 }
00407
00408
00409 int
00410 osync_list_position (OSyncList *list,
00411 OSyncList *link)
00412 {
00413 int i;
00414
00415 i = 0;
00416 while (list)
00417 {
00418 if (list == link)
00419 return i;
00420 i++;
00421 list = list->next;
00422 }
00423
00424 return -1;
00425 }
00426
00427 int
00428 osync_list_index (OSyncList *list,
00429 void * data)
00430 {
00431 int i;
00432
00433 i = 0;
00434 while (list)
00435 {
00436 if (list->data == data)
00437 return i;
00438 i++;
00439 list = list->next;
00440 }
00441
00442 return -1;
00443 }
00444
00445 OSyncList*
00446 osync_list_last (OSyncList *list)
00447 {
00448 if (list)
00449 {
00450 while (list->next)
00451 list = list->next;
00452 }
00453
00454 return list;
00455 }
00456
00457 OSyncList*
00458 osync_list_first (OSyncList *list)
00459 {
00460 if (list)
00461 {
00462 while (list->prev)
00463 list = list->prev;
00464 }
00465
00466 return list;
00467 }
00468
00469 unsigned int
00470 osync_list_length (const OSyncList *list)
00471 {
00472 unsigned int length;
00473
00474 length = 0;
00475 while (list)
00476 {
00477 length++;
00478 list = list->next;
00479 }
00480
00481 return length;
00482 }
00483
00484 void
00485 osync_list_foreach (OSyncList *list,
00486 OSyncFunc func,
00487 void * user_data)
00488 {
00489 while (list)
00490 {
00491 OSyncList *next = list->next;
00492 (*func) (list->data, user_data);
00493 list = next;
00494 }
00495 }
00496
00497 static OSyncList*
00498 osync_list_insert_sorted_real (OSyncList *list,
00499 void * data,
00500 OSyncFunc func,
00501 void * user_data)
00502 {
00503 OSyncList *tmp_list = list;
00504 OSyncList *new_list;
00505 int cmp;
00506
00507 g_return_val_if_fail (func != NULL, list);
00508
00509 if (!list)
00510 {
00511 new_list = _osync_list_alloc0 ();
00512 new_list->data = data;
00513 return new_list;
00514 }
00515
00516 cmp = ((OSyncCompareDataFunc) func) (data, tmp_list->data, user_data);
00517
00518 while ((tmp_list->next) && (cmp > 0))
00519 {
00520 tmp_list = tmp_list->next;
00521
00522 cmp = ((OSyncCompareDataFunc) func) (data, tmp_list->data, user_data);
00523 }
00524
00525 new_list = _osync_list_alloc0 ();
00526 new_list->data = data;
00527
00528 if ((!tmp_list->next) && (cmp > 0))
00529 {
00530 tmp_list->next = new_list;
00531 new_list->prev = tmp_list;
00532 return list;
00533 }
00534
00535 if (tmp_list->prev)
00536 {
00537 tmp_list->prev->next = new_list;
00538 new_list->prev = tmp_list->prev;
00539 }
00540 new_list->next = tmp_list;
00541 tmp_list->prev = new_list;
00542
00543 if (tmp_list == list)
00544 return new_list;
00545 else
00546 return list;
00547 }
00548
00549 OSyncList*
00550 osync_list_insert_sorted (OSyncList *list,
00551 void * data,
00552 OSyncCompareFunc func)
00553 {
00554 return osync_list_insert_sorted_real (list, data, (OSyncFunc) func, NULL);
00555 }
00556
00557 OSyncList*
00558 osync_list_insert_sorted_with_data (OSyncList *list,
00559 void * data,
00560 OSyncCompareDataFunc func,
00561 void * user_data)
00562 {
00563 return osync_list_insert_sorted_real (list, data, (OSyncFunc) func, user_data);
00564 }
00565
00566 static OSyncList *
00567 osync_list_sort_merge (OSyncList *l1,
00568 OSyncList *l2,
00569 OSyncFunc compare_func,
00570 void * user_data)
00571 {
00572 OSyncList list, *l, *lprev;
00573 int cmp;
00574
00575 l = &list;
00576 lprev = NULL;
00577
00578 while (l1 && l2)
00579 {
00580 cmp = ((OSyncCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
00581
00582 if (cmp <= 0)
00583 {
00584 l->next = l1;
00585 l1 = l1->next;
00586 }
00587 else
00588 {
00589 l->next = l2;
00590 l2 = l2->next;
00591 }
00592 l = l->next;
00593 l->prev = lprev;
00594 lprev = l;
00595 }
00596 l->next = l1 ? l1 : l2;
00597 l->next->prev = l;
00598
00599 return list.next;
00600 }
00601
00602 static OSyncList*
00603 osync_list_sort_real (OSyncList *list,
00604 OSyncFunc compare_func,
00605 void * user_data)
00606 {
00607 OSyncList *l1, *l2;
00608
00609 if (!list)
00610 return NULL;
00611 if (!list->next)
00612 return list;
00613
00614 l1 = list;
00615 l2 = list->next;
00616
00617 while ((l2 = l2->next) != NULL)
00618 {
00619 if ((l2 = l2->next) == NULL)
00620 break;
00621 l1 = l1->next;
00622 }
00623 l2 = l1->next;
00624 l1->next = NULL;
00625
00626 return osync_list_sort_merge (osync_list_sort_real (list, compare_func, user_data),
00627 osync_list_sort_real (l2, compare_func, user_data),
00628 compare_func,
00629 user_data);
00630 }
00631
00632 OSyncList *
00633 osync_list_sort (OSyncList *list,
00634 OSyncCompareFunc compare_func)
00635 {
00636 return osync_list_sort_real (list, (OSyncFunc) compare_func, NULL);
00637 }
00638
00639 OSyncList *
00640 osync_list_sort_with_data (OSyncList *list,
00641 OSyncCompareDataFunc compare_func,
00642 void * user_data)
00643 {
00644 return osync_list_sort_real (list, (OSyncFunc) compare_func, user_data);
00645 }