array.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #ifndef _RAR_ARRAY_
  2. #define _RAR_ARRAY_
  3. extern ErrorHandler ErrHandler;
  4. template <class T> class Array
  5. {
  6. private:
  7. T *Buffer;
  8. size_t BufSize;
  9. size_t AllocSize;
  10. size_t MaxSize;
  11. bool Secure; // Clean memory if true.
  12. public:
  13. Array();
  14. Array(size_t Size);
  15. Array(const Array &Src); // Copy constructor.
  16. ~Array();
  17. inline void CleanData();
  18. inline T& operator [](size_t Item) const;
  19. inline T* operator + (size_t Pos);
  20. inline size_t Size(); // Returns the size in items, not in bytes.
  21. void Add(size_t Items);
  22. void Alloc(size_t Items);
  23. void Reset();
  24. void SoftReset();
  25. void operator = (Array<T> &Src);
  26. void Push(T Item);
  27. void Append(T *Item,size_t Count);
  28. T* Addr(size_t Item) {return Buffer+Item;}
  29. void SetMaxSize(size_t Size) {MaxSize=Size;}
  30. T* Begin() {return Buffer;}
  31. T* End() {return Buffer==NULL ? NULL:Buffer+BufSize;}
  32. void SetSecure() {Secure=true;}
  33. };
  34. template <class T> void Array<T>::CleanData()
  35. {
  36. Buffer=NULL;
  37. BufSize=0;
  38. AllocSize=0;
  39. MaxSize=0;
  40. Secure=false;
  41. }
  42. template <class T> Array<T>::Array()
  43. {
  44. CleanData();
  45. }
  46. template <class T> Array<T>::Array(size_t Size)
  47. {
  48. CleanData();
  49. Add(Size);
  50. }
  51. // Copy constructor in case we need to pass an object as value.
  52. template <class T> Array<T>::Array(const Array &Src)
  53. {
  54. CleanData();
  55. Alloc(Src.BufSize);
  56. if (Src.BufSize!=0)
  57. memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
  58. }
  59. template <class T> Array<T>::~Array()
  60. {
  61. if (Buffer!=NULL)
  62. {
  63. if (Secure)
  64. cleandata(Buffer,AllocSize*sizeof(T));
  65. free(Buffer);
  66. }
  67. }
  68. template <class T> inline T& Array<T>::operator [](size_t Item) const
  69. {
  70. return Buffer[Item];
  71. }
  72. template <class T> inline T* Array<T>::operator +(size_t Pos)
  73. {
  74. return Buffer+Pos;
  75. }
  76. template <class T> inline size_t Array<T>::Size()
  77. {
  78. return BufSize;
  79. }
  80. template <class T> void Array<T>::Add(size_t Items)
  81. {
  82. BufSize+=Items;
  83. if (BufSize>AllocSize)
  84. {
  85. if (MaxSize!=0 && BufSize>MaxSize)
  86. {
  87. ErrHandler.GeneralErrMsg(L"Maximum allowed array size (%u) is exceeded",MaxSize);
  88. ErrHandler.MemoryError();
  89. }
  90. size_t Suggested=AllocSize+AllocSize/4+32;
  91. size_t NewSize=Max(BufSize,Suggested);
  92. T *NewBuffer;
  93. if (Secure)
  94. {
  95. NewBuffer=(T *)malloc(NewSize*sizeof(T));
  96. if (NewBuffer==NULL)
  97. ErrHandler.MemoryError();
  98. if (Buffer!=NULL)
  99. {
  100. memcpy(NewBuffer,Buffer,AllocSize*sizeof(T));
  101. cleandata(Buffer,AllocSize*sizeof(T));
  102. free(Buffer);
  103. }
  104. }
  105. else
  106. {
  107. NewBuffer=(T *)realloc(Buffer,NewSize*sizeof(T));
  108. if (NewBuffer==NULL)
  109. ErrHandler.MemoryError();
  110. }
  111. Buffer=NewBuffer;
  112. AllocSize=NewSize;
  113. }
  114. }
  115. template <class T> void Array<T>::Alloc(size_t Items)
  116. {
  117. if (Items>AllocSize)
  118. Add(Items-BufSize);
  119. else
  120. BufSize=Items;
  121. }
  122. template <class T> void Array<T>::Reset()
  123. {
  124. if (Buffer!=NULL)
  125. {
  126. free(Buffer);
  127. Buffer=NULL;
  128. }
  129. BufSize=0;
  130. AllocSize=0;
  131. }
  132. // Reset buffer size, but preserve already allocated memory if any,
  133. // so we can reuse it without wasting time to allocation.
  134. template <class T> void Array<T>::SoftReset()
  135. {
  136. BufSize=0;
  137. }
  138. template <class T> void Array<T>::operator =(Array<T> &Src)
  139. {
  140. Reset();
  141. Alloc(Src.BufSize);
  142. if (Src.BufSize!=0)
  143. memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
  144. }
  145. template <class T> void Array<T>::Push(T Item)
  146. {
  147. Add(1);
  148. (*this)[Size()-1]=Item;
  149. }
  150. template <class T> void Array<T>::Append(T *Items,size_t Count)
  151. {
  152. size_t CurSize=Size();
  153. Add(Count);
  154. memcpy(Buffer+CurSize,Items,Count*sizeof(T));
  155. }
  156. #endif