home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / ncsa_tel / contribu / byu_tel2.hqx / tek / tekstor.c < prev    next >
Text File  |  1988-02-19  |  4KB  |  208 lines

  1. /*
  2.  
  3. tekstor.c by Aaron Contorer, NCSA
  4. Copyright 1987, board of trustees, University of Illinois
  5.  
  6. Character storage routines for use by Telnet VG 
  7.     (virtual graphics screen) routines.
  8. Allocates storage incrementally as more data comes in.
  9. Uses larger and larger increments to avoid inefficiency.
  10. Full data abstraction is provided.
  11.  
  12. Data structure:  
  13.   A unique-type header node begins the data structure.  This points
  14. to the head of a linked list of "handles".  Each handle contains:
  15. > a pointer to a "pool" of storage memory created by malloc()
  16. > an int stating the number of bytes in the pool
  17. > a pointer to the next handle
  18.  
  19. IDEAS FOR IMPROVEMENT:
  20. Store pool as part of handle, rather than pointed to by handle
  21.  
  22. */
  23.  
  24. #define MINPOOL 0x0200    /* smallest allowable pool */
  25. #define MAXPOOL 0x2000    /* largest allowable pool */
  26.  
  27. #include <stdio.h>
  28. #define TRUE 1
  29. #define FALSE 0
  30.  
  31. extern char *malloc();
  32.  
  33. #define STORMASTER
  34. #include "tekstor.h"
  35.  
  36. STOREP newstore()
  37. /* 
  38.     Create a new, empty store and return a pointer to it.
  39.     Returns NULL if not enough memory to create a new store.
  40. */
  41. {
  42.     STOREP s;
  43.     
  44.     s=(STOREP) malloc(sizeof(STORE));
  45.     if (s==NULL) {
  46.         return(NULL);
  47.     }
  48.     else {
  49.         s->lasth = s->thish = s->firsth =
  50.             (HANDLEP) malloc(sizeof(HANDLE));
  51.         if (s->firsth==NULL) {
  52.             free(s);
  53.             return(NULL);
  54.         }
  55.         else {
  56.             s->firsth->pool = malloc(MINPOOL);
  57.             if (s->firsth->pool==NULL) {
  58.                 free(s->firsth);
  59.                 free(s);
  60.                 return(NULL);
  61.             }
  62.             else {
  63.                 s->lastelnum = s->thiselnum = -1;
  64.                 s->firsth->poolsize = MINPOOL;
  65.                 s->firsth->next = NULL;
  66.             }
  67.         }
  68.     }
  69.     return(s);
  70. }
  71.  
  72.  
  73. void freestore(s)
  74. STOREP s;
  75. /*
  76.     Frees all pools and other memory space associated with store s.
  77. */
  78. {
  79.     HANDLEP h,h2;
  80.     h = s->firsth;
  81.     while (h != NULL) {
  82.         h2 = h;
  83.         free(h->pool);
  84.         h = h->next;
  85.         free(h2);
  86.     }
  87.     free(s);
  88. }
  89.  
  90.  
  91. int addstore(s,d)
  92. STOREP s;
  93. char d;
  94. /*
  95.     Adds character d to the end of store s.
  96.     Returns 0 if successful, -1 if unable to add character (no memory).
  97. */
  98. {
  99.     int n; /* temp storage */
  100.     int size;
  101.     HANDLEP h;
  102.  
  103.     n = ++(s->lastelnum);
  104.     size = s->lasth->poolsize;
  105.     if (n < s->lasth->poolsize) {
  106.         s->lasth->pool[n] = d;
  107.     }
  108.     else {
  109.         /* Pool full; allocate a new one. */
  110.         if (size<MAXPOOL) size <<= 1;
  111.         h = (HANDLEP)malloc(sizeof(HANDLE));
  112.         if (h==NULL) {
  113.             (s->lastelnum)--;
  114.             return(-1);
  115.         }
  116.         else {
  117.             h->pool = malloc(size);
  118.             if (h->pool==NULL) {
  119.                 free(h);
  120.                 (s->lastelnum)--;
  121.                 return(-1);
  122.             }
  123.             else {
  124.                 h->poolsize = size;
  125.                 h->next = NULL;
  126.                 s->lasth->next = h;
  127.                 s->lasth = h;
  128.                 s->lastelnum = 0;
  129.                 h->pool[0] = d;
  130.             }
  131.         }
  132.         } /* end of new pool allocation */
  133.     return(0);
  134. } /* end addstore() */
  135.  
  136.  
  137. topstore(s)
  138. STOREP s;
  139. /*
  140.     Reset stats so that a call to nextitem(s) will be retrieving the
  141.     first item in store s.
  142. */
  143. {
  144.     s->thish = s->firsth;
  145.     s->thiselnum = -1;
  146. }
  147.  
  148.  
  149. int nextitem(s)
  150. STOREP s;
  151. /*
  152.     Increment the current location in store s.  Then return the
  153.     character at that location.  Returns -1 if no more characters.
  154. */
  155. {
  156.     HANDLEP h;
  157.  
  158.     if (s->thish==s->lasth && s->thiselnum==s->lastelnum) return(-1);
  159.     else {
  160.         h = s->thish;
  161.         if (++(s->thiselnum) < s->thish->poolsize) {
  162.             return((int)(s->thish->pool[s->thiselnum]));
  163.             }
  164.         else {
  165.             /* move to next pool */
  166.             h = h->next;
  167.             s->thish = h;
  168.             s->thiselnum = 0;
  169.             return((int)(h->pool[0]));
  170.             }
  171.         }
  172. } /* end nextitem() */
  173.  
  174.  
  175. int unstore(s)
  176. STOREP s;
  177. /*
  178.     Removes ("pops") the last item from the specified store.
  179.     Returns that item (in range 0-255), or returns -1 if there
  180.     are no items in the store.
  181. */
  182. {
  183.     HANDLEP nextolast;
  184.  
  185.     if (s->lastelnum > -1) { /* last pool not empty */
  186.         return((int)(s->lasth->pool[(s->lastelnum)--]));
  187.     } else { /* last pool empty */
  188.         if (s->lasth == s->firsth) return(-1);
  189.  
  190.         else { /* move back one pool */
  191.             nextolast = s->firsth;
  192.             while (nextolast->next != s->lasth)
  193.                 nextolast = nextolast->next;
  194.             free(nextolast->next);
  195.             s->lasth = nextolast;
  196.             s->lastelnum = nextolast->poolsize - 2;
  197.  
  198.             if (s->thish == nextolast->next) {
  199.                 s->thish = nextolast;
  200.                 s->thiselnum = s->lastelnum;
  201.             }
  202.  
  203.             nextolast->next = NULL;
  204.             return((int)(nextolast->pool[s->lastelnum+1]));
  205.         }
  206.     }
  207. }
  208.