aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/on_disk/multi_blob/multiblob.h
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;
};