home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / CIRCBUF.HPP < prev    next >
C/C++ Source or Header  |  1997-07-05  |  7KB  |  171 lines

  1. // +++Date last modified: 05-Jul-1997
  2.  
  3. //
  4. //  CIRCBUF.HPP - Header file for circular buffer C++ functions
  5. //
  6. //  by Bob Stout, originally published in C/C++ Users Journal
  7. //  Use freely
  8. //
  9.  
  10. #ifndef _CIRCBUF_DEFINED_
  11. #define _CIRCBUF_DEFINED_
  12.  
  13. #include <stdlib.h>
  14. #include <string.h>
  15.  
  16. typedef enum {ASSIGNED = -1, ERROR = -1, SUCCESS, FALSE = 0, TRUE} Boolean_T;
  17.  
  18. template<class T> class cbuf_t
  19. {
  20. private:
  21.       size_t      next;       // Wrap-around pointer to next datum
  22.       size_t      current;    // Wrap-around pointer to current datum
  23.       Boolean_T   full;       // TRUE when buffer has filled
  24.       Boolean_T   ready;      // TRUE after init() call...
  25.                               //  ASSIGNED  after import() call...
  26.                               //   else FALSE
  27.  
  28. protected:
  29.       size_t      size;       // Number of elements
  30.       T         * buf;        // Pointer to circular buffer
  31.  
  32. public:
  33.       cbuf_t()           { buf = NULL; next = current = 0;
  34.                            full = ready = FALSE; };
  35.       cbuf_t(size_t len) { init(len); };
  36.       ~cbuf_t()          { if (TRUE == ready) delete buf; };
  37.  
  38.       void        init(size_t);
  39.       Boolean_T   add(T);
  40.       Boolean_T   fetch(T *);
  41.       Boolean_T   data_ready() { return full; };
  42.       Boolean_T   data_avail() { return (next != current); };
  43.       void        data_used()  { current = next; };
  44.       Boolean_T   clear();
  45.       Boolean_T   export(T **, size_t *);
  46.       void        import(T *, size_t);
  47. };
  48.  
  49. /************************************************************************/
  50. /*                                                                      */
  51. /*  init() Circular buffer initializer.                                 */
  52. /*                                                                      */
  53. /*  Arguments: 1 - Number of elements in the circular buffer.           */
  54. /*                                                                      */
  55. /************************************************************************/
  56.  
  57. template<class T> void cbuf_t<T>::init(size_t len)
  58. {
  59.       if (TRUE == ready)
  60.             delete buf;
  61.       else  ready = TRUE;
  62.       size = len;
  63.       buf  = new T[size];
  64.       clear();
  65. }
  66.  
  67. /************************************************************************/
  68. /*                                                                      */
  69. /*  clear() - Clear a circular buffer.                                  */
  70. /*                                                                      */
  71. /*  Returns: ERROR if buffer has not been initialized, else SUCCESS.    */
  72. /*                                                                      */
  73. /************************************************************************/
  74.  
  75. template<class T> Boolean_T cbuf_t<T>::clear()
  76. {
  77.       if (!ready)
  78.             return ERROR;
  79.       memset(buf, 0, size * sizeof(T));
  80.       next = 0;
  81.       full = FALSE;
  82.       return SUCCESS;
  83. }
  84.  
  85. /************************************************************************/
  86. /*                                                                      */
  87. /*  add() - Function to add data to a circular buffer.                  */
  88. /*                                                                      */
  89. /*  Arguments: 1 - Data to add.                                         */
  90. /*                                                                      */
  91. /*  Returns: TRUE if buffer has been filled,                            */
  92. /*           FALSE if buffer has not filled,                            */
  93. /*           ERROR if buffer has not been initialized.                  */
  94. /*                                                                      */
  95. /************************************************************************/
  96.  
  97. template<class T> Boolean_T cbuf_t<T>::add(T data)
  98. {
  99.       if (!ready)
  100.             return ERROR;
  101.       buf[next] = data;
  102.       if (size <= ++next)
  103.       {
  104.             next = 0;
  105.             full = TRUE;
  106.       }
  107.       if (next == current)
  108.             ++current;
  109.       return full;
  110. }
  111.  
  112. /************************************************************************/
  113. /*                                                                      */
  114. /*  fetch() - Function to retrieve data from a circular buffer.         */
  115. /*                                                                      */
  116. /*  Arguments: 1 - Pointer to data storage.                             */
  117. /*                                                                      */
  118. /*  Returns: SUCCESS if datum retrieved, else ERROR.                    */
  119. /*                                                                      */
  120. /************************************************************************/
  121.  
  122. template<class T> Boolean_T cbuf_t<T>::fetch(T *data)
  123. {
  124.       if (!ready || next == current)
  125.             return ERROR;
  126.       *data = buf[current];
  127.       if (size <= ++current)
  128.             current = 0;
  129.       return SUCCESS;
  130. }
  131.  
  132. /************************************************************************/
  133. /*                                                                      */
  134. /*  export() - Publish a circular buffers location and length.          */
  135. /*                                                                      */
  136. /*  Arguments: 1 - Storage for buffer pointer.                          */
  137. /*             2 - Storage for size of buffer.                          */
  138. /*                                                                      */
  139. /*  Returns: ERROR if buffer has not been initialized, else SUCCESS.    */
  140. /*                                                                      */
  141. /************************************************************************/
  142.  
  143. template<class T> Boolean_T cbuf_t<T>::export(T **buffer, size_t *len)
  144. {
  145.       if (!ready)
  146.             return ERROR;
  147.       *buffer = buf;
  148.       *len    = size;
  149.       return SUCCESS;
  150. }
  151.  
  152. /************************************************************************/
  153. /*                                                                      */
  154. /*  import() - Assign an existing circular buffer to a cbuf_t object.   */
  155. /*                                                                      */
  156. /*  Arguments: 1 - Buffer to assign.                                    */
  157. /*             2 - Size of buffer.                                      */
  158. /*                                                                      */
  159. /************************************************************************/
  160.  
  161. template<class T> void cbuf_t<T>::import(T *buffer, size_t len)
  162. {
  163.       if (TRUE == ready)
  164.             delete buf;
  165.       buf   = buffer;
  166.       size  = len;
  167.       ready = ASSIGNED;
  168. }
  169.  
  170. #endif // _CIRCBUF_DEFINED_
  171.