Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ZeBuffer.h

Go to the documentation of this file.
00001 #ifndef ZEBUFFER_H
00002 #define ZEBUFFER_H
00003 #include <abuse/nomem_error.h>
00004 #include <abuse/Debug.h>
00005 #include <string>
00006 
00007 #define CHUNK 4096
00008 typedef unsigned int uint;
00009 
00010 template<class T>
00011 class ZeBuffer
00012 {
00013 private:
00014         uint m_size;
00015         uint m_allocated;
00016         uint* m_pCounter;
00017         T* m_ptr;
00018         void release()
00019         {
00020                 Track("ZeBuffer::release");
00021                 if(m_pCounter)
00022                 {
00023                         DebugOut("Counter: ");
00024                         DebugOut(*m_pCounter-1);
00025                         if(!(--(*m_pCounter)))
00026                         {
00027                                 DebugOut("Releasing buffer");
00028                                 delete m_pCounter;
00029                                 delete[] m_ptr;
00030                         }
00031                 }
00032         }
00033 
00034         void copy()throw (std::nomem_error)
00035         {
00036                 Track("ZeBuffer::copy");
00037                 if(m_pCounter && (*m_pCounter)>1)
00038                 {
00039                         uint *tmpCounter=NULL;
00040                         T* tmpptr=new T[m_allocated+sizeof(T)];
00041                         tmpCounter=new uint(1);
00042                         if(!tmpptr || !tmpCounter)
00043                         {
00044                                 delete tmpptr;
00045                                 delete tmpCounter;
00046                                 throw std::nomem_error();
00047                         }
00048                         memcpy((void*)tmpptr,(void*)m_ptr,m_size*sizeof(T));
00049                         release();
00050                         m_pCounter=tmpCounter;
00051                         m_ptr=tmpptr;
00052                 }
00053 #ifdef _DEBUG
00054                 else
00055                         DebugOut("Nothing to copy");
00056 #endif
00057         }
00058         void realloc(uint newsize)throw(std::nomem_error)
00059         {
00060                 Track("ZeBuffer::realloc");
00061                 DebugOut("Reallocating to bytes ");
00062                 DebugOut(newsize);
00063                 T* ptr=new T[newsize+sizeof(T)];
00064                 if(!ptr)
00065                         throw std::nomem_error();
00066                 if(m_pCounter)
00067                 {
00068                         memcpy((void*)ptr,(void*)m_ptr,m_size*sizeof(T));
00069                         delete[] ptr;
00070                 }
00071                 else
00072                         m_pCounter=new uint(1);
00073                 m_ptr=ptr;
00074                 m_allocated=newsize;
00075         }
00076 public:
00077         ZeBuffer(uint initial=0)throw(std::nomem_error)
00078         :m_ptr(NULL),m_size(0),m_allocated(0),m_pCounter(NULL)
00079         {
00080                 Track("ZeBuffer::default ctor");
00081                 if(initial)
00082                 {
00083                         m_ptr=new T[initial+sizeof(T)];
00084                         m_pCounter=new uint(1);
00085                         if(!m_ptr || !m_pCounter)
00086                         {
00087                                 delete m_pCounter;
00088                                 delete[] m_ptr;
00089                                 throw std::nomem_error();
00090                         }
00091                         m_allocated=initial;
00092                 }
00093         }
00094         
00095         ZeBuffer(T* ptr,uint _size)throw(std::nomem_error)
00096         :m_ptr(ptr),m_size(_size),m_allocated(_size),m_pCounter(NULL)
00097         {
00098                 Track("ZeBuffer::ctor grabbing ptr");
00099                 if((m_pCounter=new uint(1))==NULL)
00100                 {
00101                         throw std::nomem_error();
00102                 }
00103         }
00104 
00105         ZeBuffer(const ZeBuffer& other):
00106         m_ptr(NULL),m_pCounter(NULL)
00107         {
00108                 Track("ZeBuffer::copy ctor");
00109                 operator=(other);
00110         }
00111         virtual ~ZeBuffer()
00112         {
00113                 Track("ZeBuffer::dtor");
00114                 release();
00115         }
00116         void operator=(const ZeBuffer& other)
00117         {
00118                 Track("ZeBuffer::operator=");
00119                 if(this!=&other)
00120                 {
00121                         release();
00122                         m_ptr=other.m_ptr;
00123                         m_pCounter=other.m_pCounter;
00124                         if(m_pCounter)
00125                         {
00126                                 ++(*m_pCounter);
00127                                 DebugOut(*m_pCounter);
00128                         }
00129                         m_size=other.m_size;
00130                         m_allocated=other.m_allocated;
00131                 }
00132         }
00133         void append(T* ptr,uint _size)throw(std::nomem_error)
00134         {
00135                 Track("ZeBuffer::append");
00136                 copy();
00137                 uint newsize=m_size+_size;
00138                 if(newsize>m_allocated)
00139                         realloc(roundup(newsize,CHUNK));
00140                 memcpy((void*)(m_ptr+m_size),(void*)ptr,_size);
00141                 m_size=newsize;
00142         }
00143         ZeBuffer& operator+=(const ZeBuffer& copy)throw(std::nomem_error)
00144         {
00145                 Track("ZeBuffer::operator+=(const ZeBuffer&)");
00146                 append(copy.m_ptr,copy.m_size);
00147                 return *this;
00148         }
00149         ZeBuffer operator+(const ZeBuffer& copy)const throw(std::nomem_error)
00150         {
00151                 Track("ZeBuffer::operator+(const ZeBuffer&)");
00152                 return ZeBuffer(this).operator+=(copy);
00153         }
00154         ZeBuffer& operator+=(const T& data)throw(std::nomem_error)
00155         {
00156                 Track("ZeBuffer::operator+=(const T&)");
00157                 copy();
00158                 if((++m_size)>m_allocated)
00159                         realloc(m_allocated+CHUNK);
00160                 m_ptr[m_size-1]=data;
00161                 return *this;
00162         }
00163         ZeBuffer operator+(const T& data)const
00164         {
00165                 Track("ZeBuffer::operator+(const T&)");
00166                 return ZeBuffer(this).operator+=(data);
00167         }
00168         uint size()const
00169         {
00170                 Track("ZeBuffer::size");
00171                 return m_size;
00172         }
00173         uint allocated()const
00174         {
00175                 Track("ZeBuffer::allocated");
00176                 return m_allocated;
00177         }
00178         const T* data()const
00179         {
00180                 Track("ZeBuffer::data()const");
00181                 return m_ptr;
00182         }
00183         T* data()
00184         {
00185                 Track("ZeBuffer::data()");
00186                 copy();
00187                 return m_ptr;   
00188         }
00189         
00190         std::string str()const
00191         {
00192                 //ok, I've allocated one more byte than declarated
00193                 if(m_size)
00194                 {
00195                         m_ptr[m_size]=T(0);
00196                         return std::string((const char*)m_ptr);
00197                 }
00198                 else 
00199                         return std::string("");
00200         }
00201 };
00202 
00203 #endif

Generated on Thu Jun 16 00:13:14 2005 for Netlib for Abuse! by  doxygen 1.4.3