home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / par150o2.zip / buffer.c next >
C/C++ Source or Header  |  1996-01-21  |  5KB  |  215 lines

  1. /*********************/
  2. /* buffer.c          */
  3. /* for Par 1.50      */
  4. /* Copyright 1996 by */
  5. /* Adam M. Costello  */
  6. /*********************/
  7.  
  8. /* This is ANSI C code. */
  9.  
  10.  
  11. /* additem(), copyitems(), and nextitem() rely on the fact that */
  12. /* sizeof (char) is 1.  See section A7.4.8 of The C Programming */
  13. /* Language, Second Edition, by Kerninghan and Ritchie.         */
  14.  
  15.  
  16. #include "buffer.h"  /* Makes sure we're consistent with the prototypes. */
  17.                      /* Also includes <stddef.h> and "errmsg.h".         */
  18.  
  19. #include <stdlib.h>
  20. #include <string.h>
  21.  
  22. #undef NULL
  23. #define NULL ((void *) 0)
  24.  
  25. #ifdef DONTFREE
  26. #define free(ptr)
  27. #endif
  28.  
  29.  
  30. struct buffer {
  31.   struct block *firstblk, /* The first block.                    */
  32.                *current,  /* The last non-empty block, or        */
  33.                           /* firstblk if all are empty.          */
  34.                *nextblk;  /* The block containing the item to be */
  35.                           /* returned by nextitem(), or NULL.    */
  36.   int nextindex;          /* Index of item in nextblock->items.  */
  37.   size_t itemsize;        /* The size of an item.                */
  38. };
  39.  
  40. typedef struct block {
  41.   struct block *next;  /* The next block, or NULL if none.              */
  42.   void *items;         /* Storage for the items in this block.          */
  43.   int maxhere,         /* Number of items that fit in *items.           */
  44.       numprevious,     /* Total of numhere for all previous blocks.     */
  45.       numhere;         /* The first numhere slots in *items are filled. */
  46. } block;
  47.  
  48.  
  49. buffer *newbuffer(size_t itemsize, errmsg_t errmsg)
  50. {
  51.   buffer *buf;
  52.   block *blk;
  53.   void *items;
  54.   int maxhere;
  55.  
  56.   maxhere = 124 / itemsize;
  57.   if (maxhere < 4) maxhere = 4;
  58.  
  59.   buf = malloc(sizeof (buffer));
  60.   blk = malloc(sizeof (block));
  61.   items = malloc(maxhere * itemsize);
  62.   if (!buf || !blk || !items) {
  63.     strcpy(errmsg,outofmem);
  64.     goto nberror;
  65.   }
  66.  
  67.   buf->itemsize = itemsize;
  68.   buf->firstblk = buf->current = buf->nextblk = blk;
  69.   buf->nextindex = 0;
  70.   blk->next = NULL;
  71.   blk->numprevious = blk->numhere = 0;
  72.   blk->maxhere = maxhere;
  73.   blk->items = items;
  74.  
  75.   *errmsg = '\0';
  76.   return buf;
  77.  
  78. nberror:
  79.  
  80.   if (buf) free(buf);
  81.   if (blk) free(blk);
  82.   if (items) free(items);
  83.   return NULL;
  84. }
  85.  
  86.  
  87. void freebuffer(buffer *buf)
  88. {
  89.   block *blk, *tmp;
  90.  
  91.   blk = buf->firstblk;
  92.   while (blk) {
  93.     tmp = blk;
  94.     blk = blk->next;
  95.     if (tmp->items) free(tmp->items);
  96.     free(tmp);
  97.   }
  98.  
  99.   free(buf);
  100. }
  101.  
  102.  
  103. void clearbuffer(buffer *buf)
  104. {
  105.   block *blk;
  106.  
  107.   for (blk = buf->firstblk;  blk;  blk = blk->next)
  108.     blk->numhere = 0;
  109.  
  110.   buf->current = buf->firstblk;
  111. }
  112.  
  113.  
  114. void additem(buffer *buf, const void *item, errmsg_t errmsg)
  115. {
  116.   block *blk, *new;
  117.   void *items;
  118.   int maxhere;
  119.   size_t itemsize = buf->itemsize;
  120.  
  121.   blk = buf->current;
  122.  
  123.   if (blk->numhere == blk->maxhere) {
  124.     new = blk->next;
  125.     if (!new) {
  126.       maxhere = 2 * blk->maxhere;
  127.       new = malloc(sizeof (block));
  128.       items = malloc(maxhere * itemsize);
  129.       if (!new || !items) {
  130.         strcpy(errmsg,outofmem);
  131.         goto aierror;
  132.       }
  133.       blk->next = new;
  134.       new->next = NULL;
  135.       new->maxhere = maxhere;
  136.       new->numprevious = blk->numprevious + blk->numhere;
  137.       new->numhere = 0;
  138.       new->items = items;
  139.     }
  140.     blk = buf->current = new;
  141.   }
  142.  
  143.   memcpy( ((char *) blk->items) + (blk->numhere * itemsize), item, itemsize );
  144.  
  145.   ++blk->numhere;
  146.  
  147.   *errmsg = '\0';
  148.   return;
  149.  
  150. aierror:
  151.  
  152.   if (new) free(new);
  153.   if (items) free(items);
  154. }
  155.  
  156.  
  157. int numitems(buffer *buf)
  158. {
  159.   block *blk = buf->current;
  160.   return blk->numprevious + blk->numhere;
  161. }
  162.  
  163.  
  164. void *copyitems(buffer *buf, errmsg_t errmsg)
  165. {
  166.   int n;
  167.   void *r;
  168.   block *blk, *b;
  169.   size_t itemsize = buf->itemsize;
  170.  
  171.   b = buf->current;
  172.   n = b->numprevious + b->numhere;
  173.   if (!n) return NULL;
  174.  
  175.   r = malloc(n * itemsize);
  176.   if (!r) {
  177.     strcpy(errmsg,outofmem);
  178.     return NULL;
  179.   }
  180.  
  181.   b = b->next;
  182.  
  183.   for (blk = buf->firstblk;  blk != b;  blk = blk->next)
  184.     memcpy( ((char *) r) + (blk->numprevious * itemsize),
  185.             blk->items, blk->numhere * itemsize);
  186.  
  187.   *errmsg = '\0';
  188.   return r;
  189. }
  190.  
  191.  
  192. void rewindbuffer(buffer *buf)
  193. {
  194.   buf->nextblk = buf->firstblk;
  195.   buf->nextindex = 0;
  196. }
  197.  
  198.  
  199. void *nextitem(buffer *buf)
  200. {
  201.   void *r;
  202.  
  203.   if (!buf->nextblk || buf->nextindex >= buf->nextblk->numhere)
  204.     return NULL;
  205.  
  206.   r = ((char *) buf->nextblk->items) + (buf->nextindex * buf->itemsize);
  207.  
  208.   if (++buf->nextindex >= buf->nextblk->maxhere) {
  209.     buf->nextblk = buf->nextblk->next;
  210.     buf->nextindex = 0;
  211.   }
  212.  
  213.   return r;
  214. }
  215.