1 /*
2  * Simple string buffer
3  *
4  * Copyright (C) 2017 Christian Franke
5  *
6  * This file is part of FRR.
7  *
8  * FRR is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * FRR is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with FRR; see the file COPYING.  If not, write to the Free
20  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  * 02111-1307, USA.
22  */
23 #ifndef SBUF_H
24 #define SBUF_H
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /*
31  * sbuf provides a simple string buffer. One application where this comes
32  * in handy is the parsing of binary data: If there is an error in the parsing
33  * process due to invalid input data, printing an error message explaining what
34  * went wrong is definitely useful. However, just printing the actual error,
35  * without any information about the previous parsing steps, is usually not very
36  * helpful.
37  * Using sbuf, the parser can log the whole parsing process into a buffer using
38  * a printf like API. When an error ocurrs, all the information about previous
39  * parsing steps is there in the log, without any need for backtracking, and can
40  * be used to give a detailed and useful error description.
41  * When parsing completes successfully without any error, the log can just be
42  * discarded unless debugging is turned on, to not spam the log.
43  *
44  * For the described usecase, the code would look something like this:
45  *
46  * int sbuf_example(..., char **parser_log)
47  * {
48  *         struct sbuf logbuf;
49  *
50  *         sbuf_init(&logbuf, NULL, 0);
51  *         sbuf_push(&logbuf, 0, "Starting parser\n");
52  *
53  *         int rv = do_parse(&logbuf, ...);
54  *
55  *         *parser_log = sbuf_buf(&logbuf);
56  *
57  *         return 1;
58  * }
59  *
60  * In this case, sbuf_example uses a string buffer with undefined size, which
61  * will
62  * be allocated on the heap by sbuf. The caller of sbuf_example is expected to
63  * free
64  * the string returned in parser_log.
65  */
66 
67 struct sbuf {
68 	bool fixed;
69 	char *buf;
70 	size_t size;
71 	size_t pos;
72 	int indent;
73 };
74 
75 void sbuf_init(struct sbuf *dest, char *buf, size_t size);
76 void sbuf_reset(struct sbuf *buf);
77 const char *sbuf_buf(struct sbuf *buf);
78 void sbuf_free(struct sbuf *buf);
79 #include "lib/log.h"
80 void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
81 	PRINTFRR(3, 4);
82 
83 #ifdef __cplusplus
84 }
85 #endif
86 
87 #endif
88