00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _tcirculararray_h
00018 #define _tcirculararray_h
00019
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022
00023 #ifdef _WINDOWS
00024 #include <spl/configwin32.h>
00025 #else
00026 #include <spl/autoconf/config.h>
00027 #endif
00028
00029 #include <spl/Exception.h>
00030 #include <spl/Memory.h>
00031
00037 class CircularArrayException : Exception
00038 {
00039 public:
00040 CircularArrayException(const char *msg);
00041 };
00042
00044 template<typename T>
00045 class CircularArray: public IMemoryValidate
00046 {
00047 protected:
00048 int m_size;
00049 T *m_array;
00050 int m_writepos;
00051 int m_readpos;
00052
00053 public:
00054 CircularArray( int size ) : m_writepos(0), m_readpos(0)
00055 {
00056 m_size = size;
00057 m_array = new T[size];
00058 }
00059
00060 CircularArray( const CircularArray<T>& ar )
00061 : m_writepos(ar.m_writepos), m_readpos(ar.m_readpos), m_size(ar.m_size)
00062 {
00063 m_array = new T[m_size];
00064 for ( int x = 0; x < m_size; x++ )
00065 {
00066 m_array[x] = ar.m_array[x];
00067 }
00068 }
00069
00070 virtual ~CircularArray()
00071 {
00072 delete m_array;
00073 }
00074
00075 void Write( T data )
00076 {
00077 ASSERT_MEM( m_array, m_size*sizeof(T) );
00078 if ( m_size == m_writepos )
00079 {
00080 m_writepos = 0;
00081 }
00082 m_array[m_writepos++] = data;
00083 if ( m_writepos == m_readpos )
00084 {
00085 throw new CircularArrayException("insert overwrote read pos -- make array larger");
00086 }
00087 }
00088
00089 void Write( T *data, int start, int len )
00090 {
00091 int end = len + start;
00092 for ( int x = start; x < end; x++ )
00093 {
00094 write( data[x] );
00095 }
00096 }
00097
00098 void Read( T *data )
00099 {
00100 ASSERT_MEM( m_array, m_size*sizeof(T) );
00101 if ( m_readpos == m_writepos )
00102 {
00103 CircularArrayException("EOF");
00104 }
00105 if ( m_readpos == m_size )
00106 {
00107 m_readpos = 0;
00108 }
00109 *data = m_array[m_readpos++];
00110 }
00111
00112 void Read( T *data, int start, int len )
00113 {
00114 int end = len + start;
00115 for ( int x = start; x < end; x++ )
00116 {
00117 Read( &data[x] );
00118 }
00119 }
00120
00121 int Count() const
00122 {
00123 if ( m_writepos >= m_readpos )
00124 {
00125 return m_writepos - m_readpos;
00126 }
00127 return m_size - m_readpos + m_writepos;
00128 }
00129
00130 T Peek( int offset ) const
00131 {
00132 ASSERT_MEM( m_array, m_size*sizeof(T) );
00133 int pos = m_readpos + offset;
00134 if ( offset == m_writepos )
00135 {
00136 CircularArrayException("EOF");
00137 }
00138 if ( pos >= m_size )
00139 {
00140 pos -= m_size;
00141 }
00142 return m_array[pos];
00143 }
00144
00145 int LocateElement( T item ) const
00146 {
00147 int cnt = Count();
00148 for ( int x = 0; x < cnt; x++ )
00149 {
00150 if ( Peek(x) == item )
00151 {
00152 return x;
00153 }
00154 }
00155 return -1;
00156 }
00157
00158 CircularArray<T>& operator =( const CircularArray<T>& ar )
00159 {
00160 delete[] m_array;
00161
00162 m_writepos = ar.m_writepos;
00163 m_readpos = ar.m_readpos;
00164 m_size = ar.m_size;
00165
00166 m_array = new T[m_size];
00167 for ( int x = 0; x < m_size; x++ )
00168 {
00169 m_array[x] = ar.m_array[x];
00170 }
00171
00172 return *this;
00173 }
00174
00175 #ifdef DEBUG
00176 virtual void ValidateMem() const
00177 {
00178 ASSERT_MEM(m_array, m_size*sizeof(T));
00179 }
00180
00181 virtual void CheckMem() const
00182 {
00183 DEBUG_NOTE_MEM_ALLOCATION(m_array);
00184 for ( int x = 0; x < m_size; x++ )
00185 {
00186 ValidateType(m_array[x]);
00187 }
00188 }
00189 #endif
00190 };
00191
00194 #endif