home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / quot210s.zip / xtype / src / xarray.c < prev    next >
C/C++ Source or Header  |  1998-09-10  |  6KB  |  248 lines

  1. /*
  2.  * xarray.c
  3.  *
  4.  * Routines for extensible arrays. No bounds-checking is performed by any
  5.  * of these functions.
  6.  *
  7.  *      Created: 25th January 1998
  8.  * Version 1.00: 26th January 1998
  9.  *
  10.  * (C) 1998 Nicholas Paul Sheppard. See the file licence.txt for details.
  11.  */
  12.  
  13. #include <memory.h>
  14. #include <stdlib.h>
  15. #include "xtype.h"
  16.  
  17.  
  18. XARRAY *xaappend(XARRAY *xa, void *pElem)
  19. /*
  20.  * Append an element to the end of an extensible array.
  21.  *
  22.  * XARRAY *xa    - the array to be added to
  23.  * void *pElem    - pointer to the element to be added
  24.  *
  25.  * Returns    - NULL if there is a memory allocation failure
  26.  *          xa, otherwise
  27.  */
  28. {
  29.     void *    p;    /* temporary pointer */
  30.  
  31.     /* check that we have sufficient space */
  32.     p = NULL;
  33.     if (xa->iSize < (xalen(xa) + 1)) {
  34.         if ((p = realloc(xa->pData, (xa->iSize + xa->iBlock) * xa->iElemSize)) == NULL) {
  35.             return (NULL);
  36.         } else {
  37.             xa->pData = p;
  38.             xa->iSize += xa->iBlock;
  39.         }
  40.     }
  41.  
  42.     /* add the element */
  43.     xaput(xa, xa->iCount++, pElem);
  44.  
  45.     return (xa);
  46. }
  47.  
  48.  
  49. void *xacvt(XARRAY *xa)
  50. /*
  51.  * Convert an extensible array into a normal array (i.e. get rid of all the
  52.  * extraneous structure that the extensible array uses). Do not use xa after
  53.  * calling this function. Unless the array is of voids (?), the output from
  54.  * this function should also be typecast appropriately.
  55.  *
  56.  * XARRAY *xa    - the extensible array to be converted
  57.  *
  58.  * Returns    - (a pointer to) the array block represented by xa
  59.  */
  60. {
  61.     void *    p;    /* return value */
  62.  
  63.     if (xa != NULL) {
  64.         p = xa->pData;
  65.         free(xa);
  66.     } else {
  67.         p = NULL;
  68.     }
  69.  
  70.     return (p);
  71. }
  72.  
  73.  
  74. void xafree(XARRAY *xa)
  75. /*
  76.  * De-allocate the memory used by an extensible array.
  77.  *
  78.  * XARRAY *xa    - the extensible array to be de-allocated
  79.  */
  80. {
  81.     if (xa != NULL) {
  82.         free(xa->pData);
  83.         free(xa);
  84.     }
  85. }
  86.  
  87.  
  88. void *xaget(XARRAY *xa, int iPos, void *pElem)
  89. /*
  90.  * Get the value of an extensible array element.
  91.  *
  92.  * XARRAY *xa    - the extensible array to have its element changed
  93.  * int iPos    - the position of the element to set
  94.  * void *pElem    - a pointer to receive the element
  95.  *
  96.  * Returns    - pElem
  97.  */
  98. {
  99.     char *    p;    /* temporary pointer */
  100.  
  101.     /* make p point to the appropriate spot in the array */
  102.     p = (char *)xa->pData;
  103.     p += iPos * xa->iElemSize;
  104.  
  105.     /* copy the data into the output space */
  106.     memcpy(pElem, p, xa->iElemSize);
  107.  
  108.     return (pElem);
  109. }
  110.  
  111.  
  112. XARRAY *xainsert(XARRAY *xa, int iPos, void *pElem)
  113. /*
  114.  * Insert an element into an extensible array.
  115.  *
  116.  * XARRAY *xa    - the extensible array to insert an element into
  117.  * int iPos    - the position to insert the new element into
  118.  * void *pElem    - pointer to the element to be added
  119.  *
  120.  * Returns    - NULL if there is a memory allocation failure
  121.  *          xa, otherwise
  122.  */
  123. {
  124.     char *    p1;    /* temporary pointer */
  125.     char *    p2;    /* temporary pointer */
  126.     int    i;    /* counter */
  127.  
  128.     /* check that we have sufficient space */
  129.     p1 = NULL;
  130.     if (xa->iSize < (xalen(xa) + 1)) {
  131.         if ((p1 = realloc(xa->pData, (xa->iSize + xa->iBlock) * xa->iElemSize)) == NULL) {
  132.             return (NULL);
  133.         } else {
  134.             xa->pData = p1;
  135.             xa->iSize += xa->iBlock;
  136.         }
  137.     }
  138.  
  139.     /* move elements after the insertion point */
  140.     p1 = (char *)xa->pData;
  141.     p1 += (xa->iCount - 1) * xa->iElemSize;
  142.     p2 = p1 + xa->iElemSize;
  143.     for (i = xa->iCount; i > iPos; i--) {
  144.         memcpy(p2, p1, xa->iElemSize);
  145.         p1 -= xa->iElemSize;
  146.         p2 -= xa->iElemSize;
  147.     }
  148.  
  149.     /* copy the new element in */
  150.     memcpy(p1, pElem, xa->iElemSize);
  151.     xa->iCount++;
  152.  
  153.     return (xa);
  154. }
  155.  
  156.  
  157. XARRAY *xanew(int iSize, int iBlock, int iElemSize)
  158. /*
  159.  * Create a new extensible array.
  160.  *
  161.  * int iSize        - the initial number of elements in the array
  162.  * int iBlock        - the number of elements to grow the array by
  163.  * int iElemSize    - the size of the array elements
  164.  *
  165.  * Returns        - NULL if there is a memory allocation failure
  166.  *              a pointer to he new extensible array, otherwise
  167.  */
  168. {
  169.     XARRAY *    xa;    /* return value */
  170.  
  171.     if ((xa = (XARRAY *)malloc(sizeof(XARRAY))) != NULL) {
  172.         xa->iSize = iSize;
  173.         xa->iBlock = iBlock;
  174.         xa->iElemSize = iElemSize;
  175.         xa->iCount = 0;
  176.         if ((xa->pData = calloc(iSize, iElemSize)) == NULL) {
  177.             free(xa);
  178.             xa = NULL;
  179.         }
  180.     }
  181.  
  182.     return (xa);
  183. }
  184.  
  185.  
  186. XARRAY *xaput(XARRAY *xa, int iPos, void *pElem)
  187. /*
  188.  * Set the value of an extensible array element. No bounds-checking is
  189.  * performed.
  190.  *
  191.  * XARRAY *xa    - the extensible array to have its element changed
  192.  * int iPos    - the position of the element to set
  193.  * void *pElem    - a pointer to the value of the element
  194.  *
  195.  * Returns    - xa
  196.  */
  197. {
  198.     char *    p;    /* temporary pointer */
  199.  
  200.     /* make p point to the appropriate spot in the array */
  201.     p = (char *)xa->pData;
  202.     p += iPos * xa->iElemSize;
  203.  
  204.     /* copy the new data into the array */
  205.     memcpy(p, pElem, xa->iElemSize);
  206.  
  207.     return (xa);
  208. }
  209.  
  210.  
  211. XARRAY *xashrink(XARRAY *xa, int iBottom, int iTop)
  212. /*
  213.  * Shrink an array by removing a given range (inclusive).
  214.  *
  215.  * XARRAY *xa    - the extensible array to be shrunk
  216.  * int iBottom    - lower bound of range to eliminate
  217.  * int iTop    - upper bound of range to eliminate
  218.  *
  219.  * Returns    - xa
  220.  */
  221. {
  222.     char *    p1;    /* temporary pointer */
  223.     char *    p2;    /* temporary pointer */
  224.     int    i;    /* counter */
  225.  
  226.     /* move elements above the range down */
  227.     p1 = p2 = (char *)xa->pData;
  228.     p1 += iBottom * xa->iElemSize;
  229.     p2 += iTop * xa->iElemSize;
  230.     for (i = iBottom; i <= iTop; i++) {
  231.         memcpy(p1, p2, xa->iElemSize);
  232.         p1 += xa->iElemSize;
  233.         p2 += xa->iElemSize;
  234.     }
  235.     xa->iCount -= iTop - iBottom + 1;
  236.  
  237.     /* reduce the memory allocation, if we can */
  238.     i = xa->iSize;
  239.     while ((i - xa->iBlock) > xa->iCount)
  240.         i -= xa->iBlock;
  241.     if (i < xa->iSize) {
  242.         xa->pData = realloc(xa->pData, i * xa->iElemSize);
  243.         xa->iSize = i;
  244.     }
  245.  
  246.     return (xa);
  247. }
  248.