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 <iostream>
00028 #include "Assert.hxx"
00029 
00030 namespace CLAM {
00031 
00032         template<class T>
00033         class PhantomBuffer 
00034         {
00035         public:
00036                 PhantomBuffer();
00037                 T*   Read(unsigned int pos, unsigned int size);
00038 
00044                 void Touch(unsigned int pos, unsigned int size);
00045 
00051                 void Write(unsigned int pos, unsigned int size,const T* data);
00052 
00053                 unsigned LogicalSize() const {return mLogicalSize;}
00054                 
00055                 unsigned int PhantomSize() const { return mBuffer.size() - mLogicalSize; }
00056 
00057                 void Resize(unsigned int size,
00058                             unsigned int phantom,
00059                             unsigned int insert_pos);
00060         
00067                 void FulfilsInvariant() const;
00068 
00069         private:
00074                 void UpdatePhantom(unsigned int pos, unsigned int size);
00079                 void UpdateBeginning(unsigned int pos, unsigned int size);
00080 
00081                 unsigned int AllocatedSize() const
00082                 { 
00083                         return mBuffer.size(); 
00084                 }
00085 
00086         
00087                 // attributes
00088                 std::vector<T> mBuffer;
00089                 unsigned mLogicalSize;
00090         };
00091 
00092         
00093         template<class T>
00094         PhantomBuffer<T>::PhantomBuffer()
00095                 : mLogicalSize(0) 
00096         {}
00097 
00098 
00099         template<class T>
00100         void PhantomBuffer<T>::UpdatePhantom(unsigned int pos, unsigned int size)
00101         {
00102                 CLAM_DEBUG_ASSERT(pos+size <= PhantomSize(),
00103                                  "PhantomBuffer::UpdatePhantom():"
00104                                  "Requested region falls outside phantom zone");
00105                 unsigned int s,d;
00106                 for (s=pos, d=mLogicalSize+pos; s<pos+size; s++, d++)
00107                         mBuffer[d] = mBuffer[s];
00108         }
00109 
00110         template<class T>
00111         void PhantomBuffer<T>::UpdateBeginning(unsigned int pos, unsigned int size)
00112         {
00113                 CLAM_DEBUG_ASSERT(pos+size <= PhantomSize(),
00114                                  "PhantomBuffer::UpdateBeginning():"
00115                                  "Requested region falls outside beginning zone");
00116                 unsigned int s,d;
00117                 for (d=pos, s=mLogicalSize+pos; d<size; d++, s++)
00118                         mBuffer[d] = mBuffer[s];
00119         }
00120 
00121 
00122         template<class T>
00123         void PhantomBuffer<T>::Resize(unsigned int newLogicalSize, unsigned int newPhantomSize, unsigned int insertionPos)
00124         {
00125                 CLAM_ASSERT(insertionPos <= LogicalSize(),
00126                            "PhantomBuffer::Resize(): "
00127                            "Insertion position can not be greater than previous size.");
00128                 CLAM_ASSERT(newPhantomSize <= newLogicalSize,
00129                            "PhantomBuffer::Resize(): Phantom Size can not be greater than size.");
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 by  doxygen 1.6.3