00001
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
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 }
00165
00166 #endif