diff options
Diffstat (limited to 'zencore/compactbinarypackage.cpp')
| -rw-r--r-- | zencore/compactbinarypackage.cpp | 138 |
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)); |