Files
UnrealEngineUWP/Engine/Source/Developer/DerivedDataCache/Private/ZenSerialization.cpp
zousar shaker 8c80e5a866 Change Compact Binary Package API to represent binary attachments as compressed buffers identified by their raw hash.
Change Compact Binary Package serialization for binary attachments, compressed binary attachments and objects.

#rb devin.doucette

#ROBOMERGE-AUTHOR: zousar.shaker
#ROBOMERGE-SOURCE: CL 17450533 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v870-17433530)

[CL 17450587 by zousar shaker in ue5-release-engine-test branch]
2021-09-07 18:07:00 -04:00

132 lines
3.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "ZenSerialization.h"
#include "Serialization/CompactBinary.h"
#include "Serialization/CompactBinaryPackage.h"
#include "Serialization/CompactBinarySerialization.h"
#include "Serialization/CompactBinaryValidation.h"
#include "Serialization/CompactBinaryWriter.h"
#if UE_WITH_ZEN
namespace UE::Zen {
void SaveCbAttachment(const FCbAttachment& Attachment, FCbWriter& Writer)
{
if (Attachment.IsObject())
{
FCbObject Object = Attachment.AsObject();
Writer.AddBinary(Object.GetBuffer().Flatten());
if (Object)
{
Writer.AddObjectAttachment(Attachment.GetHash());
}
}
else if (Attachment.IsBinary())
{
Writer.AddBinary(Attachment.AsBinary());
Writer.AddBinaryAttachment(Attachment.GetHash());
}
else if (Attachment.IsNull())
{
Writer.AddBinary(FMemoryView());
}
else
{
// NOTE: Compressed binary is not supported in this serialization format
checkNoEntry();
}
}
void SaveCbPackage(const FCbPackage& Package, FCbWriter& Writer)
{
if (const FCbObject& RootObject = Package.GetObject())
{
Writer.AddObject(RootObject);
Writer.AddObjectAttachment(Package.GetObjectHash());
}
for (const FCbAttachment& Attachment : Package.GetAttachments())
{
SaveCbAttachment(Attachment, Writer);
}
Writer.AddNull();
}
void SaveCbPackage(const FCbPackage& Package, FArchive& Ar)
{
FCbWriter Writer;
SaveCbPackage(Package, Writer);
Writer.Save(Ar);
}
bool TryLoadCbPackage(FCbPackage& Package, FArchive& Ar, FCbBufferAllocator Allocator)
{
uint8 StackBuffer[64];
const auto StackAllocator = [&Allocator, &StackBuffer](uint64 Size) -> FUniqueBuffer
{
return Size <= sizeof(StackBuffer) ? FUniqueBuffer::MakeView(StackBuffer, Size) : Allocator(Size);
};
Package = FCbPackage();
for (;;)
{
FCbField ValueField = LoadCompactBinary(Ar, StackAllocator);
if (!ValueField)
{
Ar.SetError();
return false;
}
if (ValueField.IsNull())
{
return true;
}
else if (ValueField.IsBinary())
{
const FMemoryView View = ValueField.AsBinaryView();
if (View.GetSize() > 0)
{
FSharedBuffer Buffer = FSharedBuffer::MakeView(View, ValueField.GetOuterBuffer()).MakeOwned();
FCbField HashField = LoadCompactBinary(Ar, StackAllocator);
const FIoHash& Hash = HashField.AsAttachment();
if (HashField.HasError() || FIoHash::HashBuffer(Buffer) != Hash)
{
Ar.SetError();
return false;
}
if (HashField.IsObjectAttachment())
{
Package.AddAttachment(FCbAttachment(FCbObject(MoveTemp(Buffer)), Hash));
}
else
{
Package.AddAttachment(FCbAttachment(FCompositeBuffer(MoveTemp(Buffer)), Hash));
}
}
}
else
{
FCbObject Object = ValueField.AsObject();
if (ValueField.HasError())
{
Ar.SetError();
return false;
}
if (Object)
{
FCbField HashField = LoadCompactBinary(Ar, StackAllocator);
FIoHash ObjectHash = HashField.AsObjectAttachment();
if (HashField.HasError() || Object.GetHash() != ObjectHash)
{
Ar.SetError();
return false;
}
Package.SetObject(Object, ObjectHash);
}
}
}
}
}
#endif // UE_WITH_ZEN