JSON Voorhees
Killer JSON for C++
encode.hpp
Go to the documentation of this file.
1 /** \file jsonv/encode.hpp
2  * Classes and functions for encoding JSON values to various representations.
3  *
4  * Copyright (c) 2014 by Travis Gockel. All rights reserved.
5  *
6  * This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
7  * as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
8  * version.
9  *
10  * \author Travis Gockel (travis@gockelhut.com)
11 **/
12 #ifndef __JSONV_ENCODE_HPP_INCLUDED__
13 #define __JSONV_ENCODE_HPP_INCLUDED__
14 
15 #include <jsonv/config.hpp>
16 #include <jsonv/forward.hpp>
17 #include <jsonv/string_view.hpp>
18 
19 #include <iosfwd>
20 
21 namespace jsonv
22 {
23 
24 /** An encoder is responsible for writing values to some form of output. **/
26 {
27 public:
28  virtual ~encoder() noexcept;
29 
30  /** Encode some source value into this encoder. This is the only useful entry point to this class. **/
31  void encode(const jsonv::value& source);
32 
33 protected:
34  /** Write the null value.
35  *
36  * \code
37  * null
38  * \endcode
39  **/
40  virtual void write_null() = 0;
41 
42  /** Write the opening of an object value.
43  *
44  * \code
45  * {
46  * \endcode
47  **/
48  virtual void write_object_begin() = 0;
49 
50  /** Write the closing of an object value.
51  *
52  * \code
53  * }
54  * \endcode
55  **/
56  virtual void write_object_end() = 0;
57 
58  /** Write the key for an object, including the separator.
59  *
60  * \code
61  * "key":
62  * \endcode
63  **/
64  virtual void write_object_key(string_view key) = 0;
65 
66  /** Write the delimiter between two entries in an object.
67  *
68  * \code
69  * ,
70  * \endcode
71  **/
72  virtual void write_object_delimiter() = 0;
73 
74  /** Write the opening of an array value.
75  *
76  * \code
77  * [
78  * \endcode
79  **/
80  virtual void write_array_begin() = 0;
81 
82  /** Write the closing of an array value.
83  *
84  * \code
85  * ]
86  * \endcode
87  **/
88  virtual void write_array_end() = 0;
89 
90  /** Write the delimiter between two entries in an array.
91  *
92  * \code
93  * ,
94  * \endcode
95  **/
96  virtual void write_array_delimiter() = 0;
97 
98  /** Write a string value.
99  *
100  * \param value is the string to write. It will \e hopefully be encoded as valid UTF-8. It is the implementation's
101  * choice of how to deal with malformed string values. Two common options are to replace malformed
102  * sequences with ?s or to simply output these encodings and let the receiver deal with them.
103  *
104  * \code
105  * "value"
106  * \endcode
107  **/
108  virtual void write_string(string_view value) = 0;
109 
110  /** Write an integer value.
111  *
112  * \code
113  * 902
114  * \endcode
115  **/
116  virtual void write_integer(std::int64_t value) = 0;
117 
118  /** Write a decimal value.
119  *
120  * \param value is the decimal to write. Keep in mind that standard JSON does not support special IEEE 754 values
121  * such as NaN and infinity. It is the implementation's choice of how to deal with such values. Two
122  * common options are to output \c null or to encode a string description of the special value.
123  *
124  * \code
125  * 4.9
126  * \endcode
127  **/
128  virtual void write_decimal(double value) = 0;
129 
130  /** Write a boolean value.
131  *
132  * \code
133  * true
134  * \endcode
135  **/
136  virtual void write_boolean(bool value) = 0;
137 };
138 
139 /** An encoder that outputs to an \c std::ostream. This implementation is used for \c operator<< on a \c value.
140 **/
142  public encoder
143 {
144 public:
145  /** Create an instance which places text into \a output. **/
146  explicit ostream_encoder(std::ostream& output);
147 
148  virtual ~ostream_encoder() noexcept;
149 
150  /** If set to true (the default), then all non-ASCII characters in strings will be replaced with their numeric
151  * encodings. Since JSON allows for encoded text to be contained in a document, this is inefficient if you have
152  * many non-ASCII characters. If you know that your decoding side can properly handle UTF-8 encoding, then you
153  * should turn this on.
154  *
155  * \note
156  * This functionality cannot be used to passthrough malformed UTF-8 encoded strings. If a given string is invalid
157  * UTF-8, it will still get replaced with a numeric encoding.
158  **/
159  void ensure_ascii(bool value);
160 
161 protected:
162  virtual void write_null() override;
163 
164  virtual void write_object_begin() override;
165 
166  virtual void write_object_end() override;
167 
168  virtual void write_object_key(string_view key) override;
169 
170  virtual void write_object_delimiter() override;
171 
172  virtual void write_array_begin() override;
173 
174  virtual void write_array_end() override;
175 
176  virtual void write_array_delimiter() override;
177 
178  virtual void write_string(string_view value) override;
179 
180  virtual void write_integer(std::int64_t value) override;
181 
182  /** When a special value is given, this will output \c null. **/
183  virtual void write_decimal(double value) override;
184 
185  virtual void write_boolean(bool value) override;
186 
187 protected:
188  std::ostream& output();
189 
190 private:
191  std::ostream& _output;
192  bool _ensure_ascii;
193 };
194 
195 /** Like \c ostream_encoder, but pretty prints output to an \c std::ostream.
196  *
197  * \example "ostream_pretty_encoder to pretty-print JSON to std::cout"
198  * \code
199  * jsonv::ostream_pretty_encoder encoder(std::cout);
200  * encoder.encode(some_value);
201  * encoder.encode(another_value);
202  * \endcode
203 **/
205  public ostream_encoder
206 {
207 public:
208  /** Create an instance which places text into \a output. **/
209  explicit ostream_pretty_encoder(std::ostream& output, std::size_t indent_size = 2);
210 
211  virtual ~ostream_pretty_encoder() noexcept;
212 
213 protected:
214  virtual void write_null() override;
215 
216  virtual void write_object_begin() override;
217 
218  virtual void write_object_end() override;
219 
220  virtual void write_object_key(string_view key) override;
221 
222  virtual void write_object_delimiter() override;
223 
224  virtual void write_array_begin() override;
225 
226  virtual void write_array_end() override;
227 
228  virtual void write_array_delimiter() override;
229 
230  virtual void write_string(string_view value) override;
231 
232  virtual void write_integer(std::int64_t value) override;
233 
234  virtual void write_decimal(double value) override;
235 
236  virtual void write_boolean(bool value) override;
237 
238 private:
239  void write_prefix();
240 
241  void write_eol();
242 
243 private:
244  std::size_t _indent;
245  std::size_t _indent_size;
246  bool _defer_indent;
247 };
248 
249 }
250 
251 #endif/*__JSONV_ENCODE_HPP_INCLUDED__*/
Copyright (c) 2014-2019 by Travis Gockel.
Copyright (c) 2012-2014 by Travis Gockel.
Pulls in an implementation of string_view.
An encoder is responsible for writing values to some form of output.
Definition: encode.hpp:25
An encoder that outputs to an std::ostream.
Definition: encode.hpp:141
#define JSONV_PUBLIC
This function or class is part of the public API for JsonVoorhees.
Definition: config.hpp:104
JSONV_STRING_VIEW_TYPE string_view
A non-owning reference to a string.
Definition: string_view.hpp:52
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
Definition: value.hpp:131