| 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
 |