blob: f11f91fae96606ab087fcefeea8eb5aed7256281 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// Copyright Epic Games, Inc. All Rights Reserved.
#include "httpshared.h"
#include <zencore/compactbinarypackage.h>
#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
#include <zencore/stream.h>
#include <span>
#include <vector>
namespace zen {
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)
{
MemoryInStream InStream(Payload);
BinaryReader Reader(InStream);
if (!Payload)
{
return {};
}
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 uint64_t AttachmentSize = AttachmentEntries[i].AttachmentSize;
IoBuffer AttachmentBuffer{AttachmentSize};
Reader.Read(AttachmentBuffer.MutableData(), AttachmentSize);
CompressedBuffer CompBuf(CompressedBuffer::FromCompressed(SharedBuffer(AttachmentBuffer)));
if (i == 0)
{
Package.SetObject(LoadCompactBinaryObject(CompBuf));
}
else
{
CbAttachment Attachment(CompBuf);
Package.AddAttachment(Attachment);
}
}
return Package;
}
} // namespace zen
|