aboutsummaryrefslogtreecommitdiffstats
path: root/ydb/library/binary_json/format.h
blob: e996303e2ec5ddb06c9d50494514485777c120fe (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#pragma once

#include <util/generic/buffer.h>

namespace NKikimr::NBinaryJson {

constexpr ui32 TYPE_SHIFT = 5;
constexpr ui32 MAX_TYPE = (1 << TYPE_SHIFT) - 1;
constexpr ui32 OFFSET_SHIFT = 27;
constexpr ui32 MAX_OFFSET = (1 << OFFSET_SHIFT) - 1;

/**
 * @brief THeader stores BinaryJson version and offset to the String index
 *
 * Structure:
 *  +-----------------+------------------------------+
 *  | Version, 5 bits | String index offset, 27 bits |
 *  +-----------------+------------------------------+
 */
enum class EVersion {
    Draft = 0,
    V1 = 1,
    MaxVersion = MAX_TYPE,
};

constexpr EVersion CURRENT_VERSION = EVersion::V1;

struct THeader {
    THeader() = default;

    THeader(EVersion version, ui32 stringOffset)
        : Version(version)
        , StringOffset(stringOffset)
    {
        Y_VERIFY_DEBUG(StringOffset <= MAX_OFFSET);
    }

    EVersion Version : 5;
    ui32 StringOffset : 27;
};
static_assert(sizeof(THeader) == sizeof(ui32));

/**
 * @brief TEntry stores type of BinaryJson node and optional offset to the TSEntry or container
 *
 * Structure:
 *  +--------------------+----------------+
 *  | Entry type, 5 bits | Value, 27 bits |
 *  +--------------------+----------------+
 */
enum class EEntryType {
    BoolFalse = 0,
    BoolTrue = 1,
    Null = 2,
    String = 3,
    Number = 4,
    Container = 5,
};

struct TEntry {
    TEntry() = default;

    TEntry(EEntryType type, ui32 value = 0)
        : Type(type)
        , Value(value)
    {
        Y_VERIFY_DEBUG(value <= MAX_OFFSET);
    }

    EEntryType Type : 5;
    ui32 Value : 27;
};
static_assert(sizeof(TEntry) == sizeof(ui32));

/**
 * @brief TKeyEntry stores offset to the TSEntry containing object key
 */
using TKeyEntry = ui32;

/**
 * @brief TSEntry stores string type and offset to the string value in String index
 *
 * Structure:
 *  +---------------------+------------------------+
 *  | String type, 5 bits | String offset, 27 bits |
 *  +---------------------+------------------------+
 */
enum class EStringType {
    RawNullTerminated = 0,
};

struct TSEntry {
    TSEntry() = default;

    TSEntry(EStringType type, ui32 value)
        : Type(type)
        , Value(value)
    {
        Y_VERIFY_DEBUG(value <= MAX_OFFSET);
    }

    EStringType Type : 5;
    ui32 Value : 27;
};
static_assert(sizeof(TSEntry) == sizeof(ui32));

/**
 * @brief TMeta stores container type and container size. For arrays container size is simply
 * array size and for objects it is 2 * (number of key-value pairs)
 *
 * Structure:
 *  +------------------------+---------------+
 *  | Container type, 5 bits | Size, 27 bits |
 *  +------------------------+---------------+
 */
enum class EContainerType {
    Array = 0,
    Object = 1,
    TopLevelScalar = 2,
};

struct TMeta {
    TMeta() = default;

    TMeta(EContainerType type, ui32 size)
        : Type(type)
        , Size(size)
    {
        Y_VERIFY_DEBUG(size <= MAX_OFFSET);
    }

    EContainerType Type : 5;
    ui32 Size : 27;
};
static_assert(sizeof(TMeta) == sizeof(ui32));

/**
 * @brief Buffer to store serialized BinaryJson
 */
using TBinaryJson = TBuffer;

}