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