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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/**
* @file printer_data.h
* @author Radek Krejci <rkrejci@cesnet.cz>
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief Data printers for libyang
*
* Copyright (c) 2015 - 2025 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
*/
#ifndef LY_PRINTER_DATA_H_
#define LY_PRINTER_DATA_H_
#include <stdint.h>
#include <stdio.h>
#include "log.h"
#include "out.h"
#include "tree_data.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ly_out;
/**
* @page howtoDataPrinters Printing Data
*
* Data printers allows to serialize internal representation of a data tree in a specific format. libyang
* supports the following data formats for printing:
*
* - XML
*
* Basic format as specified in rules of mapping YANG modeled data to XML in
* [RFC 6020](http://tools.ietf.org/html/rfc6020).
*
* - JSON
*
* The alternative data format available in RESTCONF protocol. Specification of JSON encoding of data modeled by YANG
* can be found in [RFC 7951](https://tools.ietf.org/html/rfc7951).
*
* - LYB
*
* Proprietary binary format that is focused on performance. This format ignores most printing flags
* except for ::LYD_PRINT_SIBLINGS and ::LYD_PRINT_SHRINK (functionality differs from the text formats).
* In addition to storing the data, this format also stores all the default values and data node flags
* meaning the loaded data can be used directly without any revalidation (unless ::LYD_PRINT_SHRINK is used).
* Unlike text formats, LYB format has specific context restrictions:
* - The context used for parsing must contain and implement all modules, whose YANG data are instantiated in the LYB data.
* - These modules must also be in the same revisions and have the same set of enabled features as in the printer context.
* The ::LYD_PRINT_SHRINK and ::LYD_PARSE_LYB_SKIP_MODULE_CHECK flags further influence the context requirements.
*
* By default, both text formats are printed with indentation (formatting), which can be avoided by ::LYD_PRINT_SHRINK
* [printer option](@ref dataprinterflags)). Other options adjust e.g. [with-defaults mode](@ref howtoDataWD).
*
* Besides the legacy functions from libyang 1.x (::lyd_print_clb(), ::lyd_print_fd(), ::lyd_print_file(), ::lyd_print_mem()
* and ::lyd_print_path()) printing data into the specified output, there are also new functions using
* [output handler](@ref howtoOutput) introduced in libyang 2.0. In contrast to
* [schema printers](@ref howtoSchemaPrinters), there is no limit of the functionality and the functions can be used
* interchangeable. The only think to note is that the new functions ::lyd_print_all() and ::lyd_print_tree() does not
* accept ::LYD_PRINT_SIBLINGS [printer option](@ref dataprinterflags)) since this flag differentiate the functions
* themselves.
*
* Functions List
* --------------
* - ::lyd_print_all()
* - ::lyd_print_tree()
* - ::lyd_print_mem()
* - ::lyd_print_fd()
* - ::lyd_print_file()
* - ::lyd_print_path()
* - ::lyd_print_clb()
*/
/**
* @ingroup datatree
* @defgroup dataprinterflags Data printer flags
*
* Options to change default behavior of the data printers.
*
* @{
*/
#define LYD_PRINT_SIBLINGS 0x01 /**< Flag for printing also the (following) sibling nodes of the data node.
The flag is not allowed for ::lyd_print_all() and ::lyd_print_tree(). */
#define LYD_PRINT_SHRINK LY_PRINT_SHRINK /**< For text formats, output without indentation and formatting new lines.
For LYB format, print only the necessary data (making the output smaller)
but even valid data require validation after parsing.
The contexts used for printing and parsing shrunk LYB data <b>must be identical</b>
(the hash of the context used for printing is stored in the LYB data and checked
against the context used for parsing. See ::ly_ctx_get_modules_hash()
for more information about how the context hash is computed and
what exactly it means for two contexts to be identical).
Use this flag if size matters more than parsing performance. */
#define LYD_PRINT_EMPTY_CONT 0x04 /**< Preserve empty non-presence containers */
#define LYD_PRINT_EMPTY_LEAF_LIST 0x08 /**< Print even empty list and leaf-list instances, not possible for every
data format (supported only for ::LYD_JSON). */
#define LYD_PRINT_WD_MASK 0xF0 /**< Mask for with-defaults modes */
#define LYD_PRINT_WD_EXPLICIT 0x00 /**< Explicit with-defaults mode. Only the data explicitly being present in
the data tree are printed, so the implicitly added default nodes are
not printed. Note that this is the default value when no WD option is
specified. */
#define LYD_PRINT_WD_TRIM 0x10 /**< Trim mode avoids printing the nodes with the value equal to their
default value */
#define LYD_PRINT_WD_ALL 0x20 /**< With this option, all the nodes are printed as none of them are
considered default */
#define LYD_PRINT_WD_ALL_TAG 0x40 /**< Same as ::LYD_PRINT_WD_ALL but also adds attribute 'default' with value 'true' to
all nodes that has its default value. The 'default' attribute has namespace:
urn:ietf:params:xml:ns:netconf:default:1.0 and thus the attributes are
printed only when the ietf-netconf-with-defaults module is present in libyang
context (but in that case this namespace is always printed). */
#define LYD_PRINT_WD_IMPL_TAG 0x80 /**< Same as ::LYD_PRINT_WD_ALL_TAG but the attributes are added only to the nodes that
are not explicitly present in the original data tree despite their
value is equal to their default value. There is the same limitation regarding
the presence of ietf-netconf-with-defaults module in libyang context. */
#define LYD_PRINT_JSON_NO_NESTED_PREFIX 0x0100 /**< Do not print the prefix in JSON data for nested nodes
(non-top-level). By nested we mean any node that does not appear
in the top-level of a corresponding schema. The printed data do
not have the information about the module they belong to. When
parsing such data it is important to include this information
elsewhere (e.g. for lyd_parse_value_fragment() the module name
should be part of the path parameter). */
/**
* @}
*/
/**
* @brief Print the whole data tree of the root, including all the siblings.
*
* @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.
* @param[in] root The root element of the tree to print, can be any sibling.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags) except ::LYD_PRINT_WITHSIBLINGS.
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_all(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
/**
* @brief Print the selected data subtree.
*
* @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.
* @param[in] root The root element of the subtree to print.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags) except ::LYD_PRINT_WITHSIBLINGS.
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_tree(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
/**
* @brief Print data tree in the specified format.
*
* @param[out] strp Pointer to store the resulting dump.
* @param[in] root The root element of the (sub)tree to print.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags).
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_mem(char **strp, const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
/**
* @brief Print data tree in the specified format.
*
* @param[in] fd File descriptor where to print the data.
* @param[in] root The root element of the (sub)tree to print.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags).
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_fd(int fd, const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
/**
* @brief Print data tree in the specified format.
*
* @param[in] f File stream where to print the data.
* @param[in] root The root element of the (sub)tree to print.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags).
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_file(FILE *f, const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
/**
* @brief Print data tree in the specified format.
*
* @param[in] path File path where to print the data.
* @param[in] root The root element of the (sub)tree to print.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags).
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_path(const char *path, const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
/**
* @brief Print data tree in the specified format.
*
* @param[in] writeclb Callback function to write the data (see write(1)).
* @param[in] user_data Optional caller-specific argument to be passed to the \p writeclb callback.
* @param[in] root The root element of the (sub)tree to print.
* @param[in] format Output format.
* @param[in] options [Data printer flags](@ref dataprinterflags).
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyd_print_clb(ly_write_clb writeclb, void *user_data, const struct lyd_node *root,
LYD_FORMAT format, uint32_t options);
/**
* @brief Check whether the node should be printed based on the printing options.
*
* @param[in] node Node to check.
* @param[in] options [Data printer flags](@ref dataprinterflags).
* @return 0 if not,
* @return non-0 if should be printed.
*/
LIBYANG_API_DECL ly_bool lyd_node_should_print(const struct lyd_node *node, uint32_t options);
/**
* @brief Check whether the metadata should be printed.
*
* @param[in] meta Metadata to check.
* @return 0 if not,
* @return non-0 if should be printed.
*/
LIBYANG_API_DECL ly_bool lyd_metadata_should_print(const struct lyd_meta *meta);
#ifdef __cplusplus
}
#endif
#endif /* LY_PRINTER_DATA_H_ */