home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / ebksrc.arj / FLEXLIST.CPP < prev    next >
C/C++ Source or Header  |  1990-12-05  |  17KB  |  815 lines

  1. /*
  2.  
  3.     flexlist.cpp
  4.     11-28-90
  5.     Homogeneous-heterogeneous 
  6.     hybrid stack-queue-list-array generic class.
  7.     C++ versions 1 & 2
  8.  
  9.  
  10.     Copyright 1990
  11.     John W. Small
  12.     All rights reserved
  13.  
  14.     PSW / Power SoftWare
  15.     P.O. Box 10072,
  16.     McLean, Virginia 22102 8072
  17.     (703) 759-3838
  18.  
  19. */
  20.  
  21.  
  22. #include <flexlist.hpp>
  23.  
  24. #ifndef ANSI_C_STD_LIB
  25.  
  26. int strcmp(const char *s1, const char *s2)
  27. {
  28.     while (*s1++ == *s2++)
  29.         if (!*s1) return 0;
  30.     return (*s1 - *s2);
  31. }
  32.  
  33. void *memcpy(void *dest, const void *src, size_t n)
  34. {
  35.     if (dest && src && n)
  36.         while (n--) 
  37.             ((char *)dest)[n] 
  38.                 = ((const char *)src)[n];
  39.     return dest;
  40. }
  41.  
  42. void *memset(void *s, int c, size_t n)
  43. {
  44.     if (s && n)
  45.         while (n--)
  46.             ((char *)s)[n] =  (char) c;
  47.     return s;
  48. }
  49.  
  50. #endif
  51.  
  52.  
  53. /*  String variant FlexNode virtual functions  */
  54.  
  55. /*
  56.     FNnew() is called by FlexList functions (member 
  57.     functions) that need to allocate new variant length
  58.     FlexNodes, e.g. pushD(), insQD(), insD(), 
  59.     insSortD().  A pointer to the data to be placed in
  60.     the new node is passed to FNnew().  Your FNnew() 
  61.     function must decide how large that data is and 
  62.     allocate a new FlexNode big enough to hold that 
  63.     data, i.e.
  64.  
  65.     FlexN N = new char [sizeof(FlexNode) + 
  66.         sizeofYourData - 1];
  67.  
  68.     Your FNnew() function must also copy that data to
  69.     the new node.  "D" is never NULL!
  70.  
  71.     Please note that FNnew() could call a known function
  72.     member (function) in the data to determine its size. 
  73.     It could also call another function to copy/initialize
  74.     the FlexNode data area from the data.  Data that 
  75.     contains its own functions for interfacing with itself
  76.     are called objects.  Thus FlexLists can be made to 
  77.     hold polymorphic objects via the Variant FlexNode 
  78.     virtual functions functionology.
  79.  
  80.     Study all four virtual functions FNnew(), FNwrite(),
  81.     FNread(), and FNdestruct() for strings and how they
  82.     are called by the various FlexList functions to get
  83.     a better understanding of variant FlexLists.
  84. */
  85.  
  86. FlexN FlexList::FNnew(const void *D)
  87. {
  88.     FlexN N;
  89.  
  90.     for (size_t i = 0; ((char *)D)[i++]; 
  91.         /* no reinit */)
  92.         /* null statement */;
  93.     if ((N = (FlexN) new char [sizeof(FlexNode)+i-1])
  94.         != FlexN0) (void) memcpy(N->data,D,i);
  95.     return N;
  96. }
  97.  
  98.  
  99. /*  FNwrite() is called by storeD() to write variant data
  100.     to a variant FlexNode.  FNwrite() returns true if
  101.     the write is successful.  Make sure the new data
  102.     doesn't write pass the end of the old.  "ND" and
  103.     "D" are never NULL! */
  104.  
  105. int FlexList::FNwrite(void *ND, const void *D)
  106. {
  107.     char *nd, *d;
  108.     
  109.     nd = (char *) ND;
  110.     d = (char *) D;
  111.     while (*nd)
  112.         if ((*nd++ = *d++) == '\0')
  113.             break;
  114.     return 1;
  115. }
  116.  
  117. /*  FNread() is called by topD(), nextD(), prevD(), and
  118.     recallD() to read variant data from a variant 
  119.     FlexNode.  FNread() returns true if the read is
  120.     successful or if there is no place to read the data
  121.     to.  "ND" and "D" are never NULL!  */
  122.  
  123. int FlexList::FNread(const void *ND, void *D)
  124. {
  125.     char *nd, *d;
  126.     
  127.     nd = (char *) ND;
  128.     d = (char *) D;
  129.     while ((*d++ = *nd++) != '\0')
  130.         /* null statement */;
  131.     return 1;
  132. }
  133.  
  134. /*  FNdestruct() is called by clear(), ~FlexList() via 
  135.     clear(), popD(), and delD() to destruct variant 
  136.     data in a FlexNode.  Please note that references
  137.     to suballocated memory may be copied to the outgoing
  138.     data structure instead of being cloned and then 
  139.     deallocated.  You must keep any scheme straight 
  140.     though.  Clear() always passes NULL to the second
  141.     parameter of FNdestruct() via a call to delD(L,0),
  142.     however, so any suballocated memory must be freed in
  143.     that case!  "ND" is never NULL but "D" can be!  */
  144.  
  145. int FlexList::FNdestruct(void *ND, void *D)
  146. {
  147.     char *nd, *d;
  148.     
  149.     nd = (char *)ND;
  150.     if ((d = (char *)D) != (char *)0) 
  151.         while ((*d++ = *nd++) != '\0')
  152.             /* null statement */;
  153.     return 1;
  154. }
  155.  
  156. /*  Any of the virtual functions can be inhibited by returning
  157.     0.  The FlexList functions that call them will simply
  158.     return a failure indication.  */
  159.  
  160.  
  161. // FlexList constructors:
  162.  
  163. FlexList::FlexList(size_t sizeofNodeData, unsigned maxNodes)
  164. {
  165.     front = rear = current = FlexN0;
  166.     curNum = nodes = this->maxNodes = 0;
  167.     this->sizeofNodeData = sizeofNode = 0;
  168.     sorted = 0;
  169.     compare = 0;
  170.     if (sizeofNodeData <= FLmaxSizeofNodeData)  {
  171.         this->maxNodes = maxNodes;
  172.         this->sizeofNodeData = sizeofNodeData;
  173.         if (sizeofNodeData)
  174.             sizeofNode = sizeof(FlexNode)
  175.                 + sizeofNodeData - 1;
  176.         else
  177.             sizeofNode = 0;
  178.         sorted = 1;
  179.     }
  180. }
  181.  
  182. FlexList::FlexList(size_t sizeofCell, unsigned cells,
  183.     const void *array)
  184. {
  185.     front = rear = current = FlexN0;
  186.     curNum = nodes = maxNodes = 0;
  187.     sizeofNodeData = sizeofNode = 0;
  188.     sorted = 0;
  189.     compare = 0;
  190.     if ((sizeofCell <= FLmaxSizeofNodeData) &&
  191.         sizeofCell && cells && array)  {
  192.         maxNodes = FLmaxMaxNodes;
  193.         sizeofNodeData = sizeofCell;
  194.         sizeofNode = sizeof(FlexNode)
  195.             + sizeofCell - 1;
  196.         for (;cells && insQD(array); cells--)
  197.             array = (char *) array + sizeofCell;
  198.     }
  199. }
  200.  
  201.  
  202. // FlexList destructor:
  203.  
  204. int   FlexList::clear()
  205. {
  206.     while (popD())
  207.         /* null statement */;
  208.     if (!nodes)
  209.         return (sorted = 1);
  210.     return 0;
  211. }
  212.  
  213.  
  214. // FlexList stack and queue functions:
  215.  
  216. void * FlexList::pushN(FlexN N)
  217. {
  218.     if (!N || nodes >= maxNodes)
  219.         return (void *) 0;
  220.     N->prev = FlexN0;
  221.     if ((N->next = front) != FlexN0)
  222.         N->next->prev = N;
  223.     else
  224.         rear = N;
  225.     front = N;
  226.     nodes++;
  227.     if (curNum) 
  228.         curNum++;
  229.     sorted = 0;
  230.     return N->data;
  231. }
  232.  
  233. void * FlexList::pushD(const void *D)
  234. {
  235.     FlexN N;
  236.  
  237.     if (nodes >= maxNodes) 
  238.         return (void *) 0;
  239.     if (sizeofNode) {  // fixed size FlexNodes
  240.         if ((N = (FlexN) new char [sizeofNode])
  241.             == FlexN0) return (void *) 0;
  242.         if (D) 
  243.             memcpy(N->data,D,sizeofNodeData);
  244.         else
  245.             memset(N->data,0,sizeofNodeData);
  246.     }
  247.     else if (!D)
  248.         return (void *) 0;
  249.     else if ((N = FNnew(D)) == FlexN0)
  250.         return (void *) 0;
  251.     N->prev = FlexN0;
  252.     if ((N->next = front) != FlexN0)
  253.         N->next->prev = N;
  254.     else
  255.         rear = N;
  256.     front = N;      
  257.     nodes++;
  258.     if (curNum) 
  259.         curNum++;
  260.     sorted = 0;
  261.     return N->data;
  262. }
  263.  
  264. FlexN  FlexList::popN()
  265. {
  266.     FlexN N;
  267.     
  268.     if ((N = front) == FlexN0)
  269.         return FlexN0;
  270.     if (front == rear)
  271.         rear = FlexN0;
  272.     else
  273.         N->next->prev = FlexN0;
  274.     front = N->next;
  275.     nodes--;
  276.     if (curNum)  
  277.         if (!--curNum)
  278.             current = FlexN0;
  279.     N->next = N->prev = FlexN0;
  280.     return N;
  281. }
  282.  
  283. int FlexList::popD(void *D)
  284. {
  285.     FlexN N;
  286.     
  287.     if ((N = front) == FlexN0)
  288.         return 0;
  289.     if (sizeofNodeData)  {
  290.         if (D)
  291.             memcpy(D,N->data,sizeofNodeData);
  292.     }
  293.     else if (!FNdestruct(N->data,D))
  294.         return 0;
  295.     if (front == rear)
  296.         rear = FlexN0;
  297.     else
  298.         N->next->prev = FlexN0;
  299.     front = N->next;
  300.     nodes--;
  301.     if (curNum)  
  302.         if (!--curNum)
  303.             current = FlexN0;
  304.     delete N;
  305.     return 1;
  306. }
  307.  
  308. void * FlexList::topD(void *D)
  309. {
  310.     if (!front) 
  311.         return (void *) 0;
  312.     if (D) if (sizeofNodeData)
  313.         memcpy(D,front->data,sizeofNodeData);
  314.     else if (!FNread(front->data,D))
  315.         return (void *) 0;
  316.     return front->data;
  317. }
  318.  
  319. void * FlexList::insQN(FlexN N)
  320. {
  321.     if (!N || nodes >= maxNodes) 
  322.         return (void *) 0;
  323.     N->next = FlexN0;
  324.     if (rear)
  325.         rear->next = N;
  326.     else
  327.         front = N;
  328.     N->prev = rear;
  329.     rear = N;
  330.     nodes++;
  331.     sorted = 0;
  332.     return N->data;
  333. }
  334.  
  335. void * FlexList::insQD(const void *D)
  336. {
  337.     FlexN N;
  338.  
  339.     if (nodes >= maxNodes) 
  340.         return (void *) 0;
  341.     if (sizeofNode) {  // fixed size FlexNodes
  342.         if ((N = (FlexN) new char [sizeofNode])
  343.             == FlexN0) return (void *) 0;
  344.         if (D) 
  345.             memcpy(N->data,D,sizeofNodeData);
  346.         else
  347.             memset(N->data,0,sizeofNodeData);
  348.     }
  349.     else if (!D)
  350.         return (void *) 0;
  351.     else if ((N = FNnew(D)) == FlexN0)
  352.         return (void *) 0;
  353.     N->next = FlexN0;
  354.     if (rear)
  355.         rear->next = N;
  356.     else
  357.         front = N;
  358.     N->prev = rear;
  359.     rear = N;
  360.     nodes++;
  361.     sorted = 0;
  362.     return N->data;
  363. }
  364.  
  365. void * FlexList::mkcur(unsigned n)
  366. {
  367.   if (!n || (n > nodes))  {  // out of range
  368.     current = 0;
  369.     curNum = 0;
  370.     return (void *) 0;
  371.   }
  372.   else if (n == curNum)  // already there
  373.     return current->data;
  374.   if (current)  // divide list into two parts
  375.     if (n > curNum)  // in last half of list
  376.       if (((nodes >> 1) + (curNum >> 1)) < n)
  377.     // rear closest
  378.     for (current = rear, curNum = nodes;
  379.       curNum > n; curNum--)
  380.       current = current->prev;
  381.       else  // current closest
  382.     for (;curNum < n; curNum++)
  383.       current = current->next;
  384.     else  // in first half of list
  385.       if ((curNum >> 1) < n)  // current closest
  386.     for (;curNum > n; curNum--)
  387.       current = current->prev;
  388.       else  // front closest
  389.     for (current = front, curNum = 1;
  390.       curNum < n; curNum++)
  391.       current = current->next;
  392.   else  // consider whole list
  393.     if ((nodes >> 1) < n)  // closer to rear
  394.       for (current = rear, curNum = nodes; 
  395.     curNum > n; curNum--)
  396.     current = current->prev;
  397.     else  // closer to front
  398.       for (current = front, curNum = 1;
  399.     curNum < n; curNum++)
  400.     current = current->next;
  401.   return current->data;
  402. }
  403.  
  404. void * FlexList::insN(FlexN N)
  405. {
  406.     if (!N || nodes >= maxNodes)
  407.         return (void *) 0;
  408.     if ((N->prev = current) == FlexN0)  {
  409.         if ((N->next = front) == FlexN0)
  410.             rear = N;
  411.         else
  412.             N->next->prev = N;
  413.         front = N;
  414.     }
  415.     else  {  // after current
  416.         if ((N->next = current->next) == FlexN0)
  417.             rear = N;  // last node
  418.         else 
  419.             N->next->prev = N;
  420.         current->next = N;
  421.     }
  422.     current = N;
  423.     curNum++;
  424.     nodes++;
  425.     sorted = 0;
  426.     return N->data;
  427. }
  428.  
  429. void * FlexList::insD(const void *D)
  430. {
  431.     FlexN N;
  432.  
  433.     if (nodes >= maxNodes) 
  434.         return (void *) 0;
  435.     if (sizeofNode) {  // fixed size FlexNodes
  436.         if ((N = (FlexN) new char [sizeofNode])
  437.             == FlexN0) return (void *) 0;
  438.         if (D) 
  439.             memcpy(N->data,D,sizeofNodeData);
  440.         else
  441.             memset(N->data,0,sizeofNodeData);
  442.     }
  443.     else if (!D)
  444.         return (void *) 0;
  445.     else if ((N = FNnew(D)) == FlexN0)
  446.         return (void *) 0;
  447.     if ((N->prev = current) == FlexN0)  {
  448.         if ((N->next = front) == FlexN0)
  449.             rear = N;
  450.         else
  451.             N->next->prev = N;
  452.         front = N;
  453.     }
  454.     else  {  // after current
  455.         if ((N->next = current->next) == FlexN0)
  456.             rear = N;  // last node
  457.         else 
  458.             N->next->prev = N;
  459.         current->next = N;
  460.     }
  461.     current = N;
  462.     curNum++;
  463.     nodes++;
  464.     sorted = 0;
  465.     return N->data;
  466. }
  467.  
  468. void * FlexList::insSortN(FlexN N)
  469. {
  470.     unsigned long low, high;
  471.     void *ok;
  472.  
  473.     if (!N || nodes >= maxNodes || !compare)
  474.         return (void *) 0;
  475.     if (!sorted)
  476.         (void) sort();
  477.     low = 1UL;
  478.     high = (unsigned long) nodes;
  479.     while (low <= high)  
  480.         if ((*compare)(mkcur((unsigned)
  481.             ((low+high) >> 1)),
  482.             N->data) <= 0)
  483.             low = (unsigned long)
  484.                 (curNum + 1);
  485.         else
  486.             high = (unsigned long)
  487.                 (curNum - 1);
  488.     (void) mkcur((unsigned)high);
  489.     ok = insN(N);
  490.     sorted = 1;
  491.     return ok;
  492. }
  493.  
  494. void * FlexList::insSortD(const void *D)
  495. {
  496.     FlexN N;
  497.     unsigned long low, high;
  498.     void *ok;
  499.  
  500.     if (!D || nodes >= maxNodes || !compare) 
  501.         return (void *) 0;
  502.     if (sizeofNode) {  // fixed size FlexNodes
  503.         if ((N = (FlexN) new char [sizeofNode])
  504.             == FlexN0) return (void *) 0;
  505.         memcpy(N->data,D,sizeofNodeData);
  506.     }
  507.     else if ((N = FNnew(D)) == FlexN0)
  508.         return (void *) 0;
  509.     if (!sorted)
  510.         (void) sort();
  511.     low = 1UL;
  512.     high = (unsigned long) nodes;
  513.     while (low <= high)  
  514.         if ((*compare)(mkcur((unsigned)
  515.             ((low+high) >> 1)),
  516.             N->data) <= 0)
  517.             low = (unsigned long)
  518.                 (curNum + 1);
  519.         else
  520.             high = (unsigned long)
  521.                 (curNum - 1);
  522.     (void) mkcur((unsigned)high);
  523.     ok = insN(N);
  524.     sorted = 1;
  525.     return ok;
  526. }
  527.  
  528. FlexN  FlexList::delN()
  529. {
  530.     FlexN N;
  531.  
  532.     if ((N = current) == FlexN0)
  533.         return FlexN0;
  534.     current = N->prev;
  535.     curNum--;
  536.     if (N->next)
  537.         N->next->prev = N->prev;
  538.     else
  539.         rear = N->prev;
  540.     if (N->prev)
  541.         N->prev->next = N->next;
  542.     else
  543.         front = N->next;
  544.     nodes--;
  545.     N->next = N->prev = FlexN0;
  546.     return N;
  547. }
  548.  
  549. int FlexList::delD(void *D)
  550. {
  551.     FlexN N;
  552.  
  553.     if ((N = current) == FlexN0)
  554.         return 0;
  555.     if (sizeofNodeData)  {
  556.         if (D) 
  557.             memcpy(D,N->data,sizeofNodeData);
  558.     }
  559.     else if (!FNdestruct(N->data,D))
  560.         return 0;
  561.     current = N->prev;
  562.     curNum--;
  563.     if (N->next)
  564.         N->next->prev = N->prev;
  565.     else
  566.         rear = N->prev;
  567.     if (N->prev)
  568.         N->prev->next = N->next;
  569.     else
  570.         front = N->next;
  571.     nodes--;
  572.     delete N;
  573.     return 1;
  574. }
  575.  
  576. void * FlexList::nextD(void *D)
  577. {
  578.     FlexN oldCurrent;
  579.  
  580.     if ((oldCurrent = current) != FlexN0)
  581.         current = current->next;
  582.     else
  583.         current = front;
  584.     if (!current) {
  585.         curNum = 0;
  586.         return (void *) 0;
  587.     }
  588.     if (D) if (sizeofNodeData) 
  589.         memcpy(D,current->data,sizeofNodeData);
  590.     else if (!FNread(current->data,D))  {
  591.         current = oldCurrent;
  592.         return (void *) 0;
  593.     }
  594.     curNum++;
  595.     return current->data;
  596. }
  597.  
  598. void * FlexList::prevD(void *D)
  599. {
  600.     FlexN oldCurrent;
  601.     unsigned oldCurNum;
  602.  
  603.     oldCurNum = curNum;
  604.     if ((oldCurrent = current) != FlexN0)  {
  605.         current = current->prev;
  606.         curNum--;
  607.     }
  608.     else  {
  609.         current = rear;
  610.         curNum = nodes;
  611.     }
  612.     if (!current)
  613.         return (void *) 0;
  614.     if (D) if (sizeofNodeData) 
  615.         memcpy(D,current->data,sizeofNodeData);
  616.     else if (!FNread(current->data,D))  {
  617.         curNum = oldCurNum;
  618.         current = oldCurrent;
  619.         return (void *) 0;
  620.     }
  621.     return current->data;
  622. }
  623.  
  624. void * FlexList::findFirstD(const void *D)
  625. {
  626.   unsigned long low, high;
  627.  
  628.   if (!D || !compare)
  629.     return (void *) 0;
  630.   if (sorted)  {
  631.     low = 1UL;
  632.     high = (unsigned long) nodes;
  633.     while (low <= high)  
  634.       if ((*compare)(mkcur((unsigned)
  635.     ((low+high) >> 1)),D) < 0)
  636.     low = (unsigned long) (curNum + 1);
  637.       else
  638.     high = (unsigned long) (curNum - 1);
  639.     if (mkcur((unsigned)high+1))
  640.       if (!(*compare)(current->data,D))
  641.     return current->data;
  642.     // leave at insertion point
  643.     (void) mkcur((unsigned)high);
  644.   }
  645.   else  {
  646.     (void) mkcur();
  647.     while (nextD())
  648.       if (!(*compare)(current->data,D))
  649.     return current->data;  
  650.   }
  651.   return (void *) 0;
  652. }
  653.  
  654. void * FlexList::findNextD(const void *D)
  655. {
  656.     if (!D || !compare) 
  657.         return (void *) 0;
  658.     while (nextD())
  659.         if (!(*compare)(current->data,D))
  660.             return current->data;  
  661.         else if (sorted)
  662.             break;
  663.     return (void *) 0;
  664. }
  665.  
  666. void * FlexList::findLastD(const void *D)
  667. {
  668.   unsigned long low, high;
  669.  
  670.   if (!D || !compare) 
  671.     return (void *) 0;
  672.   if (sorted)  {
  673.     low = 1UL;
  674.     high = (unsigned long) nodes;
  675.     while (low <= high)  
  676.       if ((*compare)(mkcur((unsigned)
  677.     ((low+high) >> 1)),D) <= 0)
  678.     low = (unsigned long) (curNum + 1);
  679.       else
  680.     high = (unsigned long) (curNum - 1);
  681.     if (mkcur((unsigned)high))
  682.       if (!(*compare)(current->data,D))
  683.     return current->data;
  684.   }
  685.   else  {
  686.     (void) mkcur();
  687.     while (prevD())
  688.       if (!(*compare)(current->data,D))
  689.     return current->data;  
  690.   }
  691.   return (void *) 0;
  692. }
  693.  
  694. void * FlexList::findPrevD(const void *D)
  695. {
  696.     if (!D || !compare) 
  697.         return (void *) 0;
  698.     while (prevD())
  699.         if (!(*compare)(current->data,D))
  700.             return current->data;  
  701.         else if (sorted)
  702.             break;
  703.     return (void *) 0;
  704. }
  705.  
  706. int   FlexList::sort(int (*compare)
  707.     (const void *D1, const void *D2))
  708. {
  709.     if (sorted)  {
  710.         if (this->compare == compare || !compare)
  711.             { mkcur(); return 1; }
  712.     }
  713.     else if (!this->compare && !compare) 
  714.         return 0;
  715.     if (compare)
  716.         this->compare = compare;
  717.     if (!nodes)
  718.         return (sorted = 1);
  719.     FlexList tmp(sizeofNodeData);
  720.     tmp.setCompare(this->compare);
  721.     while (nodes)
  722.         (void) tmp.insSortN(popN());
  723.     front = tmp.front;
  724.     rear = tmp.rear;
  725.     nodes = tmp.nodes;
  726.     tmp.front = tmp.current = tmp.rear = FlexN0;
  727.     tmp.curNum = tmp.nodes = 0;
  728.     return (sorted = 1);
  729. }
  730.  
  731. int FlexList::storeD(const void *D, unsigned n)
  732. {
  733.     unsigned oldn;
  734.  
  735.     if (!D || n > nodes || !n && !current)
  736.         return 0;
  737.     if (sizeofNodeData)  {
  738.         if (n) (void) mkcur(n);
  739.         memcpy(current->data,D,sizeofNodeData);
  740.     }
  741.     else  {
  742.         oldn = curNum;
  743.         if (n) (void) mkcur(n);
  744.         if (!FNwrite(current->data,D))
  745.         {
  746.             (void) mkcur(oldn);
  747.             return 0;
  748.         }
  749.     }
  750.     sorted = 0;
  751.     return 1;
  752. }
  753.  
  754. int FlexList::recallD(void *D, unsigned n)
  755. {
  756.     unsigned oldn;
  757.  
  758.     if (!D || n > nodes || !n && !current)
  759.         return 0;
  760.     if (sizeofNodeData)  {
  761.         if (n) (void) mkcur(n);
  762.         memcpy(D,current->data,sizeofNodeData);
  763.     }
  764.     else  {
  765.         oldn = curNum;
  766.         if (n) (void) mkcur(n);
  767.         if (!FNread(current->data,D))
  768.         {
  769.             (void) mkcur(oldn);
  770.             return 0;
  771.         }
  772.     }
  773.     return 1;
  774. }
  775.  
  776. void * FlexList::pack()  // Only fixed nodes!
  777. {
  778.     long sizeofArray;
  779.     char *A, *Ai;
  780.     FlexN N;
  781.  
  782.     sizeofArray = ((long)sizeofNodeData)
  783.         * ((long)nodes);
  784.     if ((sizeofArray <= 0) || 
  785.         (sizeofArray > FLmaxSizeofArray))
  786.         return (void *) 0;
  787.     if ((A = new char [(unsigned) sizeofArray]) 
  788.         == (char *) 0)
  789.         return (void *) 0;
  790.     for (Ai = A, N = front; N; N = N->next,
  791.         Ai += sizeofNodeData)
  792.         memcpy(Ai,N->data,sizeofNodeData);
  793.     return A;
  794. }
  795.  
  796. void **FlexList::packPtrs()
  797. {
  798.     long sizeofArray;
  799.     void **A;
  800.     unsigned Ai;
  801.     FlexN N;
  802.  
  803.     sizeofArray = sizeof(void *) * ((long)nodes + 1);
  804.     if ((sizeofArray <= 0) ||
  805.         (sizeofArray > FLmaxSizeofArray))
  806.         return (void **) 0;
  807.     if ((A = (void **) new char [(unsigned) 
  808.         sizeofArray]) == (void **) 0)
  809.         return (void **) 0;
  810.     for (Ai = 0, N = front; N; Ai++, N = N->next)
  811.         A[Ai] = N->data; 
  812.     A[Ai] = (void *) 0;
  813.     return A;
  814. }
  815.