1370b324cSopenharmony_ci// Common/MyBuffer.h
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#ifndef ZIP7_INC_COMMON_MY_BUFFER_H
4370b324cSopenharmony_ci#define ZIP7_INC_COMMON_MY_BUFFER_H
5370b324cSopenharmony_ci
6370b324cSopenharmony_ci#include <string.h>
7370b324cSopenharmony_ci
8370b324cSopenharmony_ci#include "Defs.h"
9370b324cSopenharmony_ci#include "MyTypes.h"
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci/* 7-Zip now uses CBuffer only as CByteBuffer.
12370b324cSopenharmony_ci   So there is no need to use Z7_ARRAY_NEW macro in CBuffer code. */
13370b324cSopenharmony_ci
14370b324cSopenharmony_citemplate <class T> class CBuffer
15370b324cSopenharmony_ci{
16370b324cSopenharmony_ci  T *_items;
17370b324cSopenharmony_ci  size_t _size;
18370b324cSopenharmony_ci
19370b324cSopenharmony_cipublic:
20370b324cSopenharmony_ci  void Free()
21370b324cSopenharmony_ci  {
22370b324cSopenharmony_ci    if (_items)
23370b324cSopenharmony_ci    {
24370b324cSopenharmony_ci      delete []_items;
25370b324cSopenharmony_ci      _items = NULL;
26370b324cSopenharmony_ci    }
27370b324cSopenharmony_ci    _size = 0;
28370b324cSopenharmony_ci  }
29370b324cSopenharmony_ci
30370b324cSopenharmony_ci  CBuffer(): _items(NULL), _size(0) {}
31370b324cSopenharmony_ci  CBuffer(size_t size): _items(NULL), _size(0)
32370b324cSopenharmony_ci  {
33370b324cSopenharmony_ci    if (size != 0)
34370b324cSopenharmony_ci    {
35370b324cSopenharmony_ci      _items = new T[size];
36370b324cSopenharmony_ci      _size = size;
37370b324cSopenharmony_ci    }
38370b324cSopenharmony_ci  }
39370b324cSopenharmony_ci  CBuffer(const CBuffer &buffer): _items(NULL), _size(0)
40370b324cSopenharmony_ci  {
41370b324cSopenharmony_ci    const size_t size = buffer._size;
42370b324cSopenharmony_ci    if (size != 0)
43370b324cSopenharmony_ci    {
44370b324cSopenharmony_ci      _items = new T[size];
45370b324cSopenharmony_ci      memcpy(_items, buffer._items, size * sizeof(T));
46370b324cSopenharmony_ci      _size = size;
47370b324cSopenharmony_ci    }
48370b324cSopenharmony_ci  }
49370b324cSopenharmony_ci
50370b324cSopenharmony_ci  ~CBuffer() { delete []_items; }
51370b324cSopenharmony_ci
52370b324cSopenharmony_ci  operator       T *()       { return _items; }
53370b324cSopenharmony_ci  operator const T *() const { return _items; }
54370b324cSopenharmony_ci  size_t Size() const { return _size; }
55370b324cSopenharmony_ci
56370b324cSopenharmony_ci  void Alloc(size_t size)
57370b324cSopenharmony_ci  {
58370b324cSopenharmony_ci    if (size != _size)
59370b324cSopenharmony_ci    {
60370b324cSopenharmony_ci      Free();
61370b324cSopenharmony_ci      if (size != 0)
62370b324cSopenharmony_ci      {
63370b324cSopenharmony_ci        _items = new T[size];
64370b324cSopenharmony_ci        _size = size;
65370b324cSopenharmony_ci      }
66370b324cSopenharmony_ci    }
67370b324cSopenharmony_ci  }
68370b324cSopenharmony_ci
69370b324cSopenharmony_ci  void AllocAtLeast(size_t size)
70370b324cSopenharmony_ci  {
71370b324cSopenharmony_ci    if (size > _size)
72370b324cSopenharmony_ci    {
73370b324cSopenharmony_ci      Free();
74370b324cSopenharmony_ci      _items = new T[size];
75370b324cSopenharmony_ci      _size = size;
76370b324cSopenharmony_ci    }
77370b324cSopenharmony_ci  }
78370b324cSopenharmony_ci
79370b324cSopenharmony_ci  void CopyFrom(const T *data, size_t size)
80370b324cSopenharmony_ci  {
81370b324cSopenharmony_ci    Alloc(size);
82370b324cSopenharmony_ci    if (size != 0)
83370b324cSopenharmony_ci      memcpy(_items, data, size * sizeof(T));
84370b324cSopenharmony_ci  }
85370b324cSopenharmony_ci
86370b324cSopenharmony_ci  void ChangeSize_KeepData(size_t newSize, size_t keepSize)
87370b324cSopenharmony_ci  {
88370b324cSopenharmony_ci    if (newSize == _size)
89370b324cSopenharmony_ci      return;
90370b324cSopenharmony_ci    T *newBuffer = NULL;
91370b324cSopenharmony_ci    if (newSize != 0)
92370b324cSopenharmony_ci    {
93370b324cSopenharmony_ci      newBuffer = new T[newSize];
94370b324cSopenharmony_ci      if (keepSize > _size)
95370b324cSopenharmony_ci        keepSize = _size;
96370b324cSopenharmony_ci      if (keepSize != 0)
97370b324cSopenharmony_ci        memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T));
98370b324cSopenharmony_ci    }
99370b324cSopenharmony_ci    delete []_items;
100370b324cSopenharmony_ci    _items = newBuffer;
101370b324cSopenharmony_ci    _size = newSize;
102370b324cSopenharmony_ci  }
103370b324cSopenharmony_ci
104370b324cSopenharmony_ci  void Wipe()
105370b324cSopenharmony_ci  {
106370b324cSopenharmony_ci    if (_size != 0)
107370b324cSopenharmony_ci      memset(_items, 0, _size * sizeof(T));
108370b324cSopenharmony_ci  }
109370b324cSopenharmony_ci
110370b324cSopenharmony_ci  CBuffer& operator=(const CBuffer &buffer)
111370b324cSopenharmony_ci  {
112370b324cSopenharmony_ci    if (&buffer != this)
113370b324cSopenharmony_ci      CopyFrom(buffer, buffer._size);
114370b324cSopenharmony_ci    return *this;
115370b324cSopenharmony_ci  }
116370b324cSopenharmony_ci};
117370b324cSopenharmony_ci
118370b324cSopenharmony_citemplate <class T>
119370b324cSopenharmony_cibool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
120370b324cSopenharmony_ci{
121370b324cSopenharmony_ci  size_t size1 = b1.Size();
122370b324cSopenharmony_ci  if (size1 != b2.Size())
123370b324cSopenharmony_ci    return false;
124370b324cSopenharmony_ci  if (size1 == 0)
125370b324cSopenharmony_ci    return true;
126370b324cSopenharmony_ci  return memcmp(b1, b2, size1 * sizeof(T)) == 0;
127370b324cSopenharmony_ci}
128370b324cSopenharmony_ci
129370b324cSopenharmony_citemplate <class T>
130370b324cSopenharmony_cibool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
131370b324cSopenharmony_ci{
132370b324cSopenharmony_ci  size_t size1 = b1.Size();
133370b324cSopenharmony_ci  if (size1 != b2.Size())
134370b324cSopenharmony_ci    return true;
135370b324cSopenharmony_ci  if (size1 == 0)
136370b324cSopenharmony_ci    return false;
137370b324cSopenharmony_ci  return memcmp(b1, b2, size1 * sizeof(T)) != 0;
138370b324cSopenharmony_ci}
139370b324cSopenharmony_ci
140370b324cSopenharmony_ci
141370b324cSopenharmony_ci// typedef CBuffer<char> CCharBuffer;
142370b324cSopenharmony_ci// typedef CBuffer<wchar_t> CWCharBuffer;
143370b324cSopenharmony_citypedef CBuffer<unsigned char> CByteBuffer;
144370b324cSopenharmony_ci
145370b324cSopenharmony_ci
146370b324cSopenharmony_ciclass CByteBuffer_Wipe: public CByteBuffer
147370b324cSopenharmony_ci{
148370b324cSopenharmony_ci  Z7_CLASS_NO_COPY(CByteBuffer_Wipe)
149370b324cSopenharmony_cipublic:
150370b324cSopenharmony_ci  // CByteBuffer_Wipe(): CBuffer<unsigned char>() {}
151370b324cSopenharmony_ci  CByteBuffer_Wipe(size_t size): CBuffer<unsigned char>(size) {}
152370b324cSopenharmony_ci  ~CByteBuffer_Wipe() { Wipe(); }
153370b324cSopenharmony_ci};
154370b324cSopenharmony_ci
155370b324cSopenharmony_ci
156370b324cSopenharmony_ci
157370b324cSopenharmony_citemplate <class T> class CObjArray
158370b324cSopenharmony_ci{
159370b324cSopenharmony_ciprotected:
160370b324cSopenharmony_ci  T *_items;
161370b324cSopenharmony_ciprivate:
162370b324cSopenharmony_ci  // we disable copy
163370b324cSopenharmony_ci  CObjArray(const CObjArray &buffer);
164370b324cSopenharmony_ci  void operator=(const CObjArray &buffer);
165370b324cSopenharmony_cipublic:
166370b324cSopenharmony_ci  void Free()
167370b324cSopenharmony_ci  {
168370b324cSopenharmony_ci    delete []_items;
169370b324cSopenharmony_ci    _items = NULL;
170370b324cSopenharmony_ci  }
171370b324cSopenharmony_ci  CObjArray(size_t size): _items(NULL)
172370b324cSopenharmony_ci  {
173370b324cSopenharmony_ci    if (size != 0)
174370b324cSopenharmony_ci    {
175370b324cSopenharmony_ci      Z7_ARRAY_NEW(_items, T, size)
176370b324cSopenharmony_ci      // _items = new T[size];
177370b324cSopenharmony_ci    }
178370b324cSopenharmony_ci  }
179370b324cSopenharmony_ci  CObjArray(): _items(NULL) {}
180370b324cSopenharmony_ci  ~CObjArray() { delete []_items; }
181370b324cSopenharmony_ci
182370b324cSopenharmony_ci  operator       T *()       { return _items; }
183370b324cSopenharmony_ci  operator const T *() const { return _items; }
184370b324cSopenharmony_ci
185370b324cSopenharmony_ci  void Alloc(size_t newSize)
186370b324cSopenharmony_ci  {
187370b324cSopenharmony_ci    delete []_items;
188370b324cSopenharmony_ci    _items = NULL;
189370b324cSopenharmony_ci    Z7_ARRAY_NEW(_items, T, newSize)
190370b324cSopenharmony_ci    // _items = new T[newSize];
191370b324cSopenharmony_ci  }
192370b324cSopenharmony_ci};
193370b324cSopenharmony_ci
194370b324cSopenharmony_citypedef CObjArray<unsigned char> CByteArr;
195370b324cSopenharmony_citypedef CObjArray<bool> CBoolArr;
196370b324cSopenharmony_citypedef CObjArray<int> CIntArr;
197370b324cSopenharmony_citypedef CObjArray<unsigned> CUIntArr;
198370b324cSopenharmony_ci
199370b324cSopenharmony_ci
200370b324cSopenharmony_citemplate <class T> class CObjArray2
201370b324cSopenharmony_ci{
202370b324cSopenharmony_ci  T *_items;
203370b324cSopenharmony_ci  unsigned _size;
204370b324cSopenharmony_ci
205370b324cSopenharmony_ci  // we disable copy
206370b324cSopenharmony_ci  CObjArray2(const CObjArray2 &buffer);
207370b324cSopenharmony_ci  void operator=(const CObjArray2 &buffer);
208370b324cSopenharmony_cipublic:
209370b324cSopenharmony_ci
210370b324cSopenharmony_ci  void Free()
211370b324cSopenharmony_ci  {
212370b324cSopenharmony_ci    delete []_items;
213370b324cSopenharmony_ci    _items = NULL;
214370b324cSopenharmony_ci    _size = 0;
215370b324cSopenharmony_ci  }
216370b324cSopenharmony_ci  CObjArray2(): _items(NULL), _size(0) {}
217370b324cSopenharmony_ci  /*
218370b324cSopenharmony_ci  CObjArray2(const CObjArray2 &buffer): _items(NULL), _size(0)
219370b324cSopenharmony_ci  {
220370b324cSopenharmony_ci    size_t newSize = buffer._size;
221370b324cSopenharmony_ci    if (newSize != 0)
222370b324cSopenharmony_ci    {
223370b324cSopenharmony_ci      T *newBuffer = new T[newSize];;
224370b324cSopenharmony_ci      _items = newBuffer;
225370b324cSopenharmony_ci      _size = newSize;
226370b324cSopenharmony_ci      const T *src = buffer;
227370b324cSopenharmony_ci      for (size_t i = 0; i < newSize; i++)
228370b324cSopenharmony_ci        newBuffer[i] = src[i];
229370b324cSopenharmony_ci    }
230370b324cSopenharmony_ci  }
231370b324cSopenharmony_ci  */
232370b324cSopenharmony_ci  /*
233370b324cSopenharmony_ci  CObjArray2(size_t size): _items(NULL), _size(0)
234370b324cSopenharmony_ci  {
235370b324cSopenharmony_ci    if (size != 0)
236370b324cSopenharmony_ci    {
237370b324cSopenharmony_ci      _items = new T[size];
238370b324cSopenharmony_ci      _size = size;
239370b324cSopenharmony_ci    }
240370b324cSopenharmony_ci  }
241370b324cSopenharmony_ci  */
242370b324cSopenharmony_ci
243370b324cSopenharmony_ci  ~CObjArray2() { delete []_items; }
244370b324cSopenharmony_ci
245370b324cSopenharmony_ci  operator       T *()       { return _items; }
246370b324cSopenharmony_ci  operator const T *() const { return _items; }
247370b324cSopenharmony_ci
248370b324cSopenharmony_ci  unsigned Size() const { return (unsigned)_size; }
249370b324cSopenharmony_ci  bool IsEmpty() const { return _size == 0; }
250370b324cSopenharmony_ci
251370b324cSopenharmony_ci  // SetSize doesn't keep old items. It allocates new array if size is not equal
252370b324cSopenharmony_ci  void SetSize(unsigned size)
253370b324cSopenharmony_ci  {
254370b324cSopenharmony_ci    if (size == _size)
255370b324cSopenharmony_ci      return;
256370b324cSopenharmony_ci    T *newBuffer = NULL;
257370b324cSopenharmony_ci    if (size != 0)
258370b324cSopenharmony_ci    {
259370b324cSopenharmony_ci      Z7_ARRAY_NEW(newBuffer, T, size)
260370b324cSopenharmony_ci      // newBuffer = new T[size];
261370b324cSopenharmony_ci    }
262370b324cSopenharmony_ci    delete []_items;
263370b324cSopenharmony_ci    _items = newBuffer;
264370b324cSopenharmony_ci    _size = size;
265370b324cSopenharmony_ci  }
266370b324cSopenharmony_ci
267370b324cSopenharmony_ci  /*
268370b324cSopenharmony_ci  CObjArray2& operator=(const CObjArray2 &buffer)
269370b324cSopenharmony_ci  {
270370b324cSopenharmony_ci    Free();
271370b324cSopenharmony_ci    size_t newSize = buffer._size;
272370b324cSopenharmony_ci    if (newSize != 0)
273370b324cSopenharmony_ci    {
274370b324cSopenharmony_ci      T *newBuffer = new T[newSize];;
275370b324cSopenharmony_ci      _items = newBuffer;
276370b324cSopenharmony_ci      _size = newSize;
277370b324cSopenharmony_ci      const T *src = buffer;
278370b324cSopenharmony_ci      for (size_t i = 0; i < newSize; i++)
279370b324cSopenharmony_ci        newBuffer[i] = src[i];
280370b324cSopenharmony_ci    }
281370b324cSopenharmony_ci    return *this;
282370b324cSopenharmony_ci  }
283370b324cSopenharmony_ci  */
284370b324cSopenharmony_ci};
285370b324cSopenharmony_ci
286370b324cSopenharmony_ci#endif
287