123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- #pragma once
- #ifndef WIN32
- #define _ASSERT assert
- #endif
- #
- template<class T> class CAutoArray
- {
- struct CRefNode
- {
- int m_nSize;
- LONG m_nRefCount;
- CRefNode():m_nSize(0),m_nRefCount(1){}
- CRefNode(int nInitSize):m_nSize(nInitSize),m_nRefCount(1){}
- };
- public:
- CAutoArray():m_pData(NULL),m_pRefNode(NULL){}
- CAutoArray(int nInitSize):m_pData(NULL),m_pRefNode(NULL)
- {
- _ASSERT(nInitSize>=0);
- if(nInitSize>0)
- Init(nInitSize);
- }
- CAutoArray(T *pData,int nSize):m_pData(NULL),m_pRefNode(NULL)
- {
- Bind(pData,nSize);
- }
- void Bind(T *pData,int nSize)
- {
- Init();
- _ASSERT(nSize>=0);
- if(nSize==0 || pData==NULL )
- return;
- m_pData=pData;
- m_pRefNode=new CRefNode(nSize);
- InterlockedIncrement(&(m_pRefNode->m_nRefCount));//will not delete inside class
- }
- CAutoArray(const CAutoArray<T> &Array)
- {
- m_pData=Array.m_pData;
- m_pRefNode=Array.m_pRefNode;
- if(m_pRefNode)
- InterlockedIncrement(&(m_pRefNode->m_nRefCount));
- }
- ~CAutoArray()
- {
- Init();
- }
- CAutoArray<T> &operator=(const CAutoArray<T> &Array)
- {
- if(Array.m_pData!=m_pData)
- {
- Init();
- m_pData=Array.m_pData;
- m_pRefNode=Array.m_pRefNode;
- if(m_pRefNode)
- InterlockedIncrement(&(m_pRefNode->m_nRefCount));
- }
- return *this;
- }
- bool operator ==(const CAutoArray<T> &Array)
- {
- return m_pData==Array.m_pData;
- }
- bool operator !=(const CAutoArray<T> &Array)
- {
- return m_pData!=Array.m_pData;
- }
- const T &operator[](int nIndex)const
- {
- _ASSERT(nIndex>=0);
- _ASSERT(nIndex<GetCount() || nIndex == 0);
- return m_pData[nIndex];
- }
- T &operator[](int nIndex)
- {
- _ASSERT(nIndex>=0);
- _ASSERT(nIndex<GetCount() || nIndex == 0);
- return GetWriteableArray()[nIndex];
- }
- void Attach(T *pData,int nSize)
- {
- if(pData==m_pData && m_pRefNode && m_pRefNode->m_nSize ==nSize)
- return;
- Init();
- if(nSize==0)
- {
- m_pData=NULL;
- m_pRefNode=NULL;
- }
- else
- {
- m_pData=pData;
- m_pRefNode=new CRefNode(nSize);
- }
- }
- T *Detach()
- {
- T *pRet=m_pData;
- m_pData=NULL;
- if(m_pRefNode && m_pRefNode->m_nRefCount ==1)
- delete m_pRefNode;
- m_pRefNode=NULL;
- return pRet;
- }
- void Init(int nInitSize=0)
- {
- _ASSERT(nInitSize>=0);
- if(m_pRefNode)
- {
- DecrementRef();
- }
- if(nInitSize>0)
- {
- m_pData=new T[nInitSize];
- if(m_pData && m_pRefNode==NULL)
- m_pRefNode=new CRefNode(nInitSize);
- }
- }
- void Clear()
- {
- Init();
- }
- void EnlargeArray(int nNewSize)
- {
- if(nNewSize<=GetCount())
- return;
- T *pData=new T[nNewSize];
- if(pData)
- {
- if(m_pData)
- {
- for(int i=0; i<m_pRefNode->m_nSize; i++)
- pData[i] = m_pData[i];
- if(m_pRefNode->m_nRefCount==1)
- {
- delete []m_pData;
- m_pRefNode->m_nSize=nNewSize;
- }
- else
- DecrementRef();
- }
- m_pData=pData;
- if(m_pRefNode==NULL)
- m_pRefNode=new CRefNode(nNewSize);
- }
- }
- void Copy(const T *pData,int nFrom,int nSize)
- {
- if(pData==NULL || nSize==0)
- {
- Init();
- return;
- }
- _ASSERT(nFrom>=0);
- _ASSERT(nSize>=0);
- Init(nSize);
- if(m_pData)
- {
- const T *pS=pData+nFrom;
- for(T *pT=m_pData;pT<m_pData+nSize;pT++,pS++)
- *pT=*pS;
- }
- }
- void Copy(const CAutoArray<T> &Array)
- {
- Copy(Array,0,Array.GetCount());
- }
- void Copy(const CAutoArray<T> &Array,int nFrom,int nSize)
- {
- if(nSize==0)
- return;
- _ASSERT(nFrom>=0);
- _ASSERT(nSize>=0);
- _ASSERT(nFrom<Array.GetCount());
- int nMaxSize=Array.GetCount()-nFrom;
- if(nSize>nMaxSize)nSize=nMaxSize;
- Init(nSize);
- if(m_pData)
- {
- const T *pS=Array.m_pData+nFrom;
- for(T *pT=m_pData;pT<m_pData+nSize;pT++,pS++)
- *pT=*pS;
- }
- }
- void Append(const T* pData,int nFrom,int nSize)
- {
- if(pData==NULL || nSize==0)
- return;
- _ASSERT(nFrom>=0);
- _ASSERT(nSize>=0);
- if(GetCount()==0)
- {
- Copy(pData,nFrom,nSize);
- return;
- }
- int nOldSize = GetCount();
- EnlargeArray(nOldSize + nSize);
- if(m_pData)
- {
- T *pBegin=m_pData+nOldSize;
- const T *pS=pData+nFrom;
- for(T *pT=pBegin;pT<pBegin+nSize;pT++,pS++)
- *pT=*pS;
- }
- }
- void Append(const CAutoArray<T> &Array,int nFrom,int nSize)
- {
- if(nSize==0)
- return;
- _ASSERT(nFrom>=0);
- _ASSERT(nSize>=0);
- _ASSERT(nFrom<Array.GetCount());
- int nMaxSize=Array.GetCount()-nFrom;
- if(nSize>nMaxSize)nSize=nMaxSize;
- if(nSize==0)
- return;
-
- if(GetCount()==0)
- {
- Copy(Array,nFrom,nSize);
- return;
- }
-
- int nOldSize = GetCount();
- EnlargeArray(nOldSize + nSize);
- if(m_pData)
- {
- T *pBegin=m_pData+nOldSize;
- const T *pS=Array.m_pData+nFrom;
- for(T *pT=pBegin;pT<pBegin+nSize;pT++,pS++)
- *pT=*pS;
- }
- }
- void Append(const CAutoArray<T> &Array)
- {
- Append(Array,0,Array.GetCount());
- }
- CAutoArray<T> Clone()
- {
- return Clone(0,GetCount());
- }
- CAutoArray<T> Clone(int nFrom,int nSize)
- {
- CAutoArray<T> RetArray;
- RetArray.Copy(m_pData,nFrom,nSize);
- return RetArray;
- }
- int GetCount()const
- {
- if(m_pRefNode)
- return m_pRefNode->m_nSize;
- else
- return 0;
- }
- operator const T*()const {return m_pData;};
- T* GetWriteableArray()
- {
- if(m_pRefNode && m_pRefNode->m_nRefCount>1)
- {
- int nSize=m_pRefNode->m_nSize;
- T *pData=new T[nSize];
- if(m_pData)
- {
- for(T *pT=pData,*pS=m_pData;pT<pData+nSize;pT++,pS++)
- *pT=*pS;
- DecrementRef();
- m_pData=pData;
- m_pRefNode=new CRefNode(nSize);
- }
- }
- return m_pData;
- }
- private:
- LONG DecrementRef()
- {
- _ASSERT(m_pRefNode);
- LONG nRef=InterlockedDecrement(&(m_pRefNode->m_nRefCount));
- if(nRef==0)
- {
- delete []m_pData;
- delete m_pRefNode;
- }
- m_pData=NULL;
- m_pRefNode=NULL;
- return nRef;
- }
- T *m_pData;
- CRefNode *m_pRefNode;
- };
- typedef CAutoArray<BYTE> CAutoBuffer;
|