aboutsummaryrefslogtreecommitdiff
path: root/zencore/compactbinarypackage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zencore/compactbinarypackage.cpp')
-rw-r--r--zencore/compactbinarypackage.cpp138
1 files changed, 75 insertions, 63 deletions
diff --git a/zencore/compactbinarypackage.cpp b/zencore/compactbinarypackage.cpp
index a25466bed..19675b9cf 100644
--- a/zencore/compactbinarypackage.cpp
+++ b/zencore/compactbinarypackage.cpp
@@ -11,7 +11,7 @@ namespace zen {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CbAttachment::CbAttachment(const CompressedBuffer& InValue) : CbAttachment(InValue.MakeOwned())
+CbAttachment::CbAttachment(const CompressedBuffer& InValue, const IoHash& Hash) : CbAttachment(InValue.MakeOwned(), Hash)
{
}
@@ -19,36 +19,40 @@ CbAttachment::CbAttachment(const SharedBuffer& InValue) : CbAttachment(Composite
{
}
-CbAttachment::CbAttachment(const SharedBuffer& InValue, [[maybe_unused]] const IoHash& InHash)
-: CbAttachment(CompositeBuffer(InValue), InHash)
+CbAttachment::CbAttachment(const SharedBuffer& InValue, const IoHash& InHash) : CbAttachment(CompositeBuffer(InValue), InHash)
{
}
-CbAttachment::CbAttachment(const CompositeBuffer& InValue) : Value{std::in_place_type<BinaryValue>, InValue}
+CbAttachment::CbAttachment(const CompositeBuffer& InValue)
+: Hash(InValue.IsNull() ? IoHash::Zero : IoHash::HashBuffer(InValue))
+, Value(InValue)
{
- if (std::get<BinaryValue>(Value).Buffer.IsNull())
+ if (std::get<CompositeBuffer>(Value).IsNull())
{
Value.emplace<std::nullptr_t>();
}
}
-CbAttachment::CbAttachment(CompositeBuffer&& InValue) : Value{std::in_place_type<BinaryValue>, InValue}
+CbAttachment::CbAttachment(CompositeBuffer&& InValue)
+: Hash(InValue.IsNull() ? IoHash::Zero : IoHash::HashBuffer(InValue))
+, Value(std::move(InValue))
+
{
- if (std::get<BinaryValue>(Value).Buffer.IsNull())
+ if (std::get<CompositeBuffer>(Value).IsNull())
{
Value.emplace<std::nullptr_t>();
}
}
-CbAttachment::CbAttachment(CompositeBuffer&& InValue, const IoHash& Hash) : Value{std::in_place_type<BinaryValue>, InValue, Hash}
+CbAttachment::CbAttachment(CompositeBuffer&& InValue, const IoHash& InHash) : Hash(InHash), Value(InValue)
{
- if (std::get<BinaryValue>(Value).Buffer.IsNull())
+ if (std::get<CompositeBuffer>(Value).IsNull())
{
Value.emplace<std::nullptr_t>();
}
}
-CbAttachment::CbAttachment(CompressedBuffer&& InValue) : Value(std::in_place_type<CompressedBuffer>, InValue)
+CbAttachment::CbAttachment(CompressedBuffer&& InValue, const IoHash& InHash) : Hash(InHash), Value(InValue)
{
if (std::get<CompressedBuffer>(Value).IsNull())
{
@@ -61,11 +65,13 @@ CbAttachment::CbAttachment(const CbObject& InValue, const IoHash* const InHash)
auto SetValue = [&](const CbObject& ValueToSet) {
if (InHash)
{
- Value.emplace<CbObjectValue>(ValueToSet, *InHash);
+ Value.emplace<CbObject>(ValueToSet);
+ Hash = *InHash;
}
else
{
- Value.emplace<CbObjectValue>(ValueToSet, ValueToSet.GetHash());
+ Value.emplace<CbObject>(ValueToSet);
+ Hash = ValueToSet.GetHash();
}
};
@@ -94,7 +100,8 @@ CbAttachment::TryLoad(CbFieldIterator& Fields)
if (const CbObjectView ObjectView = Fields.AsObjectView(); !Fields.HasError())
{
// Is a null object or object not prefixed with a precomputed hash value
- Value.emplace<CbObjectValue>(CbObject(ObjectView, Fields.GetOuterBuffer()), ObjectView.GetHash());
+ Value.emplace<CbObject>(CbObject(ObjectView, Fields.GetOuterBuffer()));
+ Hash = ObjectView.GetHash();
++Fields;
}
else if (const IoHash ObjectAttachmentHash = Fields.AsObjectAttachment(); !Fields.HasError())
@@ -106,7 +113,8 @@ CbAttachment::TryLoad(CbFieldIterator& Fields)
{
return false;
}
- Value.emplace<CbObjectValue>(CbObject(InnerObjectView, Fields.GetOuterBuffer()), ObjectAttachmentHash);
+ Value.emplace<CbObject>(CbObject(InnerObjectView, Fields.GetOuterBuffer()));
+ Hash = ObjectAttachmentHash;
++Fields;
}
else if (const IoHash BinaryAttachmentHash = Fields.AsBinaryAttachment(); !Fields.HasError())
@@ -118,7 +126,8 @@ CbAttachment::TryLoad(CbFieldIterator& Fields)
{
return false;
}
- Value.emplace<BinaryValue>(SharedBuffer::MakeView(BinaryView, Fields.GetOuterBuffer()), BinaryAttachmentHash);
+ Value.emplace<CompositeBuffer>(SharedBuffer::MakeView(BinaryView, Fields.GetOuterBuffer()));
+ Hash = BinaryAttachmentHash;
++Fields;
}
else if (MemoryView BinaryView = Fields.AsBinaryView(); !Fields.HasError())
@@ -126,14 +135,17 @@ CbAttachment::TryLoad(CbFieldIterator& Fields)
if (BinaryView.GetSize() > 0)
{
// Is a compressed binary blob
- Value.emplace<CompressedBuffer>(
- CompressedBuffer::FromCompressed(SharedBuffer::MakeView(BinaryView, Fields.GetOuterBuffer())).MakeOwned());
+ CompressedBuffer Compressed =
+ CompressedBuffer::FromCompressed(SharedBuffer::MakeView(BinaryView, Fields.GetOuterBuffer())).MakeOwned();
+ Value.emplace<CompressedBuffer>(Compressed);
+ Hash = IoHash::FromBLAKE3(Compressed.GetRawHash());
++Fields;
}
else
{
// Is an uncompressed empty binary blob
- Value.emplace<BinaryValue>(SharedBuffer::MakeView(BinaryView, Fields.GetOuterBuffer()), IoHash::HashBuffer(nullptr, 0));
+ Value.emplace<CompositeBuffer>(SharedBuffer::MakeView(BinaryView, Fields.GetOuterBuffer()));
+ Hash = IoHash::HashBuffer(nullptr, 0);
++Fields;
}
}
@@ -179,7 +191,8 @@ TryLoad_ArchiveFieldIntoAttachment(CbAttachment& TargetAttachment, CbField&& Fie
if (Buffer.GetSize() > 0)
{
// Is a compressed binary blob
- TargetAttachment = CbAttachment(CompressedBuffer::FromCompressed(std::move(Buffer)));
+ CompressedBuffer Compressed = CompressedBuffer::FromCompressed(std::move(Buffer));
+ TargetAttachment = CbAttachment(Compressed, IoHash::FromBLAKE3(Compressed.GetRawHash()));
}
else
{
@@ -205,25 +218,25 @@ CbAttachment::TryLoad(BinaryReader& Reader, BufferAllocator Allocator)
void
CbAttachment::Save(CbWriter& Writer) const
{
- if (const CbObjectValue* ObjValue = std::get_if<CbObjectValue>(&Value))
+ if (const CbObject* Object = std::get_if<CbObject>(&Value))
{
- if (ObjValue->Object)
+ if (*Object)
{
- Writer.AddObjectAttachment(ObjValue->Hash);
+ Writer.AddObjectAttachment(Hash);
}
- Writer.AddObject(ObjValue->Object);
+ Writer.AddObject(*Object);
}
- else if (const BinaryValue* BinValue = std::get_if<BinaryValue>(&Value))
+ else if (const CompositeBuffer* Binary = std::get_if<CompositeBuffer>(&Value))
{
- if (BinValue->Buffer.GetSize() > 0)
+ if (Binary->GetSize() > 0)
{
- Writer.AddBinaryAttachment(BinValue->Hash);
+ Writer.AddBinaryAttachment(Hash);
}
- Writer.AddBinary(BinValue->Buffer);
+ Writer.AddBinary(*Binary);
}
- else if (const CompressedBuffer* BufferValue = std::get_if<CompressedBuffer>(&Value))
+ else if (const CompressedBuffer* Compressed = std::get_if<CompressedBuffer>(&Value))
{
- Writer.AddBinary(BufferValue->GetCompressed());
+ Writer.AddBinary(Compressed->GetCompressed());
}
}
@@ -244,7 +257,7 @@ CbAttachment::IsNull() const
bool
CbAttachment::IsBinary() const
{
- return std::holds_alternative<BinaryValue>(Value);
+ return std::holds_alternative<CompositeBuffer>(Value);
}
bool
@@ -256,36 +269,21 @@ CbAttachment::IsCompressedBinary() const
bool
CbAttachment::IsObject() const
{
- return std::holds_alternative<CbObjectValue>(Value);
+ return std::holds_alternative<CbObject>(Value);
}
IoHash
CbAttachment::GetHash() const
{
- if (const CompressedBuffer* Buffer = std::get_if<CompressedBuffer>(&Value))
- {
- return IoHash::FromBLAKE3(Buffer->GetRawHash());
- }
-
- if (const BinaryValue* BinValue = std::get_if<BinaryValue>(&Value))
- {
- return BinValue->Hash;
- }
-
- if (const CbObjectValue* ObjectValue = std::get_if<CbObjectValue>(&Value))
- {
- return ObjectValue->Hash;
- }
-
- return IoHash::Zero;
+ return Hash;
}
CompositeBuffer
CbAttachment::AsCompositeBinary() const
{
- if (const BinaryValue* BinValue = std::get_if<BinaryValue>(&Value))
+ if (const CompositeBuffer* BinValue = std::get_if<CompositeBuffer>(&Value))
{
- return BinValue->Buffer;
+ return *BinValue;
}
return CompositeBuffer::Null;
@@ -294,9 +292,9 @@ CbAttachment::AsCompositeBinary() const
SharedBuffer
CbAttachment::AsBinary() const
{
- if (const BinaryValue* BinValue = std::get_if<BinaryValue>(&Value))
+ if (const CompositeBuffer* BinValue = std::get_if<CompositeBuffer>(&Value))
{
- return BinValue->Buffer.Flatten();
+ return BinValue->Flatten();
}
return {};
@@ -305,9 +303,9 @@ CbAttachment::AsBinary() const
CompressedBuffer
CbAttachment::AsCompressedBinary() const
{
- if (const CompressedBuffer* Buffer = std::get_if<CompressedBuffer>(&Value))
+ if (const CompressedBuffer* CompValue = std::get_if<CompressedBuffer>(&Value))
{
- return *Buffer;
+ return *CompValue;
}
return CompressedBuffer::Null;
@@ -317,9 +315,9 @@ CbAttachment::AsCompressedBinary() const
CbObject
CbAttachment::AsObject() const
{
- if (const CbObjectValue* ObjectValue = std::get_if<CbObjectValue>(&Value))
+ if (const CbObject* ObjectValue = std::get_if<CbObject>(&Value))
{
- return ObjectValue->Object;
+ return *ObjectValue;
}
return {};
@@ -377,6 +375,19 @@ CbPackage::AddAttachment(const CbAttachment& Attachment, AttachmentResolver* Res
}
}
+void
+CbPackage::AddAttachments(std::span<const CbAttachment> InAttachments)
+{
+ if (InAttachments.empty())
+ {
+ return;
+ }
+ // Assume we have no duplicates!
+ Attachments.insert(Attachments.end(), InAttachments.begin(), InAttachments.end());
+ std::sort(Attachments.begin(), Attachments.end());
+ ZEN_ASSERT_SLOW(std::unique(Attachments.begin(), Attachments.end()) == Attachments.end());
+}
+
int32_t
CbPackage::RemoveAttachment(const IoHash& Hash)
{
@@ -710,7 +721,7 @@ namespace legacy {
{
return false;
}
- Package.AddAttachment(CbAttachment(Compressed));
+ Package.AddAttachment(CbAttachment(Compressed, Hash));
}
else
{
@@ -738,7 +749,7 @@ namespace legacy {
{
if (CompressedBuffer Compressed = CompressedBuffer::FromCompressed(AttachmentData))
{
- Package.AddAttachment(CbAttachment(Compressed));
+ Package.AddAttachment(CbAttachment(Compressed, Hash));
}
else
{
@@ -978,15 +989,15 @@ TEST_CASE("usonpackage.serialization")
{
using namespace std::literals;
- const auto TestSaveLoadValidate = [&](const char* Test, const CbPackage& Package) {
+ const auto TestSaveLoadValidate = [&](const char* Test, CbPackage& InOutPackage) {
ZEN_UNUSED(Test);
CbWriter Writer;
- Package.Save(Writer);
+ InOutPackage.Save(Writer);
CbFieldIterator Fields = Writer.Save();
BinaryWriter MemStream;
- Package.Save(MemStream);
+ InOutPackage.Save(MemStream);
CHECK(MakeMemoryView(MemStream).EqualBytes(Fields.GetRangeBuffer().GetView()));
CHECK(ValidateCompactBinaryRange(MakeMemoryView(MemStream), CbValidateMode::All) == CbValidateError::None);
@@ -995,13 +1006,14 @@ TEST_CASE("usonpackage.serialization")
CbPackage FromFields;
FromFields.TryLoad(Fields);
CHECK_FALSE(bool(Fields));
- CHECK(FromFields == Package);
+ CHECK(FromFields == InOutPackage);
CbPackage FromArchive;
BinaryReader ReadAr(MakeMemoryView(MemStream));
FromArchive.TryLoad(ReadAr);
CHECK(ReadAr.CurrentOffset() == ReadAr.Size());
- CHECK(FromArchive == Package);
+ CHECK(FromArchive == InOutPackage);
+ InOutPackage = FromArchive;
};
SUBCASE("Empty")
@@ -1083,7 +1095,7 @@ TEST_CASE("usonpackage.serialization")
const CbAttachment* const Object2Attachment = Package.FindAttachment(Object2.GetHash());
CHECK((Object1Attachment && Object1Attachment->AsObject().Equals(Object1)));
- CHECK((Object2Attachment && Object2Attachment->AsBinary() == Object2.GetBuffer()));
+ CHECK((Object2Attachment && Object2Attachment->AsBinary().GetView().EqualBytes(Object2.GetBuffer().GetView())));
SharedBuffer Object1ClonedBuffer = SharedBuffer::Clone(Object1.GetOuterBuffer());
Package.AddAttachment(CbAttachment(Object1ClonedBuffer));