// Common/MyBuffer.h | |
#ifndef __COMMON_MY_BUFFER_H | |
#define __COMMON_MY_BUFFER_H | |
#include "Defs.h" | |
/* 7-Zip now uses CBuffer only as CByteBuffer. | |
So there is no need to use MY_ARRAY_NEW macro in CBuffer code. */ | |
template <class T> class CBuffer | |
{ | |
T *_items; | |
size_t _size; | |
public: | |
void Free() | |
{ | |
if (_items) | |
{ | |
delete []_items; | |
_items = 0; | |
} | |
_size = 0; | |
} | |
CBuffer(): _items(0), _size(0) {}; | |
CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; } | |
CBuffer(const CBuffer &buffer): _items(0), _size(0) | |
{ | |
size_t size = buffer._size; | |
if (size != 0) | |
{ | |
_items = new T[size]; | |
memcpy(_items, buffer._items, size * sizeof(T)); | |
_size = size; | |
} | |
} | |
~CBuffer() { delete []_items; } | |
operator T *() { return _items; } | |
operator const T *() const { return _items; } | |
size_t Size() const { return _size; } | |
void Alloc(size_t size) | |
{ | |
if (size != _size) | |
{ | |
Free(); | |
if (size != 0) | |
{ | |
_items = new T[size]; | |
_size = size; | |
} | |
} | |
} | |
void AllocAtLeast(size_t size) | |
{ | |
if (size > _size) | |
{ | |
Free(); | |
_items = new T[size]; | |
_size = size; | |
} | |
} | |
void CopyFrom(const T *data, size_t size) | |
{ | |
Alloc(size); | |
if (size != 0) | |
memcpy(_items, data, size * sizeof(T)); | |
} | |
void ChangeSize_KeepData(size_t newSize, size_t keepSize) | |
{ | |
if (newSize == _size) | |
return; | |
T *newBuffer = NULL; | |
if (newSize != 0) | |
{ | |
newBuffer = new T[newSize]; | |
if (keepSize > _size) | |
keepSize = _size; | |
if (keepSize != 0) | |
memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T)); | |
} | |
delete []_items; | |
_items = newBuffer; | |
_size = newSize; | |
} | |
CBuffer& operator=(const CBuffer &buffer) | |
{ | |
if (&buffer != this) | |
CopyFrom(buffer, buffer._size); | |
return *this; | |
} | |
}; | |
template <class T> | |
bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2) | |
{ | |
size_t size1 = b1.Size(); | |
if (size1 != b2.Size()) | |
return false; | |
if (size1 == 0) | |
return true; | |
return memcmp(b1, b2, size1 * sizeof(T)) == 0; | |
} | |
template <class T> | |
bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2) | |
{ | |
size_t size1 = b1.Size(); | |
if (size1 != b2.Size()) | |
return true; | |
if (size1 == 0) | |
return false; | |
return memcmp(b1, b2, size1 * sizeof(T)) != 0; | |
} | |
// typedef CBuffer<char> CCharBuffer; | |
// typedef CBuffer<wchar_t> CWCharBuffer; | |
typedef CBuffer<unsigned char> CByteBuffer; | |
template <class T> class CObjArray | |
{ | |
protected: | |
T *_items; | |
private: | |
// we disable copy | |
CObjArray(const CObjArray &buffer); | |
void operator=(const CObjArray &buffer); | |
public: | |
void Free() | |
{ | |
delete []_items; | |
_items = 0; | |
} | |
CObjArray(size_t size): _items(0) | |
{ | |
if (size != 0) | |
{ | |
MY_ARRAY_NEW(_items, T, size) | |
// _items = new T[size]; | |
} | |
} | |
CObjArray(): _items(0) {}; | |
~CObjArray() { delete []_items; } | |
operator T *() { return _items; } | |
operator const T *() const { return _items; } | |
void Alloc(size_t newSize) | |
{ | |
delete []_items; | |
_items = 0; | |
MY_ARRAY_NEW(_items, T, newSize) | |
// _items = new T[newSize]; | |
} | |
}; | |
typedef CObjArray<unsigned char> CByteArr; | |
typedef CObjArray<bool> CBoolArr; | |
typedef CObjArray<int> CIntArr; | |
typedef CObjArray<unsigned> CUIntArr; | |
template <class T> class CObjArray2 | |
{ | |
T *_items; | |
unsigned _size; | |
// we disable copy | |
CObjArray2(const CObjArray2 &buffer); | |
void operator=(const CObjArray2 &buffer); | |
public: | |
void Free() | |
{ | |
delete []_items; | |
_items = 0; | |
_size = 0; | |
} | |
CObjArray2(): _items(0), _size(0) {}; | |
/* | |
CObjArray2(const CObjArray2 &buffer): _items(0), _size(0) | |
{ | |
size_t newSize = buffer._size; | |
if (newSize != 0) | |
{ | |
T *newBuffer = new T[newSize];; | |
_items = newBuffer; | |
_size = newSize; | |
const T *src = buffer; | |
for (size_t i = 0; i < newSize; i++) | |
newBuffer[i] = src[i]; | |
} | |
} | |
*/ | |
/* | |
CObjArray2(size_t size): _items(0), _size(0) | |
{ | |
if (size != 0) | |
{ | |
_items = new T[size]; | |
_size = size; | |
} | |
} | |
*/ | |
~CObjArray2() { delete []_items; } | |
operator T *() { return _items; } | |
operator const T *() const { return _items; } | |
unsigned Size() const { return (unsigned)_size; } | |
bool IsEmpty() const { return _size == 0; } | |
// SetSize doesn't keep old items. It allocates new array if size is not equal | |
void SetSize(unsigned size) | |
{ | |
if (size == _size) | |
return; | |
T *newBuffer = NULL; | |
if (size != 0) | |
{ | |
MY_ARRAY_NEW(newBuffer, T, size) | |
// newBuffer = new T[size]; | |
} | |
delete []_items; | |
_items = newBuffer; | |
_size = size; | |
} | |
/* | |
CObjArray2& operator=(const CObjArray2 &buffer) | |
{ | |
Free(); | |
size_t newSize = buffer._size; | |
if (newSize != 0) | |
{ | |
T *newBuffer = new T[newSize];; | |
_items = newBuffer; | |
_size = newSize; | |
const T *src = buffer; | |
for (size_t i = 0; i < newSize; i++) | |
newBuffer[i] = src[i]; | |
} | |
return *this; | |
} | |
*/ | |
}; | |
#endif |