1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 17 окт. 2019 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef CORE_FILES_JSON_SERIALIZER_H_
23 #define CORE_FILES_JSON_SERIALIZER_H_
24 
25 #include <common/types.h>
26 #include <core/io/IOutStream.h>
27 #include <core/io/IOutSequence.h>
28 #include <core/io/Path.h>
29 #include <core/files/json/token.h>
30 #include <data/cstorage.h>
31 
32 namespace lsp
33 {
34     namespace json
35     {
36 
37         class Serializer
38         {
39             private:
40                 Serializer & operator = (const Serializer &);
41 
42             protected:
43                 enum pmode_t
44                 {
45                     WRITE_ROOT,
46                     WRITE_ARRAY,
47                     WRITE_OBJECT
48                 };
49 
50                 enum serialize_flags_t
51                 {
52                     SF_PROPERTY     = 1 << 0,
53                     SF_VALUE        = 1 << 1,
54                     SF_COMMA        = 1 << 2,
55                     SF_CONTENT      = 1 << 3
56                 };
57 
58                 typedef struct state_t
59                 {
60                     pmode_t         mode;
61                     size_t          flags;
62                     size_t          ident;
63                 } state_t;
64 
65             protected:
66                 io::IOutSequence   *pOut;
67                 size_t              nWFlags;
68                 state_t             sState;
69                 cstorage<state_t>   sStack;
70                 serial_flags_t      sSettings;
71 
72             protected:
73                 inline status_t     push_state(pmode_t state);
74                 status_t            pop_state();
75                 inline void         copy_settings(const serial_flags_t *flags);
76 
77                 inline char         hex(int x);
78                 status_t            write_raw(const char *buf, int len);
79                 status_t            write_literal(const LSPString *value);
80                 inline status_t     emit_comma();
81                 inline status_t     emit_separator();
82 
83             public:
84                 explicit Serializer();
85                 virtual ~Serializer();
86 
87             public:
88                 /**
89                  * Open parser
90                  * @param path UTF-8 path to the file
91                  * @param settings serialization flags
92                  * @param charset character set
93                  * @return status of operation
94                  */
95                 status_t    open(const char *path, const serial_flags_t *settings, const char *charset = NULL);
96 
97                 /**
98                  * Open parser
99                  * @param path string representation of path to the file
100                  * @param settings serialization flags
101                  * @param charset character set
102                  * @return status of operation
103                  */
104                 status_t    open(const LSPString *path, const serial_flags_t *settings, const char *charset = NULL);
105 
106                 /**
107                  * Open parser
108                  * @param path path to the file
109                  * @param settings serialization flags
110                  * @param charset character set
111                  * @return status of operation
112                  */
113                 status_t    open(const io::Path *path, const serial_flags_t *settings, const char *charset = NULL);
114 
115                 /**
116                  * Wrap string with parser
117                  * @param str string to wrap
118                  * @param settings serialization flags
119                  * @return status of operation
120                  */
121                 status_t    wrap(LSPString *str, const serial_flags_t *settings);
122 
123                 /**
124                  * Wrap input sequence with parser
125                  * @param seq sequence to use for reads
126                  * @param settings serialization flags
127                  * @param flags wrapping flags
128                  * @return status of operation
129                  */
130                 status_t    wrap(io::IOutSequence *seq, const serial_flags_t *settings, size_t flags = WRAP_NONE);
131 
132                 /**
133                  * Wrap input stream with parser
134                  * @param os output stream
135                  * @param version JSON version
136                  * @param settings serialization flags
137                  * @param flags wrapping flags
138                  * @param charset character set
139                  * @return status of operation
140                  */
141                 status_t    wrap(io::IOutStream *os, const serial_flags_t *settings, size_t flags = WRAP_NONE, const char *charset = NULL);
142 
143                 /**
144                  * Close parser
145                  * @return status of operation
146                  */
147                 status_t    close();
148 
149             public:
150 
151                 /**
152                  * Write JSON event to output
153                  * @param event event to write
154                  * @return status of operation
155                  */
156                 status_t    write(const event_t *event);
157 
158                 /**
159                  * Write comma
160                  * @return status of operation
161                  */
162                 status_t    write_comma();
163 
164                 /**
165                  * Write new line
166                  * @return status of operation
167                  */
168                 status_t    writeln();
169 
170                 /**
171                  * Write integer value
172                  * @param value value to write
173                  * @return status of operation
174                  */
175                 status_t    write_int(ssize_t value);
176 
177                 /**
178                  * Write hexadecimal value
179                  * @param value value to write
180                  * @return status of operation
181                  */
182                 status_t    write_hex(ssize_t value);
183 
184                 /**
185                  * Write double
186                  * @param value double value
187                  * @return status of operation
188                  */
189                 status_t    write_double(double value);
190 
191                 /**
192                  * Write double
193                  * @param value double value
194                  * @param fmt format specifier (same as for sprintf)
195                  * @return status of operation
196                  */
197                 status_t    write_double(double value, const char *fmt);
198 
199                 /**
200                  * Write boolean value
201                  * @param value value to write
202                  * @return status of operation
203                  */
204                 status_t    write_bool(bool value);
205 
206                 /**
207                  * Write string value
208                  * @param value value to write, NULL will be interpreted as NULL value
209                  * @param charset character set
210                  * @return status of operation
211                  */
212                 status_t    write_string(const char *value, const char *charset);
213 
214                 /**
215                  * Write string in UTF-8
216                  * @param value value to write, NULL will be interpreted as NULL value
217                  * @return status of operation
218                  */
219                 status_t    write_string(const char *value);
220 
221                 /**
222                  * Write string value
223                  * @param value value to write, NULL will be interpreted as NULL value
224                  * @return status of operation
225                  */
226                 status_t    write_string(const LSPString *value);
227 
228                 /**
229                  * Write null value
230                  * @return status of operation
231                  */
232                 status_t    write_null();
233 
234                 /**
235                  * Write comment
236                  * @param value comment to write
237                  * @return status of operation
238                  */
239                 status_t    write_comment(const char *value, const char *charset);
240 
241                 /**
242                  * Write comment in UTF-8 encoding
243                  * @param value comment to write
244                  * @return status of operation
245                  */
246                 status_t    write_comment(const char *value);
247 
248                 /**
249                  * Write comment
250                  * @param value comment to write
251                  * @return status of operation
252                  */
253                 status_t    write_comment(const LSPString *value);
254 
255                 /**
256                  * Write property
257                  * @param name property name
258                  * @param charset character set
259                  * @return status of operation
260                  */
261                 status_t    write_property(const char *name, const char *charset);
262 
263                 /**
264                  * Write property in UTF-8 encoding
265                  * @param name property name
266                  * @param charset character set
267                  * @return status of operation
268                  */
269                 status_t    write_property(const char *name);
270 
271                 /**
272                  * Write property
273                  * @param name property name
274                  * @return status of operation
275                  */
276                 status_t    write_property(const LSPString *name);
277 
278                 /**
279                  * Write beginning of the object
280                  * @return status of operation
281                  */
282                 status_t    start_object();
283 
284                 /**
285                  * Write the end of the object
286                  * @return status of operation
287                  */
288                 status_t    end_object();
289 
290                 /**
291                  * Write beginning of the array
292                  * @return status of operation
293                  */
294                 status_t    start_array();
295 
296                 /**
297                  * Write the end of the array
298                  * @return status of operation
299                  */
300                 status_t    end_array();
301 
302             public:
303                 /**
304                  * Get multiline flag
305                  * @return multiline flag
306                  */
get_multiline()307                 inline bool get_multiline() const { return sSettings.multiline; }
308 
309                 /**
310                  * Get multiline flag
311                  * @return multiline flag
312                  */
set_multiline(bool multiline)313                 inline bool set_multiline(bool multiline)
314                 {
315                     bool prev = sSettings.multiline;
316                     sSettings.multiline = multiline;
317                     return prev;
318                 }
319         };
320 
321     } /* namespace json */
322 } /* namespace lsp */
323 
324 #endif /* CORE_FILES_JSON_SERIALIZER_H_ */
325