Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

linklist.cc

Go to the documentation of this file.
00001 
00002 #ifndef DO_NOT_USE_RCSLIB
00003 #include "rcs_defs.hh"          /* EXTERN_C_STD_HEADERS */
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 // DO_NOT_USE_RCSLIB
00023 #endif
00024 
00025 
00026 #ifdef EXTERN_C_STD_HEADERS
00027 extern "C"
00028 {
00029 #endif
00030 
00031 #include <stdlib.h>             /* malloc() */
00032 #include <string.h>             /* memcpy() */
00033 
00034 #ifndef NO_STDIO
00035 #include <stdio.h>              /* fprintf(), stderr */
00036 #endif
00037 
00038 #ifdef EXTERN_C_STD_HEADERS
00039 }
00040 #endif
00041 
00042 
00043 
00044 #include "linklist.hh"          /* class RCS_LINKED_LIST */
00045                                 /* class RCS_LINKED_LIST_NODE */
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 // Constructor defined private to prevent copying.
00883 RCS_LINKED_LIST::RCS_LINKED_LIST (RCS_LINKED_LIST & list)
00884 {
00885 }

Generated on Sun Dec 2 15:56:50 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001