name: CircularBuffer<class TObject>
synopsis:

>     g++ [flags ...] file ...

>     #include <CircularBuffer.h>
>     CircularBuffer(long capacity = DEF_BUF_CAPACITY);
>     boolean append(const TObject in);
>     boolean append(const Vector>TObject<& in);
>     boolean seekCurr(long offset);
>     boolean setRead(long num_read = DEF_NUM_READ);

quick start:

>     // declare a Float CircularBuffer of capacity 5
>     //
>     CircularBuffer<Float> cbuf(5);

>     for (long i = 0; i < 5; i++) {
>       Float num((float)i);
>       cbuf.append(num);
>     }

>     // check the number of elements and if the buffer is full
>     //
>     if (cbuf.getNumElements() != 5 || !cbuf.isFull()) {
>          // error
>       }
>     }

description:
The CircularBuffer class is a circular Vector of TObjects. A CircularBuffer has a read, a write and a current index indicating positions in the Vector. The elements between the read and write indices are the valid elements. When new data is added to the CircularBuffer, it is appended to the position next to the write index, then the write index is advanced. The read index is used to indicate that you have read those data, so they are allowed to be overwritten by the new data. If the CircularBuffer is full, new data are not allowed to be added until some of the current data have been read.
dependencies:

- Vector
- Float
- Console
- MemoryManager

public constants:

- define the class name:

      static const String CLASS_NAME = L"CircularBuffer";

- i/o related constants:

      static const String DEF_PARAM;

      static const String PARAM_VALUES;

      static const String PARAM_CAPACITY;

      static const String PARAM_READ;

      static const String PARAM_WRITE;

      static const String PARAM_CURR;

- default values and arguments:

      static const long DEF_BUF_CAPACITY = 8192;

      static const long DEF_READ_IDX = 0;

      static const long DEF_WRITE_IDX = -1;

      static const long DEF_CURR_IDX = 0;

      static const long DEF_OFFSET = 0;

      static const long DEF_NUM_READ = 1;

error codes:

- general CircularBuffer class error:

      static const long ERR = 41600;

      static const long ERR = 41610;

protected data:

- declare a vector of data objects:

      Vector<TObject> v_d

- declare the position indices:

       long read_d;

       long write_d;

       long curr_d;

- declare the debugging parameters:

      static Integral::DEBUG debug_level_d;

- static memory manager:

      static MemoryManager mgr_d;

required public methods:

- static methods: diagnose method is moved outside the class header file and defined in the CircularBufferDiagnose.h in order to avoid the issues with the preprocessing of the diagnose code

      static const String& name();

      static boolean diagnose(Integral::DEBUG debug_level);

- debug methods:

      static boolean setDebug(Integral::DEBUG debug_level);

      boolean debug(const unichar* message) const;

- destructor/constructor(s):

      ~CircularBuffer();

      CircularBuffer(long capacity = DEF_BUF_CAPACITY);

      CircularBuffer(const CircularBuffer<TObject>& copy_cbuf);

- assign methods:

      boolean assign(const CircularBuffer<TObject>& copy_cbuf);

- operator= methods:

      CircularBuffer& operator=(const CircularBuffer<TObject>& arg);

- i/o methods: refer to the notes section for an explanation of having two read and write methods in this class

      long sofSize() const;

      boolean read(Sof& sof, long tag);

      boolean write(Sof& sof, long tag) const;

      boolean read(Sof& sof, long tag, const String& name);

      boolean write(Sof& sof, long tag, const String& name) const;

      boolean readData(Sof& sof, const String& pname = DEF_PARAM,long size = SofParser::FULL_OBJECT, boolean param_a = true, boolean nested_a = false);

      boolean writeData(Sof& sof, const String& name = DEF_PARAM) const;

- equality methods:

      boolean eq(const CircularBuffer<TObject>& compare_cbuf) const;

- memory management methods:

      static void* operator new(size_t size);

      static void* operator new[](size_t size);

      static void operator delete(void* ptr);

      static void operator delete[](void* ptr);

      static boolean setGrowSize(long grow_size);

      boolean clear(Integral::CMODE cmode = Integral::DEF_CMODE);

class-specific public methods:

- operator overload methods:

      CircularBuffer<TObject>& operator() (long offset);

      const CircularBuffer<TObject>& operator() (long offset) const;

- get element methods:

      boolean getElement(TObject& out, long offset = DEF_OFFSET) const;

      boolean getElement(Vector<TObject>& out, long num_elem, long offset = DEF_OFFSET) const;

- get number of element methods:

      long getNumElements() const;

      long getNumForward() const

      long getNumBackward() const;

- status checking methods:

      boolean isFull() const;

      boolean isEmpty() const;

- resize methods:

      long getCapacity() const;

      boolean setCapacity(long capacity, boolean preserve_values = true);

- data manipulation methods:

      boolean append(const TObject& in);

      boolean append(const Vector<TObject>& in);

      boolean append(const Vector<TObject>& in, long num_elem, long invec_offset = DEF_OFFSET);

      boolean prepend(const TObject& in);

      boolean prepend(const Vector<TObject>& in);

      boolean prepend(const Vector<TObject>& in, long num_elem, long invec_offset = DEF_OFFSET);

- position methods:

      boolean resetCurr();

      boolean seekCurr(long offset);

      boolean setRead(long num_read = DEF_NUM_READ);

private methods:

- none.

friend classes:

- none

examples:

- This example shows how to construct a CircularBuffer and check its status:

      #include <Long.h>
      #include <CircularBuffer.h>

      int main () {

        // declare a circular buffer of long
        //
        CircularBuffer<Long> cbuf(50);

        // prepare data
        //
        Vector<Long> longs(100);
        for (long i = 0; i <100; i++) {
          longs(i) = i;
        }

        // add the data to the buffer
        //
        cbuf.append(longs, 50, 0);               // [0 - 50] were appended

        // the buffer should be full now
        //
        if (!cbuf.isFull()) {

          // exit
          //
          Integral::exit();
        }

        // release some data in buffer and append more data
        //
        cbuf.setRead(40);

        cbuf.append(longs, 10, 50);               // [0 - 9] were overwritten

        // display the contents of the circular buffer
        //
        cbuf.debug(L"cbuf");

        // exit gracefully
        //
        Integral::exit();
      }

notes:

- There is no memory allocation mode for the CircularBuffer class. CircularBuffer always operates in SYSTEM mode. The objects contained within a CircularBuffer can use either allocation mode by invoking their setAllocationMode method.
- Unlike other classes, we have two read and write methods in dstr classes. The interface is still the same as that in other classes. The reason behind this is that we cannot use "CLASS_NAME" as a default argument in the read and write methods here because the data structures build the class name on the fly.