Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

Buffer.h

00001 // Copyright (C) 1999 Jean-Marc Valin
00002 
00003 #ifndef BUFFER_H
00004 #define BUFFER_H
00005 
00006 #include "Object.h"
00007 #include "ObjectRef.h"
00008 #include "Exception.h"
00009 #include <typeinfo>
00010 #include <vector>
00011 
00012 namespace FD {
00013 
00016 class Buffer : public Object {
00017 protected:
00019    mutable std::vector<ObjectRef> data;
00020 
00021    mutable std::vector<int> flags;
00022 
00024    int bufferLength ;
00025 
00026    mutable int bufferPos;
00027 
00028    mutable int currentPos;
00029 
00030 
00031 public:
00033    Buffer(int bLength)
00034       : data(bLength)
00035       , flags(bLength,0)
00036       , bufferLength (bLength)
00037    {
00038       bufferPos=-1;
00039       currentPos = -1;
00040    }
00041 
00043    Buffer(const Buffer&);
00044 
00046    inline ObjectRef &get(int ind) const;
00047 
00049    inline ObjectRef &operator[] (int ind);
00050    
00051    int isValid(int ind) const
00052    {
00053       if (ind > currentPos || ind <= currentPos-bufferLength)
00054          return false;
00055       int tmp = bufferPos+ind-currentPos;
00056       if (tmp < 0)
00057          tmp += bufferLength;
00058       return flags[tmp];
00059    }
00060 
00062    void printOn(std::ostream &out = std::cout) const;
00063 
00064    int getCurrentPos() {return currentPos;}
00065 
00066 };
00067 
00068 
00069 class BufferException : public BaseException {
00070 public:
00072    BufferException(const Buffer *_buffer, std::string _message, int _element) 
00073       : buffer (_buffer)
00074       , message(_message)
00075       , element(_element)
00076    {}
00077 
00079    virtual void print(std::ostream &out = std::cerr) 
00080    {
00081       out<< typeid(buffer).name() << " error: "<< message << ".\nElement " << element << std::endl;
00082       out << "Buffer is: \n";
00083       out << *buffer;
00084    }
00085 protected:
00087    const Buffer *buffer;
00088 
00090    std::string message;
00091 
00093    int element;
00094 };
00095 
00096 
00097 inline ObjectRef & Buffer::operator[] (int ind) 
00098 {
00099    if (ind < 0 || ind <= currentPos-bufferLength)
00100    {
00101       throw new BufferException (this, "trying to write to non-existing element",ind);
00102    }
00103    if (ind > currentPos)
00104    {
00105       int diff = ind-currentPos;
00106       while (diff--)
00107       {
00108          bufferPos++;
00109          if (bufferPos == bufferLength)
00110             bufferPos=0;
00111          flags[bufferPos] = 0;
00112       }
00113       currentPos = ind;
00114       flags[bufferPos] = 1;
00115       return data[bufferPos];
00116    }
00117    
00118    int tmp = bufferPos+ind-currentPos;
00119    if (tmp < 0)
00120       tmp += bufferLength;
00121    flags[tmp] = 1;
00122    return data[tmp];
00123 }
00124 
00125 inline ObjectRef &Buffer::get(int ind) const
00126 {
00127    if (ind < 0 || ind <= currentPos-bufferLength || ind > currentPos)
00128    {
00129       throw new BufferException (this, "trying to read non-existing element",ind);
00130    }
00131    int tmp = bufferPos+ind-currentPos;
00132    if (tmp < 0)
00133       tmp += bufferLength;
00134    if (flags[tmp])
00135       return data[tmp];
00136    else 
00137       throw new BufferException (this, "trying to read not initialized element",ind);
00138 }
00139 
00140 
00141 inline void Buffer::printOn(std::ostream &out) const
00142 {
00143    int i;
00144    //cerr << "printing... currentPos = " << currentPos << " bufferLength = " << bufferLength << std::endl;
00145    out << "<Buffer" << std::endl;
00146    for (i=currentPos-bufferLength+1;i<=currentPos;i++)
00147    {
00148       if (i>=0)
00149       {
00150          out << "< " << i << " ";
00151          if (isValid(i))
00152             out << get(i);
00153          else
00154             out << "nil";
00155       }
00156    }
00157    out << " >" << std::endl;
00158 }
00159 
00160 
00161 inline Buffer::Buffer(const Buffer&)
00162 {throw new BufferException(NULL,"use an ObjectRef instead",0);}
00163 
00164 }//namespace FD
00165 
00166 #endif

Generated on Wed Oct 5 14:28:55 2005 for FlowDesigner by  doxygen 1.4.4