blob: b40a5ae6af94ba22b91c970236e990f58cc0897d (
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
|
#pragma once
#include <util/generic/vector.h>
#include <util/memory/blob.h>
#define BLOBMETASIG 0x3456789Au
enum E_Multiblob_Flags {
// if EMF_INTERLAY is clear
// multiblob format
// HeaderSize() bytes for TMultiBlobHeader
// Count*sizeof(ui64) bytes for blob sizes
// blob1
// (alignment)
// blob2
// (alignment)
// ...
// (alignment)
// blobn
// if EMF_INTERLAY is set
// multiblob format
// HeaderSize() bytes for TMultiBlobHeader
// size1 ui64, the size of 1st blob
// blob1
// (alignment)
// size2 ui64, the size of 2nd blob
// blob2
// (alignment)
// ...
// (alignment)
// sizen ui64, the size of n'th blob
// blobn
EMF_INTERLAY = 1,
// Means that multiblob contains blocks in TChunkedDataReader format
// Legacy, use it only for old files, created for TChunkedDataReader
EMF_CHUNKED_DATA_READER = 2,
// Flags that may be configured for blobbuilder in client code
EMF_WRITEABLE = EMF_INTERLAY,
};
struct TMultiBlobHeader {
// data
ui32 BlobMetaSig;
ui32 BlobRecordSig;
ui64 Count; // count of sub blobs
ui32 Align; // alignment for every subblob
ui32 Flags;
static const ui32 RecordSig = 0x23456789;
static inline size_t HeaderSize() {
return 4 * sizeof(ui64);
}
inline const ui64* Sizes(const void* Data) const {
return (const ui64*)((const char*)Data + HeaderSize());
}
};
class TSubBlobs: public TVector<TBlob> {
public:
TSubBlobs() {
}
TSubBlobs(const TBlob& multi) {
ReadMultiBlob(multi);
}
void ReadMultiBlob(const TBlob& multi);
const TMultiBlobHeader* GetHeader() const {
return (const TMultiBlobHeader*)&Header;
}
protected:
TMultiBlobHeader Header;
TBlob Multi;
private:
bool ReadChunkedData(const TBlob& multi) noexcept;
};
|