- optimize memory usage

This commit is contained in:
2026-07-06 12:33:45 +03:00
parent 25e30a6ba7
commit 7f638a5aef
3 changed files with 41 additions and 10 deletions
+28 -4
View File
@@ -497,12 +497,12 @@ size_t BufferReader::count() const
}
// -------------- BufferWriter ----------------------
BufferWriter::BufferWriter(ByteBuffer &buffer)
:mData(buffer.mutableData()), mIndex(0)
BufferWriter::BufferWriter(ByteBuffer &buffer, size_t startOffset)
:mBuffer(&buffer), mData(buffer.mutableData() + startOffset), mBase(startOffset), mIndex(0), mCapacity(0)
{}
BufferWriter::BufferWriter(void *output)
:mData(reinterpret_cast<uint8_t*>(output)), mIndex(0)
BufferWriter::BufferWriter(void *output, size_t capacity)
:mBuffer(nullptr), mData(reinterpret_cast<uint8_t*>(output)), mBase(0), mIndex(0), mCapacity(capacity)
{}
@@ -545,6 +545,30 @@ void BufferWriter::writeIp(const NetworkAddress& ip)
void BufferWriter::writeBuffer(const void* dataPtr, size_t dataSize)
{
if (dataSize == 0)
return;
if (mBuffer)
{
// Growable mode: ensure the backing buffer is large enough, then refresh
// the cached pointer in case resize() reallocated the storage.
size_t needed = mBase + mIndex + dataSize;
if (needed > mBuffer->size())
mBuffer->resize(needed);
mData = mBuffer->mutableData() + mBase;
}
else
{
// Bounded mode: never write past the caller-supplied capacity.
if (mIndex + dataSize > mCapacity)
{
assert(0 && "BufferWriter capacity exceeded");
dataSize = mIndex < mCapacity ? mCapacity - mIndex : 0;
if (dataSize == 0)
return;
}
}
memmove(mData + mIndex, dataPtr, dataSize);
mIndex += dataSize;
}
+9 -4
View File
@@ -172,12 +172,17 @@ namespace ice
class BufferWriter
{
protected:
uint8_t* mData;
size_t mIndex;
ByteBuffer* mBuffer; // Non-null => growable: writes resize this buffer to fit
uint8_t* mData; // Cached write pointer (refreshed on growth in growable mode)
size_t mBase; // Start offset within mBuffer (growable mode)
size_t mIndex; // Bytes written since mBase
size_t mCapacity; // Usable capacity from mData (raw/bounded mode)
public:
BufferWriter(void* output);
BufferWriter(ByteBuffer& buffer);
// Bounded writer over caller-owned memory. Writes past 'capacity' are refused.
BufferWriter(void* output, size_t capacity);
// Growable writer: the backing buffer is resized as needed so writes never overflow.
BufferWriter(ByteBuffer& buffer, size_t startOffset = 0);
void writeUInt(uint32_t value);
void writeUShort(uint16_t value);
+4 -2
View File
@@ -216,8 +216,10 @@ void StunMessage::buildPacket(ByteBuffer& buffer, const std::string& password)
for (size_t i=0; i<4; i++)
bitstream.writeBit(bit(msgtype, 3-i));
// Enqueue 2 bytes of length - now it is zero
BufferWriter stream(buffer.mutableData() + bitstream.count() / 8);
// Enqueue 2 bytes of length - now it is zero.
// Growable writer starting right after the bits already emitted; it resizes
// 'buffer' as attributes are appended so an oversized message cannot overflow.
BufferWriter stream(buffer, bitstream.count() / 8);
stream.writeUShort(0);
// Enqueue magic cookie value