PhantomBuffer.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef _PHANTOM_BUFFER_H
00023 #define _PHANTOM_BUFFER_H
00024 
00025 
00026 #include <vector>
00027 #include "Assert.hxx"
00028 
00029 namespace CLAM {
00030 
00031         template<class T>
00032         class PhantomBuffer 
00033         {
00034         public:
00035                 PhantomBuffer();
00036                 T*   Read(unsigned int pos, unsigned int size);
00037 
00043                 void Touch(unsigned int pos, unsigned int size);
00044 
00050                 void Write(unsigned int pos, unsigned int size,const T* data);
00051 
00052                 unsigned LogicalSize() const {return mLogicalSize;}
00053                 
00054                 unsigned int PhantomSize() const { return mBuffer.size() - mLogicalSize; }
00055 
00056                 void Resize(unsigned int size,
00057                             unsigned int phantom,
00058                             unsigned int insert_pos);
00059         
00066                 void FulfilsInvariant() const;
00067 
00068         private:
00073                 void UpdatePhantom(unsigned int pos, unsigned int size);
00078                 void UpdateBeginning(unsigned int pos, unsigned int size);
00079 
00080                 unsigned int AllocatedSize() const
00081                 { 
00082                         return mBuffer.size(); 
00083                 }
00084 
00085         
00086                 // attributes
00087                 std::vector<T> mBuffer;
00088                 unsigned mLogicalSize;
00089         };
00090 
00091         
00092         template<class T>
00093         PhantomBuffer<T>::PhantomBuffer()
00094                 : mLogicalSize(0) 
00095         {}
00096 
00097 
00098         template<class T>
00099         void PhantomBuffer<T>::UpdatePhantom(unsigned int pos, unsigned int size)
00100         {
00101                 CLAM_DEBUG_ASSERT(pos+size <= PhantomSize(),
00102                                  "PhantomBuffer::UpdatePhantom():"
00103                                  "Requested region falls outside phantom zone");
00104                 unsigned int s,d;
00105                 for (s=pos, d=mLogicalSize+pos; s<pos+size; s++, d++)
00106                         mBuffer[d] = mBuffer[s];
00107         }
00108 
00109         template<class T>
00110         void PhantomBuffer<T>::UpdateBeginning(unsigned int pos, unsigned int size)
00111         {
00112                 CLAM_DEBUG_ASSERT(pos+size <= PhantomSize(),
00113                                  "PhantomBuffer::UpdateBeginning():"
00114                                  "Requested region falls outside beginning zone");
00115                 unsigned int s,d;
00116                 for (d=pos, s=mLogicalSize+pos; d<size; d++, s++)
00117                         mBuffer[d] = mBuffer[s];
00118         }
00119 
00120 
00121         template<class T>
00122         void PhantomBuffer<T>::Resize(unsigned int newLogicalSize, unsigned int newPhantomSize, unsigned int insertionPos)
00123         {
00124                 CLAM_ASSERT(insertionPos <= LogicalSize(),
00125                            "PhantomBuffer::Resize(): "
00126                            "Insertion position can not be greater than previous size.");
00127                 CLAM_ASSERT(newPhantomSize <= newLogicalSize,
00128                            "PhantomBuffer::Resize(): Phantom Size can not be greater than size.");
00129 
00130 
00131                 if ( newLogicalSize <= LogicalSize() )
00132                         return;
00133 
00134                 CLAM_ASSERT(newPhantomSize >= PhantomSize(),
00135                            "PhantomBuffer::Resize(): PhantomSize can not be decreased.");
00136 
00137                 unsigned int logicalElementsToInsert = newLogicalSize - LogicalSize();
00138                 unsigned int phantomElementsToInsert = newPhantomSize - PhantomSize();
00139 
00140                 typename std::vector<T>::iterator it = mBuffer.begin();
00141                 it += insertionPos;
00142                 mBuffer.insert(it, logicalElementsToInsert, T());
00143 
00144                 mBuffer.insert( mBuffer.end(), phantomElementsToInsert,  T());
00145                 //TODO update phantom
00146 
00147                 mLogicalSize = newLogicalSize;
00148         }
00149 
00150 
00151         template<class T>
00152         T* PhantomBuffer<T>::Read(unsigned int pos, unsigned int size)
00153         {
00154                 CLAM_DEBUG_ASSERT( (pos+size-1) <= ( AllocatedSize() ),
00155                                   "PhantomBuffer::Read(): Position outside bounds");
00156                 return &mBuffer[pos];
00157         }
00158 
00159 
00160         template<class T>
00161         void PhantomBuffer<T>::Touch(unsigned int pos, unsigned int size)
00162         {
00163                 CLAM_DEBUG_ASSERT( (pos+size) <= ( AllocatedSize() ),
00164                                   "PhantomBuffer::Write(): Position outside bounds");
00165                 unsigned int writen_area_end = pos+size;
00166 
00167                 if (writen_area_end > mLogicalSize)
00168                 {
00169                         unsigned int update_start;
00170                         if (mLogicalSize > pos)
00171                                 update_start = 0;
00172                         else
00173                                 update_start = pos-mLogicalSize;
00174                         UpdateBeginning(update_start, writen_area_end - mLogicalSize - update_start);
00175                 }
00176                 else if ( pos < PhantomSize() )
00177                 {
00178                         int update_end;
00179                         if (PhantomSize() < writen_area_end )
00180                                 update_end = PhantomSize();
00181                         else
00182                                 update_end = writen_area_end;
00183                         UpdatePhantom(pos,update_end-pos);
00184                 }
00185         }
00186 
00187 
00188         template<class T>
00189         void PhantomBuffer<T>::Write(unsigned int pos, unsigned int size,const T* data)
00190         {
00191                 CLAM_DEBUG_ASSERT( (pos+size) <= ( AllocatedSize() ),
00192                                   "PhantomBuffer::Write(): Position outside bounds");
00193                 unsigned int s,d;
00194 
00195                 for (s=0, d=pos; s<size; s++, d++)
00196                         mBuffer[d] = data[s];
00197                 Touch(pos,size);
00198         }
00199 
00200 
00201         template<class T>
00202         void PhantomBuffer<T>::FulfilsInvariant() const
00203         {
00204                 CLAM_ASSERT(mBuffer.size() == AllocatedSize(),
00205                            "PhantomBuffer<T>::FulfilsInvariant(): "
00206                            "internal vector size unconsistency");
00207                 CLAM_ASSERT(PhantomSize() <= mLogicalSize,
00208                            "PhantomBuffer<T>::FulfilsInvariant(): "
00209                            "Phantom size biger than logical size");
00210                 unsigned int i;
00211                 for (i=0; i<PhantomSize(); i++)
00212                         CLAM_ASSERT(mBuffer[i] == mBuffer[i+mLogicalSize],
00213                                     "PhantomBuffer<T>::FulfilsInvariant(): "
00214                                     "Phantom data is unconsistent!");
00215 
00216         }
00217 
00218 } // namespace CLAM
00219 
00220 #endif
00221 

Generated on Tue Aug 12 22:33:43 2008 for CLAM by  doxygen 1.5.5