123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #ifndef _RAR_ARRAY_
- #define _RAR_ARRAY_
- extern ErrorHandler ErrHandler;
- template <class T> class Array
- {
- private:
- T *Buffer;
- size_t BufSize;
- size_t AllocSize;
- size_t MaxSize;
- bool Secure; // Clean memory if true.
- public:
- Array();
- Array(size_t Size);
- Array(const Array &Src); // Copy constructor.
- ~Array();
- inline void CleanData();
- inline T& operator [](size_t Item) const;
- inline T* operator + (size_t Pos);
- inline size_t Size(); // Returns the size in items, not in bytes.
- void Add(size_t Items);
- void Alloc(size_t Items);
- void Reset();
- void SoftReset();
- void operator = (Array<T> &Src);
- void Push(T Item);
- void Append(T *Item,size_t Count);
- T* Addr(size_t Item) {return Buffer+Item;}
- void SetMaxSize(size_t Size) {MaxSize=Size;}
- T* Begin() {return Buffer;}
- T* End() {return Buffer==NULL ? NULL:Buffer+BufSize;}
- void SetSecure() {Secure=true;}
- };
- template <class T> void Array<T>::CleanData()
- {
- Buffer=NULL;
- BufSize=0;
- AllocSize=0;
- MaxSize=0;
- Secure=false;
- }
- template <class T> Array<T>::Array()
- {
- CleanData();
- }
- template <class T> Array<T>::Array(size_t Size)
- {
- CleanData();
- Add(Size);
- }
- // Copy constructor in case we need to pass an object as value.
- template <class T> Array<T>::Array(const Array &Src)
- {
- CleanData();
- Alloc(Src.BufSize);
- if (Src.BufSize!=0)
- memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
- }
- template <class T> Array<T>::~Array()
- {
- if (Buffer!=NULL)
- {
- if (Secure)
- cleandata(Buffer,AllocSize*sizeof(T));
- free(Buffer);
- }
- }
- template <class T> inline T& Array<T>::operator [](size_t Item) const
- {
- return Buffer[Item];
- }
- template <class T> inline T* Array<T>::operator +(size_t Pos)
- {
- return Buffer+Pos;
- }
- template <class T> inline size_t Array<T>::Size()
- {
- return BufSize;
- }
- template <class T> void Array<T>::Add(size_t Items)
- {
- BufSize+=Items;
- if (BufSize>AllocSize)
- {
- if (MaxSize!=0 && BufSize>MaxSize)
- {
- ErrHandler.GeneralErrMsg(L"Maximum allowed array size (%u) is exceeded",MaxSize);
- ErrHandler.MemoryError();
- }
- size_t Suggested=AllocSize+AllocSize/4+32;
- size_t NewSize=Max(BufSize,Suggested);
- T *NewBuffer;
- if (Secure)
- {
- NewBuffer=(T *)malloc(NewSize*sizeof(T));
- if (NewBuffer==NULL)
- ErrHandler.MemoryError();
- if (Buffer!=NULL)
- {
- memcpy(NewBuffer,Buffer,AllocSize*sizeof(T));
- cleandata(Buffer,AllocSize*sizeof(T));
- free(Buffer);
- }
- }
- else
- {
- NewBuffer=(T *)realloc(Buffer,NewSize*sizeof(T));
- if (NewBuffer==NULL)
- ErrHandler.MemoryError();
- }
- Buffer=NewBuffer;
- AllocSize=NewSize;
- }
- }
- template <class T> void Array<T>::Alloc(size_t Items)
- {
- if (Items>AllocSize)
- Add(Items-BufSize);
- else
- BufSize=Items;
- }
- template <class T> void Array<T>::Reset()
- {
- if (Buffer!=NULL)
- {
- free(Buffer);
- Buffer=NULL;
- }
- BufSize=0;
- AllocSize=0;
- }
- // Reset buffer size, but preserve already allocated memory if any,
- // so we can reuse it without wasting time to allocation.
- template <class T> void Array<T>::SoftReset()
- {
- BufSize=0;
- }
- template <class T> void Array<T>::operator =(Array<T> &Src)
- {
- Reset();
- Alloc(Src.BufSize);
- if (Src.BufSize!=0)
- memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
- }
- template <class T> void Array<T>::Push(T Item)
- {
- Add(1);
- (*this)[Size()-1]=Item;
- }
- template <class T> void Array<T>::Append(T *Items,size_t Count)
- {
- size_t CurSize=Size();
- Add(Count);
- memcpy(Buffer+CurSize,Items,Count*sizeof(T));
- }
- #endif
|