home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / asycnch / circleq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-01  |  2.7 KB  |  105 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include "circleq.h"
  5.  
  6. /*
  7.  * Qalloc allocates space for a Queue Control Structure (CircleQ) and
  8.  * a buffer to be contained within.
  9.  * If space is not available for this structure, or it's buffer, NULL
  10.  * is returned, otherwise a pointer to a CirclQ is returned.
  11. */
  12. CircleQ * Qalloc(int Size)
  13. {
  14.     CircleQ * Qptr;
  15.     if ((Qptr = calloc(sizeof(CircleQ),1)) == NULL)
  16.     {
  17.         errno = ENOMEM;
  18.         return NULL;
  19.     }
  20.     if ((Qptr->Buffer = calloc(Size,1)) == NULL)
  21.     {
  22.         free(Qptr);
  23.         errno = ENOMEM;
  24.         return NULL ;
  25.     }
  26.     Qptr->Head = Qptr->Tail = Qptr->Buffer;
  27.     Qptr->Size = Size;
  28.     return Qptr;
  29. }
  30. /*
  31.  * QinsertChar inserts a character on a queue. The tail pointer is used
  32.  * to indicate where the character shall be placed. Once a character is
  33.  * written, the tail pointer is updated. If the tail pointer overruns the
  34.  * head pointer, the overrun flag is set. Once the overrun flag is set, the
  35.  * head pointer will be updated on all subsequent writes to ensure that
  36.  * the buffer always contains Qptr->Size characters. If Qptr->Tail or
  37.  * Qptr->Head reach the end of the buffer, they are wrapped around to
  38.  * the beginning of the buffer.
  39. */
  40. void QinsertChar(CircleQ * Qptr, char Ch)
  41. {
  42.     *Qptr->Tail = Ch;
  43.     if ((Qptr->Tail + 1) >= (Qptr->Buffer+Qptr->Size))
  44.         Qptr->Tail = Qptr->Buffer;
  45.     else
  46.         Qptr->Tail ++;
  47.  
  48.     if (Qptr->Head == Qptr->Tail)
  49.         Qptr->Flag = 1;        /* Queue buffer overflow */
  50.  
  51.     if (Qptr->Flag)
  52.         Qptr->Head ++ ;
  53.     if (Qptr->Head >= Qptr->Buffer + Qptr->Size)
  54.         Qptr->Head = Qptr->Buffer;
  55. }
  56. /*
  57.  * QpeekChar returns a character from the specified queue without removing
  58.  * it. If the queue is empty -1 is returned.
  59. */
  60. char QpeekChar(CircleQ * Qptr)
  61. {
  62.     if (Qptr->Head == Qptr->Tail)
  63.     {
  64.         Qptr->Flag = 0;
  65.         return -1;
  66.     }
  67.     return *Qptr->Head;
  68. }
  69. /*
  70.  * QreadChar returns a character from the specified queue. The queue is then
  71.  * updated to reflect the last read. If the queue is empty, -1 is returned.
  72. */
  73. char QreadChar(CircleQ * Qptr)
  74. {
  75.     char Ch = -1;
  76.     if (Qptr->Head == Qptr->Tail)
  77.     {
  78.         Qptr->Flag = 0;
  79.         return -1;
  80.     }
  81.     Ch = *Qptr->Head;
  82.     Qptr->Head ++ ;
  83.     if (Qptr->Head >= Qptr->Buffer + Qptr->Size)
  84.         Qptr->Head = Qptr->Buffer;
  85.     return Ch;
  86. }
  87. /*
  88.  * Qfree frees a queue control structure (CircleQ) and all buffers
  89.  * associated with it (Qptr->Buffer). This Head and Tail pointers are
  90.  * set to NULL, and Size and Flag (overrun flag) are set to 0.
  91.  * Qptr is then freed, releasing all memory associated with the queue.
  92.  * No subsequent operations may be made on this queue.
  93. */
  94. void Qfree(CircleQ * Qptr)
  95. {
  96.     if (Qptr != NULL)
  97.     {
  98.         free(Qptr->Buffer);
  99.         Qptr->Buffer = Qptr->Head = Qptr->Tail = NULL;
  100.         Qptr->Size = Qptr->Flag = 0;
  101.         free(Qptr);
  102.     }
  103. }
  104.  
  105.