blob: 00d34e37107f4d358cdbac763d717efe1fd1c77c [file] [log] [blame]
Radek Krejcia5bba312020-01-09 15:41:20 +01001/**
2 * @file printer.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Generic libyang printer structures and functions
5 *
6 * Copyright (c) 2015-2019 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#ifndef LY_PRINTER_H_
16#define LY_PRINTER_H_
17
18#include <unistd.h>
19
20/**
21 * @brief Printer output structure specifying where the data are printed.
22 */
Radek Krejci241f6b52020-05-21 18:13:49 +020023struct ly_out;
Radek Krejcia5bba312020-01-09 15:41:20 +010024
25/**
26 * @brief Types of the printer's output
27 */
Radek Krejci241f6b52020-05-21 18:13:49 +020028typedef enum LY_OUT_TYPE {
29 LY_OUT_ERROR = -1, /**< error value to indicate failure of the functions returning LY_OUT_TYPE */
30 LY_OUT_FD, /**< file descriptor printer */
31 LY_OUT_FDSTREAM, /**< internal replacement for LY_OUT_FD in case vdprintf() is not available */
32 LY_OUT_FILE, /**< FILE stream printer */
33 LY_OUT_FILEPATH, /**< filepath printer */
34 LY_OUT_MEMORY, /**< memory printer */
35 LY_OUT_CALLBACK /**< callback printer */
36} LY_OUT_TYPE;
Radek Krejcia5bba312020-01-09 15:41:20 +010037
38/**
39 * @brief Get output type of the printer handler.
40 *
41 * @param[in] out Printer handler.
42 * @return Type of the printer's output.
43 */
Radek Krejci241f6b52020-05-21 18:13:49 +020044LY_OUT_TYPE ly_out_type(const struct ly_out *out);
Radek Krejcia5bba312020-01-09 15:41:20 +010045
46/**
47 * @brief Reset the output medium to write from its beginning, so the following printer function will rewrite the current data
48 * instead of appending.
49 *
50 * Note that in case the underlying output is not seekable (stream referring a pipe/FIFO/socket or the callback output type),
51 * nothing actually happens despite the function succeeds. Also note that the medium is not returned to the state it was when
52 * the handler was created. For example, file is seeked into the offset zero, not to the offset where it was opened when
Radek Krejci241f6b52020-05-21 18:13:49 +020053 * ly_out_new_file() was called.
Radek Krejcia5bba312020-01-09 15:41:20 +010054 *
55 * @param[in] out Printer handler.
56 * @return LY_SUCCESS in case of success
57 * @return LY_ESYS in case of failure
58 */
Radek Krejci241f6b52020-05-21 18:13:49 +020059LY_ERR ly_out_reset(struct ly_out *out);
Radek Krejcia5bba312020-01-09 15:41:20 +010060
61/**
62 * @brief Create printer handler using callback printer function.
63 *
64 * @param[in] writeclb Pointer to the printer callback function writing the data (see write(2)).
65 * @param[in] arg Optional caller-specific argument to be passed to the @p writeclb callback.
66 * @return NULL in case of memory allocation error.
67 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
68 */
Radek Krejci241f6b52020-05-21 18:13:49 +020069struct ly_out *ly_out_new_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg);
Radek Krejcia5bba312020-01-09 15:41:20 +010070
71/**
72 * @brief Get or reset callback function associated with a callback printer handler.
73 *
74 * @param[in] out Printer handler.
75 * @param[in] fd Optional value of a new file descriptor for the handler. If -1, only the current file descriptor value is returned.
76 * @return Previous value of the file descriptor.
77 */
Radek Krejci241f6b52020-05-21 18:13:49 +020078ssize_t (*ly_out_clb(struct ly_out *out, ssize_t (*writeclb)(void *arg, const void *buf, size_t count)))(void *arg, const void *buf, size_t count);
Radek Krejcia5bba312020-01-09 15:41:20 +010079
80/**
81 * @brief Get or reset callback function's argument aasociated with a callback printer handler.
82 *
83 * @param[in] out Printer handler.
84 * @param[in] arg caller-specific argument to be passed to the callback function associated with the printer handler.
85 * If NULL, only the current file descriptor value is returned.
86 * @return The previous callback argument.
87 */
Radek Krejci241f6b52020-05-21 18:13:49 +020088void *ly_out_clb_arg(struct ly_out *out, void *arg);
Radek Krejcia5bba312020-01-09 15:41:20 +010089
90/**
91 * @brief Create printer handler using file descriptor.
92 *
93 * @param[in] fd File descriptor to use.
94 * @return NULL in case of error.
95 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
96 */
Radek Krejci241f6b52020-05-21 18:13:49 +020097struct ly_out *ly_out_new_fd(int fd);
Radek Krejcia5bba312020-01-09 15:41:20 +010098
99/**
100 * @brief Get or reset file descriptor printer handler.
101 *
102 * @param[in] out Printer handler.
103 * @param[in] fd Optional value of a new file descriptor for the handler. If -1, only the current file descriptor value is returned.
104 * @return Previous value of the file descriptor. Note that caller is responsible for closing the returned file descriptor in case of setting new descriptor @p fd.
105 * @return -1 in case of error when setting up the new file descriptor.
106 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200107int ly_out_fd(struct ly_out *out, int fd);
Radek Krejcia5bba312020-01-09 15:41:20 +0100108
109/**
110 * @brief Create printer handler using file stream.
111 *
112 * @param[in] f File stream to use.
113 * @return NULL in case of error.
114 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
115 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200116struct ly_out *ly_out_new_file(FILE *f);
Radek Krejcia5bba312020-01-09 15:41:20 +0100117
118/**
119 * @brief Get or reset file stream printer handler.
120 *
121 * @param[in] out Printer handler.
122 * @param[in] f Optional new file stream for the handler. If NULL, only the current file stream is returned.
123 * @return Previous file stream of the handler. Note that caller is responsible for closing the returned stream in case of setting new stream @p f.
124 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200125FILE *ly_out_file(struct ly_out *out, FILE *f);
Radek Krejcia5bba312020-01-09 15:41:20 +0100126
127/**
128 * @brief Create printer handler using memory to dump data.
129 *
130 * @param[in] strp Pointer to store the resulting data. If it points to a pointer to an allocated buffer and
131 * @p size of the buffer is set, the buffer is used (and extended if needed) to store the printed data.
132 * @param[in] size Size of the buffer provided via @p strp. In case it is 0, the buffer for the printed data
133 * is newly allocated even if @p strp points to a pointer to an existing buffer.
134 * @return NULL in case of error.
135 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
136 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200137struct ly_out *ly_out_new_memory(char **strp, size_t size);
Radek Krejcia5bba312020-01-09 15:41:20 +0100138
139/**
140 * @brief Get or change memory where the data are dumped.
141 *
142 * @param[in] out Printer handler.
Radek Krejci241f6b52020-05-21 18:13:49 +0200143 * @param[in] strp A new string pointer to store the resulting data, same rules as in ly_out_new_memory() are applied.
Radek Krejcia5bba312020-01-09 15:41:20 +0100144 * @param[in] size Size of the buffer provided via @p strp. In case it is 0, the buffer for the printed data
145 * is newly allocated even if @p strp points to a pointer to an existing buffer.
146 * @return Previous dumped data. Note that the caller is responsible to free the data in case of changing string pointer @p strp.
147 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200148char *ly_out_memory(struct ly_out *out, char **strp, size_t size);
Radek Krejcia5bba312020-01-09 15:41:20 +0100149
150/**
151 * @brief Create printer handler file of the given filename.
152 *
153 * @param[in] filepath Path of the file where to write data.
154 * @return NULL in case of error.
155 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
156 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200157struct ly_out *ly_out_new_filepath(const char *filepath);
Radek Krejcia5bba312020-01-09 15:41:20 +0100158
159/**
160 * @brief Get or change the filepath of the file where the printer prints the data.
161 *
162 * Note that in case of changing the filepath, the current file is closed and a new one is
163 * created/opened instead of renaming the previous file. Also note that the previous filepath
164 * string is returned only in case of not changing it's value.
165 *
166 * @param[in] out Printer handler.
167 * @param[in] filepath Optional new filepath for the handler. If and only if NULL, the current filepath string is returned.
168 * @return Previous filepath string in case the @p filepath argument is NULL.
169 * @return NULL if changing filepath succeedes and ((void *)-1) otherwise.
170 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200171const char *ly_out_filepath(struct ly_out *out, const char *filepath);
Radek Krejcia5bba312020-01-09 15:41:20 +0100172
173/**
174 * @brief Generic printer of the given format string into the specified output.
175 *
Radek Krejci241f6b52020-05-21 18:13:49 +0200176 * Alternatively, ly_write() can be used.
Radek Krejcia5bba312020-01-09 15:41:20 +0100177 *
178 * @param[in] out Output specification.
179 * @param[in] format format string to be printed.
180 * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
181 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200182LY_ERR ly_print(struct ly_out *out, const char *format, ...);
Radek Krejcia5bba312020-01-09 15:41:20 +0100183
184/**
185 * @brief Generic printer of the given string buffer into the specified output.
186 *
Radek Krejci241f6b52020-05-21 18:13:49 +0200187 * Alternatively, ly_print() can be used.
Radek Krejcia5bba312020-01-09 15:41:20 +0100188 *
189 * As an extension for printing holes (skipping some data until they are known),
190 * ly_write_skip() and ly_write_skipped() can be used.
191 *
192 * @param[in] out Output specification.
193 * @param[in] buf Memory buffer with the data to print.
194 * @param[in] len Length of the data to print in the @p buf.
Radek Krejci241f6b52020-05-21 18:13:49 +0200195 * @return LY_ERR value, number of the printed bytes is updated in ly_out::printed.
Radek Krejcia5bba312020-01-09 15:41:20 +0100196 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200197LY_ERR ly_write(struct ly_out *out, const char *buf, size_t len);
Radek Krejcia5bba312020-01-09 15:41:20 +0100198
199/**
200 * @brief Free the printer handler.
201 * @param[in] out Printer handler to free.
Radek Krejci241f6b52020-05-21 18:13:49 +0200202 * @param[in] clb_arg_destructor Freeing function for printer callback (LY_OUT_CALLBACK) argument.
203 * @param[in] destroy Flag to free allocated buffer (for LY_OUT_MEMORY) or to
204 * close stream/file descriptor (for LY_OUT_FD, LY_OUT_FDSTREAM and LY_OUT_FILE)
Radek Krejcia5bba312020-01-09 15:41:20 +0100205 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200206void ly_out_free(struct ly_out *out, void (*clb_arg_destructor)(void *arg), int destroy);
Radek Krejcia5bba312020-01-09 15:41:20 +0100207
208#endif /* LY_PRINTER_H_ */