From 151b0a7766a115103416e48a6c9e0bf5acc2a5aa Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 6 Mar 2024 12:49:31 +0100 Subject: Add WriteMeasuredVarUInt to avoid measuring ints twice before writing (#665) Avoid double resize of buffer in CbWriter::SetName and CbWriter::AddBinary Add WriteMeasuredVarUInt to avoid measuring ints twice before writing --- src/zencore/compactbinarybuilder.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src/zencore/compactbinarybuilder.cpp') diff --git a/src/zencore/compactbinarybuilder.cpp b/src/zencore/compactbinarybuilder.cpp index 5c08d2e6e..3331291ce 100644 --- a/src/zencore/compactbinarybuilder.cpp +++ b/src/zencore/compactbinarybuilder.cpp @@ -221,12 +221,11 @@ CbWriter::SetName(const std::string_view Name) State.Flags |= StateFlags::Name; const uint32_t NameLenByteCount = MeasureVarUInt(uint32_t(Name.size())); const int64_t NameLenOffset = Data.size(); - Data.resize(NameLenOffset + NameLenByteCount); + Data.resize(NameLenOffset + NameLenByteCount + Name.size()); - WriteVarUInt(uint64_t(Name.size()), Data.data() + NameLenOffset); + WriteMeasuredVarUInt(uint64_t(Name.size()), NameLenByteCount, Data.data() + NameLenOffset); - const uint8_t* NamePtr = reinterpret_cast(Name.data()); - Data.insert(Data.end(), NamePtr, NamePtr + Name.size()); + memcpy(Data.data() + NameLenOffset + NameLenByteCount, Name.data(), Name.size()); return *this; } @@ -341,7 +340,7 @@ CbWriter::EndObject() const uint64_t Size = uint64_t(Data.size() - PayloadOffset); const uint32_t SizeByteCount = MeasureVarUInt(Size); Data.insert(Data.begin() + PayloadOffset, SizeByteCount, 0); - WriteVarUInt(Size, Data.data() + PayloadOffset); + WriteMeasuredVarUInt(Size, SizeByteCount, Data.data() + PayloadOffset); EndField(bUniform ? CbFieldType::UniformObject : CbFieldType::Object); } @@ -400,8 +399,8 @@ CbWriter::EndArray() const uint64_t Size = uint64_t(Data.size() - PayloadOffset) + CountByteCount; const uint32_t SizeByteCount = MeasureVarUInt(Size); Data.insert(Data.begin() + PayloadOffset, SizeByteCount + CountByteCount, 0); - WriteVarUInt(Size, Data.data() + PayloadOffset); - WriteVarUInt(Count, Data.data() + PayloadOffset + SizeByteCount); + WriteMeasuredVarUInt(Size, SizeByteCount, Data.data() + PayloadOffset); + WriteMeasuredVarUInt(Count, CountByteCount, Data.data() + PayloadOffset + SizeByteCount); EndField(bUniform ? CbFieldType::UniformArray : CbFieldType::Array); } @@ -429,13 +428,13 @@ CbWriter::AddNull() void CbWriter::AddBinary(const void* const Value, const uint64_t Size) { - const size_t SizeByteCount = MeasureVarUInt(Size); + const uint32_t SizeByteCount = MeasureVarUInt(Size); Data.reserve(Data.size() + 1 + SizeByteCount + Size); BeginField(); const size_t SizeOffset = Data.size(); - Data.resize(Data.size() + SizeByteCount); - WriteVarUInt(Size, Data.data() + SizeOffset); - Data.insert(Data.end(), static_cast(Value), static_cast(Value) + Size); + Data.resize(Data.size() + SizeByteCount + Size); + WriteMeasuredVarUInt(Size, SizeByteCount, Data.data() + SizeOffset); + memcpy(Data.data() + SizeOffset + SizeByteCount, Value, Size); EndField(CbFieldType::Binary); } @@ -468,7 +467,7 @@ CbWriter::AddString(const std::string_view Value) Data.resize(Offset + SizeByteCount + Size); uint8_t* StringData = Data.data() + Offset; - WriteVarUInt(Size, StringData); + WriteMeasuredVarUInt(Size, SizeByteCount, StringData); StringData += SizeByteCount; if (Size > 0) { @@ -489,7 +488,7 @@ CbWriter::AddString(const std::wstring_view Value) const int64_t Offset = Data.size(); Data.resize(Offset + SizeByteCount + Size); uint8_t* StringData = Data.data() + Offset; - WriteVarUInt(Size, StringData); + WriteMeasuredVarUInt(Size, SizeByteCount, StringData); StringData += SizeByteCount; if (Size > 0) { @@ -511,7 +510,7 @@ CbWriter::AddInteger(const int32_t Value) const uint32_t MagnitudeByteCount = MeasureVarUInt(Magnitude); const int64_t Offset = Data.size(); Data.resize(Offset + MagnitudeByteCount); - WriteVarUInt(Magnitude, Data.data() + Offset); + WriteMeasuredVarUInt(Magnitude, MagnitudeByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerNegative); } @@ -526,7 +525,7 @@ CbWriter::AddInteger(const int64_t Value) const uint64_t Magnitude = ~uint64_t(Value); const uint32_t MagnitudeByteCount = MeasureVarUInt(Magnitude); const uint64_t Offset = AddUninitialized(Data, MagnitudeByteCount); - WriteVarUInt(Magnitude, Data.data() + Offset); + WriteMeasuredVarUInt(Magnitude, MagnitudeByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerNegative); } @@ -537,7 +536,7 @@ CbWriter::AddInteger(const uint32_t Value) BeginField(); const uint32_t ValueByteCount = MeasureVarUInt(Value); const uint64_t Offset = AddUninitialized(Data, ValueByteCount); - WriteVarUInt(Value, Data.data() + Offset); + WriteMeasuredVarUInt(Value, ValueByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerPositive); } @@ -548,7 +547,7 @@ CbWriter::AddInteger(const uint64_t Value) BeginField(); const uint32_t ValueByteCount = MeasureVarUInt(Value); const uint64_t Offset = AddUninitialized(Data, ValueByteCount); - WriteVarUInt(Value, Data.data() + Offset); + WriteMeasuredVarUInt(Value, ValueByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerPositive); } -- cgit v1.2.3