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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/**
* @file lyb.h
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief Header for LYB format printer & parser
*
* Copyright (c) 2020 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/
;
;
/*
* LYB format
*
* Unlike XML or JSON, it is binary format so most data are represented in similar way but in binary.
* Some notable differences:
*
* - schema nodes are identified based on their hash instead of their string name. In case of collisions
* an array of hashes is created with each next hash one bit shorter until a unique sequence of all these
* hashes is found and then all of them are stored.
*
* - tree structure is represented as individual strictly bounded "siblings". Each "siblings" begins
* with its metadata, which consist of 1) the whole "sibling" length in bytes and 2) number
* of included metadata chunks of nested "siblings".
*
* - since length of a "sibling" is not known before it is printed, holes are first written and
* after the "sibling" is printed, they are filled with actual valid metadata. As a consequence,
* LYB data cannot be directly printed into streams!
*
* - data are preceded with information about all the used modules. It is needed because of
* possible augments and deviations which must be known beforehand, otherwise schema hashes
* could be matched to the wrong nodes.
*
* This is a short summary of the format:
* @verbatim
sb = siblings_start
se = siblings_end
siblings = zero-LYB_SIZE_BYTES | (sb instance+ se)
instance = node_type model hash node
model = 16bit_zero | (model_name_length model_name revision)
node = opaq | leaflist | list | any | inner | leaf
opaq = opaq_data siblings
leaflist = sb leaf+ se
list = sb (node_header siblings)+ se
any = node_header anydata_data
inner = node_header siblings
leaf = node_header term_value
node_header = metadata node_flags
@endverbatim
*/
/**
* @brief LYB data node type
*/
;
/**
* @brief LYB format parser context
*/
;
/**
* @brief Destructor for the lylyb_ctx structure
*/
void ;
/* just a shortcut */
/* struct lyd_lyb_sibling allocation step */
/* current LYB format version */
/* LYB format version mask of the header byte */
/**
* LYB schema hash constants
*
* Hash is divided to collision ID and hash itself.
*
* @anchor collisionid
*
* First bits are collision ID until 1 is found. The rest is truncated 32b hash.
* 1xxx xxxx - collision ID 0 (no collisions)
* 01xx xxxx - collision ID 1 (collision ID 0 hash collided)
* 001x xxxx - collision ID 2 ...
*
* When finding a match for a unique schema (siblings) hash (sequence of hashes with increasing collision ID), the highest
* collision ID can be read from the last hash (LYB parser).
*
* To learn what is the highest collision ID of a hash that must be included in a unique schema (siblings) hash,
* collisions with all the preceding sibling schema hashes must be checked (LYB printer).
*/
/* Number of bits the whole hash will take (including hash collision ID) */
/* Masking 32b hash (collision ID 0) */
/* Type for storing the whole hash (used only internally, publicly defined directly) */
/* Need to move this first >> collision number (from 0) to get collision ID hash part */
/* How many bytes are reserved for one data chunk SIZE (8B is maximum) */
/* Maximum size that will be written into LYB_SIZE_BYTES (must be large enough) */
/* How many bytes are reserved for one data chunk inner chunk count */
/* Maximum size that will be written into LYB_INCHUNK_BYTES (must be large enough) */
/* Just a helper macro */
/* model revision as XXXX XXXX XXXX XXXX (2B) (year is offset from 2000)
* YYYY YYYM MMMD DDDD */
/**
* @brief Get single hash for a schema node to be used for LYB data. Read from cache, if possible.
*
* @param[in] node Node to hash.
* @param[in] collision_id Collision ID of the hash to generate, see @ref collisionid.
* @return Generated hash.
*/
LYB_HASH ;
/**
* @brief Fill the hash cache of all the schema nodes of a module.
*
* @param[in] mod Module to process.
*/
void ;
/**
* @brief Check whether a node's module is in a module array.
*
* @param[in] node Node to check.
* @param[in] models Modules in a sized array.
* @return Boolean value whether @p node's module was found in the given @p models array.
*/
ly_bool ;
/* LY_LYB_H_ */