mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-17 11:05:03 +02:00
Poco::Buffer properly handles zero-sized buffers
This commit is contained in:
@@ -41,10 +41,14 @@ public:
|
|||||||
Buffer(std::size_t capacity):
|
Buffer(std::size_t capacity):
|
||||||
_capacity(capacity),
|
_capacity(capacity),
|
||||||
_used(capacity),
|
_used(capacity),
|
||||||
_ptr(new T[capacity]),
|
_ptr(0),
|
||||||
_ownMem(true)
|
_ownMem(true)
|
||||||
/// Creates and allocates the Buffer.
|
/// Creates and allocates the Buffer.
|
||||||
{
|
{
|
||||||
|
if (capacity > 0)
|
||||||
|
{
|
||||||
|
_ptr = new T[capacity];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer(T* pMem, std::size_t length):
|
Buffer(T* pMem, std::size_t length):
|
||||||
@@ -64,26 +68,32 @@ public:
|
|||||||
Buffer(const T* pMem, std::size_t length):
|
Buffer(const T* pMem, std::size_t length):
|
||||||
_capacity(length),
|
_capacity(length),
|
||||||
_used(length),
|
_used(length),
|
||||||
_ptr(new T[length]),
|
_ptr(0),
|
||||||
_ownMem(true)
|
_ownMem(true)
|
||||||
/// Creates and allocates the Buffer; copies the contents of
|
/// Creates and allocates the Buffer; copies the contents of
|
||||||
/// the supplied memory into the buffer. Length argument specifies
|
/// the supplied memory into the buffer. Length argument specifies
|
||||||
/// the length of the supplied memory pointed to by pMem in the
|
/// the length of the supplied memory pointed to by pMem in the
|
||||||
/// number of elements of type T.
|
/// number of elements of type T.
|
||||||
{
|
{
|
||||||
if (_used)
|
if (_capacity > 0)
|
||||||
|
{
|
||||||
|
_ptr = new T[_capacity];
|
||||||
std::memcpy(_ptr, pMem, _used * sizeof(T));
|
std::memcpy(_ptr, pMem, _used * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer(const Buffer& other):
|
Buffer(const Buffer& other):
|
||||||
/// Copy constructor.
|
/// Copy constructor.
|
||||||
_capacity(other._used),
|
_capacity(other._used),
|
||||||
_used(other._used),
|
_used(other._used),
|
||||||
_ptr(new T[other._used]),
|
_ptr(0),
|
||||||
_ownMem(true)
|
_ownMem(true)
|
||||||
{
|
{
|
||||||
if (_used)
|
if (_used)
|
||||||
|
{
|
||||||
|
_ptr = new T[_used];
|
||||||
std::memcpy(_ptr, other._ptr, _used * sizeof(T));
|
std::memcpy(_ptr, other._ptr, _used * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer& operator = (const Buffer& other)
|
Buffer& operator = (const Buffer& other)
|
||||||
@@ -115,15 +125,15 @@ public:
|
|||||||
/// resized. If resize is attempted on those, IllegalAccessException
|
/// resized. If resize is attempted on those, IllegalAccessException
|
||||||
/// is thrown.
|
/// is thrown.
|
||||||
{
|
{
|
||||||
if (!_ownMem)
|
if (!_ownMem) throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
|
||||||
throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
|
|
||||||
|
|
||||||
if (newCapacity > _capacity)
|
if (newCapacity > _capacity)
|
||||||
{
|
{
|
||||||
T* ptr = new T[newCapacity];
|
T* ptr = new T[newCapacity];
|
||||||
if (preserveContent)
|
if (preserveContent)
|
||||||
|
{
|
||||||
std::memcpy(ptr, _ptr, _used * sizeof(T));
|
std::memcpy(ptr, _ptr, _used * sizeof(T));
|
||||||
|
}
|
||||||
delete [] _ptr;
|
delete [] _ptr;
|
||||||
_ptr = ptr;
|
_ptr = ptr;
|
||||||
_capacity = newCapacity;
|
_capacity = newCapacity;
|
||||||
@@ -144,18 +154,20 @@ public:
|
|||||||
/// resized. If resize is attempted on those, IllegalAccessException
|
/// resized. If resize is attempted on those, IllegalAccessException
|
||||||
/// is thrown.
|
/// is thrown.
|
||||||
{
|
{
|
||||||
if (!_ownMem)
|
if (!_ownMem) throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
|
||||||
throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
|
|
||||||
|
|
||||||
if (newCapacity != _capacity)
|
if (newCapacity != _capacity)
|
||||||
{
|
{
|
||||||
T* ptr = new T[newCapacity];
|
T* ptr = 0;
|
||||||
if (preserveContent)
|
if (newCapacity > 0)
|
||||||
{
|
{
|
||||||
std::size_t newSz = _used < newCapacity ? _used : newCapacity;
|
ptr = new T[newCapacity];
|
||||||
std::memcpy(ptr, _ptr, newSz * sizeof(T));
|
if (preserveContent)
|
||||||
|
{
|
||||||
|
std::size_t newSz = _used < newCapacity ? _used : newCapacity;
|
||||||
|
std::memcpy(ptr, _ptr, newSz * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] _ptr;
|
delete [] _ptr;
|
||||||
_ptr = ptr;
|
_ptr = ptr;
|
||||||
_capacity = newCapacity;
|
_capacity = newCapacity;
|
||||||
@@ -217,7 +229,7 @@ public:
|
|||||||
swap(_used, other._used);
|
swap(_used, other._used);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==(const Buffer& other) const
|
bool operator == (const Buffer& other) const
|
||||||
/// Compare operator.
|
/// Compare operator.
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
@@ -235,14 +247,14 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const Buffer& other) const
|
bool operator != (const Buffer& other) const
|
||||||
/// Compare operator.
|
/// Compare operator.
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
/// Sets the contents of the bufer to zero.
|
/// Sets the contents of the buffer to zero.
|
||||||
{
|
{
|
||||||
std::memset(_ptr, 0, _used * sizeof(T));
|
std::memset(_ptr, 0, _used * sizeof(T));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user