diff options
| author | Martin Ridgers <[email protected]> | 2021-09-15 09:22:32 +0200 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-09-15 09:23:33 +0200 |
| commit | 8f5e773529858223beeecf5d1b69c23991df644e (patch) | |
| tree | 2c360c67e028f5ecd7368212b0adf8b23578ff9d /zenhttp/httpshared.cpp | |
| parent | Use zen::Sleep() in timer.cpp's tests (diff) | |
| parent | Updated function service to new package management API (diff) | |
| download | zen-8f5e773529858223beeecf5d1b69c23991df644e.tar.xz zen-8f5e773529858223beeecf5d1b69c23991df644e.zip | |
Merge main
Diffstat (limited to 'zenhttp/httpshared.cpp')
| -rw-r--r-- | zenhttp/httpshared.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/zenhttp/httpshared.cpp b/zenhttp/httpshared.cpp new file mode 100644 index 000000000..68252a763 --- /dev/null +++ b/zenhttp/httpshared.cpp @@ -0,0 +1,138 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "httpshared.h" + +#include <zencore/compactbinarypackage.h> +#include <zencore/compositebuffer.h> +#include <zencore/iobuffer.h> +#include <zencore/iohash.h> +#include <zencore/stream.h> + +#include <span> +#include <vector> + +namespace zen { + +CompositeBuffer +FormatPackageMessageBuffer(const CbPackage& Data) +{ + std::vector<IoBuffer> Message = FormatPackageMessage(Data); + + std::vector<SharedBuffer> Buffers; + + for (IoBuffer& Buf : Message) + { + Buffers.push_back(SharedBuffer(Buf)); + } + + return CompositeBuffer(std::move(Buffers)); +} + +std::vector<IoBuffer> +FormatPackageMessage(const CbPackage& Data) +{ + const std::span<const CbAttachment>& Attachments = Data.GetAttachments(); + + std::vector<IoBuffer> ResponseBuffers; + ResponseBuffers.reserve(3 + Attachments.size()); // TODO: may want to use an additional fudge factor here to avoid growing since each + // attachment is likely to consist of several buffers + + uint64_t TotalAttachmentsSize = 0; + + // Fixed size header + + CbPackageHeader Hdr{.HeaderMagic = kCbPkgMagic, .AttachmentCount = gsl::narrow<uint32_t>(Attachments.size())}; + + ResponseBuffers.push_back(IoBufferBuilder::MakeCloneFromMemory(&Hdr, sizeof Hdr)); + + // Attachment metadata array + + IoBuffer AttachmentMetadataBuffer = IoBuffer{sizeof(CbAttachmentEntry) * (Attachments.size() + /* root */ 1)}; + + CbAttachmentEntry* AttachmentInfo = reinterpret_cast<CbAttachmentEntry*>(AttachmentMetadataBuffer.MutableData()); + + ResponseBuffers.push_back(AttachmentMetadataBuffer); // Attachment metadata + + // Root object + + IoBuffer RootIoBuffer = Data.GetObject().GetBuffer().AsIoBuffer(); + ResponseBuffers.push_back(RootIoBuffer); // Root object + + *AttachmentInfo++ = {.AttachmentSize = RootIoBuffer.Size(), .AttachmentHash = Data.GetObjectHash()}; + + // Attachment payloads + + for (const CbAttachment& Attachment : Attachments) + { + CompressedBuffer AttachmentBuffer = Attachment.AsCompressedBinary(); + CompositeBuffer Compressed = AttachmentBuffer.GetCompressed(); + + *AttachmentInfo++ = {.AttachmentSize = AttachmentBuffer.GetCompressedSize(), + .AttachmentHash = IoHash::FromBLAKE3(AttachmentBuffer.GetRawHash())}; + + for (const SharedBuffer& Segment : Compressed.GetSegments()) + { + ResponseBuffers.push_back(Segment.AsIoBuffer()); + TotalAttachmentsSize += Segment.GetSize(); + } + } + + return std::move(ResponseBuffers); +} + +CbPackage +ParsePackageMessage(IoBuffer Payload, std::function<IoBuffer(const IoHash&, uint64_t)> CreateBuffer) +{ + if (!Payload) + { + return {}; + } + + MemoryInStream InStream(Payload); + BinaryReader Reader(InStream); + + CbPackage Package; + + CbPackageHeader Hdr; + Reader.Read(&Hdr, sizeof Hdr); + + if (Hdr.HeaderMagic != kCbPkgMagic) + { + // report error + return {}; + } + + uint32_t ChunkCount = Hdr.AttachmentCount + 1; + + std::unique_ptr<CbAttachmentEntry[]> AttachmentEntries{new CbAttachmentEntry[ChunkCount]}; + + Reader.Read(AttachmentEntries.get(), sizeof(CbAttachmentEntry) * ChunkCount); + + for (uint32_t i = 0; i < ChunkCount; ++i) + { + const CbAttachmentEntry& Entry = AttachmentEntries[i]; + const uint64_t AttachmentSize = Entry.AttachmentSize; + IoBuffer AttachmentBuffer = CreateBuffer(Entry.AttachmentHash, AttachmentSize); + + ZEN_ASSERT(AttachmentBuffer); + ZEN_ASSERT(AttachmentBuffer.Size() == AttachmentSize); + + Reader.Read(AttachmentBuffer.MutableData(), AttachmentSize); + + CompressedBuffer CompBuf(CompressedBuffer::FromCompressed(SharedBuffer(AttachmentBuffer))); + + if (i == 0) + { + Package.SetObject(LoadCompactBinaryObject(std::move(CompBuf))); + } + else + { + CbAttachment Attachment(std::move(CompBuf)); + Package.AddAttachment(Attachment); + } + } + + return Package; +} + +} // namespace zen
\ No newline at end of file |