00001
00002 #ifndef DO_NOT_USE_RCSLIB
00003 #include "rcs_defs.hh"
00004
00005 #else
00006
00007 #ifdef DEBUG_MEMORY
00008 #include "dbg_mem.h"
00009
00010 #else
00011
00012 #ifndef DEBUG_MALLOC
00013 #define DEBUG_MALLOC(x) malloc(x)
00014 #endif
00015
00016 #ifndef DEBUG_FREE
00017 #define DEBUG_FREE(x) free(x)
00018 #endif
00019
00020 #endif
00021
00022
00023 #endif
00024
00025
00026 #ifdef EXTERN_C_STD_HEADERS
00027 extern "C"
00028 {
00029 #endif
00030
00031 #include <stdlib.h>
00032 #include <string.h>
00033
00034 #ifndef NO_STDIO
00035 #include <stdio.h>
00036 #endif
00037
00038 #ifdef EXTERN_C_STD_HEADERS
00039 }
00040 #endif
00041
00042
00043
00044 #include "linklist.hh"
00045
00046
00047 RCS_LINKED_LIST_NODE::RCS_LINKED_LIST_NODE (void *_data, size_t _size)
00048 {
00049 data = _data;
00050 size = _size;
00051 next = (RCS_LINKED_LIST_NODE *) NULL;
00052 last = (RCS_LINKED_LIST_NODE *) NULL;
00053 }
00054
00055 RCS_LINKED_LIST_NODE::~RCS_LINKED_LIST_NODE ()
00056 {
00057 }
00058
00059 RCS_LINKED_LIST::RCS_LINKED_LIST ()
00060 {
00061 head = (RCS_LINKED_LIST_NODE *) NULL;
00062 tail = (RCS_LINKED_LIST_NODE *) NULL;
00063 current_node = (RCS_LINKED_LIST_NODE *) NULL;
00064 extra_node = (RCS_LINKED_LIST_NODE *) NULL;
00065 last_data_retrieved = NULL;
00066 last_size_retrieved = 0;
00067 last_copied_retrieved = 0;
00068 list_size = 0;
00069 next_node_id = 1;
00070 delete_data_not_copied = 0;
00071 extra_node = new RCS_LINKED_LIST_NODE (NULL, 0);
00072 max_list_size = 0;
00073 sizing_mode = NO_MAXIMUM_SIZE;
00074 }
00075
00076 RCS_LINKED_LIST::~RCS_LINKED_LIST ()
00077 {
00078 flush_list ();
00079 if (NULL != extra_node)
00080 {
00081 delete extra_node;
00082 extra_node = (RCS_LINKED_LIST_NODE *) NULL;
00083 }
00084 }
00085
00086 void
00087 RCS_LINKED_LIST::set_list_sizing_mode (int _new_max_size,
00088 LIST_SIZING_MODE _new_sizing_mode)
00089 {
00090 max_list_size = _new_max_size;
00091 sizing_mode = _new_sizing_mode;
00092 }
00093
00094 void
00095 RCS_LINKED_LIST::flush_list ()
00096 {
00097 RCS_LINKED_LIST_NODE *next_node;
00098 current_node = head;
00099 while (NULL != current_node)
00100 {
00101 next_node = current_node->next;
00102 if ((current_node->copied || delete_data_not_copied)
00103 && (NULL != current_node->data))
00104 {
00105 DEBUG_FREE (current_node->data);
00106 }
00107 delete current_node;
00108 current_node = next_node;
00109 }
00110 if (last_copied_retrieved)
00111 {
00112 if (last_data_retrieved != NULL)
00113 {
00114 DEBUG_FREE (last_data_retrieved);
00115 last_data_retrieved = NULL;
00116 last_size_retrieved = 0;
00117 }
00118 }
00119 head = (RCS_LINKED_LIST_NODE *) NULL;
00120 tail = (RCS_LINKED_LIST_NODE *) NULL;
00121 list_size = 0;
00122 last_data_stored = NULL;
00123 last_size_stored = 0;
00124 }
00125
00126 void
00127 RCS_LINKED_LIST::delete_members ()
00128 {
00129 int old_delete_data_not_copied = delete_data_not_copied;
00130 delete_data_not_copied = 1;
00131 flush_list ();
00132 delete_data_not_copied = old_delete_data_not_copied;
00133 }
00134
00135 void *
00136 RCS_LINKED_LIST::retrieve_head ()
00137 {
00138 RCS_LINKED_LIST_NODE *next_node;
00139
00140 if (NULL != head)
00141 {
00142 if (last_copied_retrieved)
00143 {
00144 if (NULL != last_data_retrieved)
00145 {
00146 DEBUG_FREE (last_data_retrieved);
00147 last_data_retrieved = NULL;
00148 last_size_retrieved = 0;
00149 }
00150 }
00151 last_data_retrieved = head->data;
00152 last_size_retrieved = head->size;
00153 last_copied_retrieved = head->copied;
00154 next_node = head->next;
00155 delete head;
00156 head = next_node;
00157 if (NULL != head)
00158 {
00159 head->last = (RCS_LINKED_LIST_NODE *) NULL;
00160 }
00161 else
00162 {
00163 tail = (RCS_LINKED_LIST_NODE *) NULL;
00164 }
00165 list_size--;
00166 return (last_data_retrieved);
00167 }
00168 return (NULL);
00169 }
00170
00171 void *
00172 RCS_LINKED_LIST::retrieve_tail ()
00173 {
00174 RCS_LINKED_LIST_NODE *last_node;
00175
00176 if (NULL != tail)
00177 {
00178 if (last_copied_retrieved)
00179 {
00180 if (NULL != last_data_retrieved)
00181 {
00182 DEBUG_FREE (last_data_retrieved);
00183 last_data_retrieved = NULL;
00184 last_size_retrieved = 0;
00185 }
00186 }
00187 last_data_retrieved = tail->data;
00188 last_size_retrieved = tail->size;
00189 last_copied_retrieved = tail->copied;
00190 last_node = tail->last;
00191 delete tail;
00192 tail = last_node;
00193 if (NULL != tail)
00194 {
00195 tail->next = (RCS_LINKED_LIST_NODE *) NULL;
00196 }
00197 else
00198 {
00199 head = (RCS_LINKED_LIST_NODE *) NULL;
00200 }
00201 list_size--;
00202 return (last_data_retrieved);
00203 }
00204 return (NULL);
00205 }
00206
00207 int
00208 RCS_LINKED_LIST::store_at_head (void *_data, size_t _size, int _copy)
00209 {
00210 RCS_LINKED_LIST_NODE *new_head;
00211 RCS_LINKED_LIST_NODE *old_tail = tail;
00212
00213 if (list_size >= max_list_size)
00214 {
00215 switch (sizing_mode)
00216 {
00217 case DELETE_FROM_TAIL:
00218 if (NULL != tail)
00219 {
00220 tail = tail->last;
00221 if (NULL != tail)
00222 {
00223 tail->next = (RCS_LINKED_LIST_NODE *) NULL;
00224 }
00225 else
00226 {
00227 head = (RCS_LINKED_LIST_NODE *) NULL;
00228 delete old_tail;
00229 list_size = 0;
00230 break;
00231 }
00232 delete old_tail;
00233 list_size--;
00234 }
00235 break;
00236
00237 case NO_MAXIMUM_SIZE:
00238 break;
00239
00240 case DELETE_FROM_HEAD:
00241 case STOP_AT_MAX:
00242 default:
00243 return (-1);
00244 }
00245 }
00246
00247 if (_copy)
00248 {
00249 last_data_stored = DEBUG_MALLOC (_size);
00250 memcpy (last_data_stored, _data, _size);
00251 last_size_stored = _size;
00252 new_head = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00253 }
00254 else
00255 {
00256 last_data_stored = _data;
00257 last_size_stored = _size;
00258 new_head = new RCS_LINKED_LIST_NODE (_data, _size);
00259 }
00260 if (NULL != new_head)
00261 {
00262 new_head->copied = _copy;
00263 new_head->id = next_node_id++;
00264 if (NULL == head)
00265 {
00266 head = new_head;
00267 if (NULL != tail)
00268 {
00269 return (-1);
00270 }
00271 tail = new_head;
00272 }
00273 else
00274 {
00275 head->last = new_head;
00276 new_head->last = (RCS_LINKED_LIST_NODE *) NULL;
00277 new_head->next = head;
00278 head = new_head;
00279 }
00280 list_size++;
00281 return (head->id);
00282 }
00283 else
00284 {
00285 return (-1);
00286 }
00287 }
00288
00289 int
00290 RCS_LINKED_LIST::store_at_tail (void *_data, size_t _size, int _copy)
00291 {
00292 RCS_LINKED_LIST_NODE *new_tail;
00293 RCS_LINKED_LIST_NODE *old_head = head;
00294
00295 if (list_size >= max_list_size)
00296 {
00297 switch (sizing_mode)
00298 {
00299 case DELETE_FROM_HEAD:
00300 if (NULL != head)
00301 {
00302 head = head->next;
00303 if (NULL != head)
00304 {
00305 head->last = (RCS_LINKED_LIST_NODE *) NULL;
00306 }
00307 else
00308 {
00309 head = (RCS_LINKED_LIST_NODE *) NULL;
00310 delete old_head;
00311 list_size = 0;
00312 break;
00313 }
00314 delete old_head;
00315 list_size--;
00316 }
00317 break;
00318
00319 case NO_MAXIMUM_SIZE:
00320 break;
00321
00322 case DELETE_FROM_TAIL:
00323 case STOP_AT_MAX:
00324 default:
00325 #ifndef _Windows
00326 fprintf (stderr, "RCS_LINKED_LIST: Invalid list_sizing_mode.\n");
00327 #endif
00328 return (-1);
00329 }
00330 }
00331
00332 if (_copy)
00333 {
00334 last_data_stored = DEBUG_MALLOC (_size);
00335 memcpy (last_data_stored, _data, _size);
00336 last_size_stored = _size;
00337 new_tail = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00338 }
00339 else
00340 {
00341 last_data_stored = _data;
00342 last_size_stored = _size;
00343 new_tail = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00344 }
00345 if (NULL != new_tail)
00346 {
00347 new_tail->copied = _copy;
00348 new_tail->id = next_node_id++;
00349 if (NULL == tail)
00350 {
00351 tail = new_tail;
00352 if (NULL != head)
00353 {
00354 #ifndef _Windows
00355 fprintf (stderr,
00356 "RCS_LINKED_LIST: Tail is NULL but head is not.\n");
00357 #endif
00358 return (-1);
00359 }
00360 head = new_tail;
00361 }
00362 else
00363 {
00364 tail->next = new_tail;
00365 new_tail->last = tail;
00366 new_tail->next = (RCS_LINKED_LIST_NODE *) NULL;
00367 tail = new_tail;
00368 }
00369 list_size++;
00370 return (tail->id);
00371 }
00372 else
00373 {
00374 #ifndef _Windows
00375 fprintf (stderr,
00376 "RCS_LINKED_LIST: Couldn't create new node to store_at_tail.\n");
00377 #endif
00378 return (-1);
00379 }
00380 }
00381
00382 int
00383 RCS_LINKED_LIST::store_after_current_node (void *_data, size_t _size,
00384 int _copy)
00385 {
00386 RCS_LINKED_LIST_NODE *new_node;
00387 RCS_LINKED_LIST_NODE *old_tail = tail;
00388 RCS_LINKED_LIST_NODE *old_head = head;
00389
00390 if (list_size >= max_list_size)
00391 {
00392 switch (sizing_mode)
00393 {
00394 case DELETE_FROM_TAIL:
00395 if (NULL != tail)
00396 {
00397 tail = tail->last;
00398 if (NULL != tail)
00399 {
00400 tail->next = (RCS_LINKED_LIST_NODE *) NULL;
00401 }
00402 else
00403 {
00404 head = (RCS_LINKED_LIST_NODE *) NULL;
00405 delete old_tail;
00406 list_size = 0;
00407 break;
00408 }
00409 delete old_tail;
00410 list_size--;
00411 }
00412 break;
00413
00414 case NO_MAXIMUM_SIZE:
00415 break;
00416
00417 case DELETE_FROM_HEAD:
00418 if (NULL != head)
00419 {
00420 head = head->next;
00421 if (NULL != head)
00422 {
00423 head->last = (RCS_LINKED_LIST_NODE *) NULL;
00424 }
00425 else
00426 {
00427 head = (RCS_LINKED_LIST_NODE *) NULL;
00428 delete old_head;
00429 list_size = 0;
00430 break;
00431 }
00432 delete old_head;
00433 list_size--;
00434 }
00435 break;
00436 case STOP_AT_MAX:
00437 default:
00438 #ifndef _Windows
00439 fprintf (stderr, "RCS_LINKED_LIST: Invalid list_sizing_mode.\n");
00440 #endif
00441 return (-1);
00442 }
00443 }
00444
00445 if (_copy)
00446 {
00447 last_data_stored = DEBUG_MALLOC (_size);
00448 memcpy (last_data_stored, _data, _size);
00449 last_size_stored = _size;
00450 new_node = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00451 }
00452 else
00453 {
00454 last_data_stored = _data;
00455 last_size_stored = _size;
00456 new_node = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00457 }
00458 if (NULL != new_node)
00459 {
00460 new_node->copied = _copy;
00461 new_node->id = next_node_id++;
00462 if (NULL == current_node)
00463 {
00464 if (tail == NULL)
00465 {
00466 tail = new_node;
00467 if (NULL != head)
00468 {
00469 #ifndef _Windows
00470 fprintf (stderr,
00471 "RCS_LINKED_LIST: Tail is NULL but the head is not.\n");
00472 #endif
00473 return (-1);
00474 }
00475 head = new_node;
00476 }
00477 current_node = tail;
00478 }
00479 else
00480 {
00481 new_node->next = current_node->next;
00482 if (current_node == extra_node)
00483 {
00484 new_node->last = current_node->last;
00485 if (NULL != current_node->last)
00486 {
00487 current_node->last->next = new_node;
00488 }
00489 else
00490 {
00491 head = new_node;
00492 }
00493 }
00494 else
00495 {
00496 new_node->last = current_node;
00497 }
00498 current_node->next = new_node;
00499 if (NULL != new_node->next)
00500 {
00501 new_node->next->last = new_node;
00502 }
00503 else
00504 {
00505 tail = new_node;
00506 }
00507 }
00508 list_size++;
00509 return (new_node->id);
00510 }
00511 else
00512 {
00513 #ifndef _Windows
00514 fprintf (stderr,
00515 "RCS_LINKED_LIST: Couldn't create new node to store_after_current.\n");
00516 #endif
00517 return (-1);
00518 }
00519 }
00520
00521
00522 int
00523 RCS_LINKED_LIST::store_before_current_node (void *_data, size_t _size,
00524 int _copy)
00525 {
00526 RCS_LINKED_LIST_NODE *new_node;
00527 RCS_LINKED_LIST_NODE *old_tail = tail;
00528 RCS_LINKED_LIST_NODE *old_head = head;
00529
00530 if (list_size >= max_list_size)
00531 {
00532 switch (sizing_mode)
00533 {
00534 case DELETE_FROM_TAIL:
00535 if (NULL != tail)
00536 {
00537 tail = tail->last;
00538 if (NULL != tail)
00539 {
00540 tail->next = (RCS_LINKED_LIST_NODE *) NULL;
00541 }
00542 else
00543 {
00544 head = (RCS_LINKED_LIST_NODE *) NULL;
00545 delete old_tail;
00546 list_size = 0;
00547 break;
00548 }
00549 delete old_tail;
00550 list_size--;
00551 }
00552 break;
00553
00554 case NO_MAXIMUM_SIZE:
00555 break;
00556
00557 case DELETE_FROM_HEAD:
00558 if (NULL != head)
00559 {
00560 head = head->next;
00561 if (NULL != head)
00562 {
00563 head->last = (RCS_LINKED_LIST_NODE *) NULL;
00564 }
00565 else
00566 {
00567 head = (RCS_LINKED_LIST_NODE *) NULL;
00568 delete old_head;
00569 list_size = 0;
00570 break;
00571 }
00572 delete old_head;
00573 list_size--;
00574 }
00575 break;
00576
00577 case STOP_AT_MAX:
00578 default:
00579 #ifndef _Windows
00580 fprintf (stderr, "RCS_LINKED_LIST: Invalid list_sizing_mode.\n");
00581 #endif
00582 return (-1);
00583 }
00584 }
00585
00586 if (_copy)
00587 {
00588 last_data_stored = DEBUG_MALLOC (_size);
00589 memcpy (last_data_stored, _data, _size);
00590 last_size_stored = _size;
00591 new_node = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00592 }
00593 else
00594 {
00595 last_data_stored = _data;
00596 last_size_stored = _size;
00597 new_node = new RCS_LINKED_LIST_NODE (last_data_stored, _size);
00598 }
00599 if (NULL != new_node)
00600 {
00601 new_node->copied = _copy;
00602 new_node->id = next_node_id++;
00603 if (NULL == current_node)
00604 {
00605 if (tail == NULL)
00606 {
00607 tail = new_node;
00608 if (NULL != head)
00609 {
00610 #ifndef _Windows
00611 fprintf (stderr,
00612 "RCS_LINKED_LIST: Tail is NULL but head is not.\n");
00613 #endif
00614 return (-1);
00615 }
00616 head = new_node;
00617 }
00618 current_node = tail;
00619 }
00620 else
00621 {
00622 new_node->last = current_node->last;
00623 if (current_node == extra_node)
00624 {
00625 new_node->next = current_node->next;
00626 if (NULL != current_node->next)
00627 {
00628 current_node->next->last = new_node;
00629 }
00630 else
00631 {
00632 tail = new_node;
00633 }
00634 }
00635 else
00636 {
00637 new_node->next = current_node;
00638 }
00639 current_node->last = new_node;
00640 if (NULL != new_node->last)
00641 {
00642 new_node->last->next = new_node;
00643 }
00644 else
00645 {
00646 head = new_node;
00647 }
00648 }
00649 list_size++;
00650 return (new_node->id);
00651 }
00652 else
00653 {
00654 #ifndef _Windows
00655 fprintf (stderr,
00656 "RCS_LINKED_LIST: Couldn't create new node to store_before_current.\n");
00657 #endif
00658 return (-1);
00659 }
00660 }
00661
00662 void *
00663 RCS_LINKED_LIST::get_head ()
00664 {
00665 current_node = head;
00666 if (NULL != current_node)
00667 {
00668 return (current_node->data);
00669 }
00670 else
00671 {
00672 return (NULL);
00673 }
00674 }
00675
00676 void *
00677 RCS_LINKED_LIST::get_tail ()
00678 {
00679 current_node = tail;
00680 if (NULL != current_node)
00681 {
00682 return (current_node->data);
00683 }
00684 else
00685 {
00686 return (NULL);
00687 }
00688 }
00689
00690 void *
00691 RCS_LINKED_LIST::get_next ()
00692 {
00693 if (NULL != current_node)
00694 {
00695 current_node = current_node->next;
00696 }
00697 if (NULL != current_node)
00698 {
00699 return (current_node->data);
00700 }
00701 else
00702 {
00703 return (NULL);
00704 }
00705 }
00706
00707 void *
00708 RCS_LINKED_LIST::get_last ()
00709 {
00710 if (NULL != current_node)
00711 {
00712 current_node = current_node->last;
00713 }
00714 if (NULL != current_node)
00715 {
00716 return (current_node->data);
00717 }
00718 else
00719 {
00720 return (NULL);
00721 }
00722 }
00723
00724 IS_EMPTY
00725 RCS_LINKED_LIST::is_empty ()
00726 {
00727 if ((NULL == head) || (NULL == tail) || (list_size == 0))
00728 {
00729 return (LIST_EMPTY);
00730 }
00731 else
00732 {
00733 return (LIST_NOT_EMPTY);
00734 }
00735 }
00736
00737 void *
00738 RCS_LINKED_LIST::get_by_id (int _id)
00739 {
00740 RCS_LINKED_LIST_NODE *temp;
00741
00742 temp = head;
00743 while (NULL != temp)
00744 {
00745 if (temp->id == _id)
00746 {
00747 return (temp->data);
00748 }
00749 temp = temp->next;
00750 }
00751 return (NULL);
00752 }
00753
00754 void *
00755 RCS_LINKED_LIST::get_first_newer (int _id)
00756 {
00757 current_node = head;
00758 while (NULL != current_node)
00759 {
00760 if (current_node->id > _id)
00761 {
00762 return (current_node->data);
00763 }
00764 current_node = current_node->next;
00765 }
00766 return (NULL);
00767 }
00768
00769 void *
00770 RCS_LINKED_LIST::get_last_newer (int _id)
00771 {
00772 current_node = tail;
00773 while (NULL != current_node)
00774 {
00775 if (current_node->id > _id)
00776 {
00777 return (current_node->data);
00778 }
00779 current_node = current_node->last;
00780 }
00781 return (NULL);
00782 }
00783
00784 void
00785 RCS_LINKED_LIST::delete_node (int _id)
00786 {
00787 RCS_LINKED_LIST_NODE *temp;
00788
00789 temp = head;
00790 while (NULL != temp)
00791 {
00792 if (temp->id == _id)
00793 {
00794 list_size--;
00795 if (temp == current_node)
00796 {
00797 if (NULL != extra_node)
00798 {
00799 extra_node->next = current_node->next;
00800 extra_node->last = current_node->last;
00801 current_node = extra_node;
00802 }
00803 }
00804 if (NULL != temp->next)
00805 {
00806 temp->next->last = temp->last;
00807 }
00808 else
00809 {
00810 tail = temp->last;
00811 }
00812 if (NULL != temp->last)
00813 {
00814 temp->last->next = temp->next;
00815 }
00816 else
00817 {
00818 head = temp->next;
00819 }
00820 if ((temp->copied || delete_data_not_copied)
00821 && (NULL != temp->data))
00822 {
00823 DEBUG_FREE (temp->data);
00824 }
00825 delete temp;
00826 break;
00827 }
00828 temp = temp->next;
00829 }
00830 }
00831
00832 void
00833 RCS_LINKED_LIST::delete_current_node ()
00834 {
00835 if (NULL != current_node && (current_node != extra_node))
00836 {
00837 RCS_LINKED_LIST_NODE *temp;
00838 temp = current_node;
00839 if (NULL != extra_node)
00840 {
00841 extra_node->next = current_node->next;
00842 extra_node->last = current_node->last;
00843 current_node = extra_node;
00844 }
00845 if (NULL != temp->next)
00846 {
00847 temp->next->last = temp->last;
00848 }
00849 else
00850 {
00851 tail = temp->last;
00852 }
00853 if (NULL != temp->last)
00854 {
00855 temp->last->next = temp->next;
00856 }
00857 else
00858 {
00859 head = temp->next;
00860 }
00861 if ((temp->copied || delete_data_not_copied) && (NULL != temp->data))
00862 {
00863 DEBUG_FREE (temp->data);
00864 }
00865 delete temp;
00866 list_size--;
00867 }
00868 }
00869
00870
00871 int
00872 RCS_LINKED_LIST::get_current_id ()
00873 {
00874 if (current_node == NULL)
00875 {
00876 return (-1);
00877 }
00878 return (current_node->id);
00879 }
00880
00881
00882
00883 RCS_LINKED_LIST::RCS_LINKED_LIST (RCS_LINKED_LIST & list)
00884 {
00885 }