1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/json
7  
// Official repository: https://github.com/boostorg/json
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_JSON_SERIALIZER_HPP
10  
#ifndef BOOST_JSON_SERIALIZER_HPP
11  
#define BOOST_JSON_SERIALIZER_HPP
11  
#define BOOST_JSON_SERIALIZER_HPP
12  

12  

13  
#include <boost/json/detail/config.hpp>
13  
#include <boost/json/detail/config.hpp>
14  
#include <boost/json/detail/format.hpp>
14  
#include <boost/json/detail/format.hpp>
15  
#include <boost/json/detail/stream.hpp>
15  
#include <boost/json/detail/stream.hpp>
16  
#include <boost/json/detail/writer.hpp>
16  
#include <boost/json/detail/writer.hpp>
17  
#include <boost/json/serialize_options.hpp>
17  
#include <boost/json/serialize_options.hpp>
18  
#include <boost/json/value.hpp>
18  
#include <boost/json/value.hpp>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace json {
21  
namespace json {
22  

22  

23  
/** A serializer for JSON.
23  
/** A serializer for JSON.
24  

24  

25  
    This class traverses an instance of a library type and emits serialized
25  
    This class traverses an instance of a library type and emits serialized
26  
    JSON text by filling in one or more caller-provided buffers. To use,
26  
    JSON text by filling in one or more caller-provided buffers. To use,
27  
    declare a variable and call @ref reset with a pointer to the variable you
27  
    declare a variable and call @ref reset with a pointer to the variable you
28  
    want to serialize. Then call @ref read over and over until @ref done
28  
    want to serialize. Then call @ref read over and over until @ref done
29  
    returns `true`.
29  
    returns `true`.
30  

30  

31  
    @par Example
31  
    @par Example
32  
    This demonstrates how the serializer may be used to print a JSON value to
32  
    This demonstrates how the serializer may be used to print a JSON value to
33  
    an output stream.
33  
    an output stream.
34  

34  

35  
    @code
35  
    @code
36  
    void print( std::ostream& os, value const& jv)
36  
    void print( std::ostream& os, value const& jv)
37  
    {
37  
    {
38  
        serializer sr;
38  
        serializer sr;
39  
        sr.reset( &jv );
39  
        sr.reset( &jv );
40  
        while( ! sr.done() )
40  
        while( ! sr.done() )
41  
        {
41  
        {
42  
            char buf[ 4000 ];
42  
            char buf[ 4000 ];
43  
            os << sr.read( buf );
43  
            os << sr.read( buf );
44  
        }
44  
        }
45  
    }
45  
    }
46  
    @endcode
46  
    @endcode
47  

47  

48  
    @par Thread Safety
48  
    @par Thread Safety
49  
    The same instance may not be accessed concurrently.
49  
    The same instance may not be accessed concurrently.
50  

50  

51  
    @par Non-Standard JSON
51  
    @par Non-Standard JSON
52  
    The @ref serialize_options structure optionally provided upon construction
52  
    The @ref serialize_options structure optionally provided upon construction
53  
    is used to enable non-standard JSON extensions. A default-constructed
53  
    is used to enable non-standard JSON extensions. A default-constructed
54  
    `serialize_options` doesn't enable any extensions.
54  
    `serialize_options` doesn't enable any extensions.
55  

55  

56  
    @see @ref serialize.
56  
    @see @ref serialize.
57  
*/
57  
*/
58  
class serializer
58  
class serializer
59  
    : detail::writer
59  
    : detail::writer
60  
{
60  
{
61  
    using fn_t = bool (*)(writer&, detail::stream&);
61  
    using fn_t = bool (*)(writer&, detail::stream&);
62  

62  

63  
    fn_t fn0_ = nullptr;
63  
    fn_t fn0_ = nullptr;
64  
    fn_t fn1_ = nullptr;
64  
    fn_t fn1_ = nullptr;
65  
    bool done_ = false;
65  
    bool done_ = false;
66  

66  

67  
public:
67  
public:
68  
    /** Destructor
68  
    /** Destructor
69  

69  

70  
        All temporary storage is deallocated.
70  
        All temporary storage is deallocated.
71  

71  

72  
        @par Complexity
72  
        @par Complexity
73  
        Constant
73  
        Constant
74  

74  

75  
        @par Exception Safety
75  
        @par Exception Safety
76  
        No-throw guarantee.
76  
        No-throw guarantee.
77  
    */
77  
    */
78  
#ifdef BOOST_JSON_DOCS
78  
#ifdef BOOST_JSON_DOCS
79  
    BOOST_JSON_DECL
79  
    BOOST_JSON_DECL
80  
    ~serializer() noexcept;
80  
    ~serializer() noexcept;
81  
#endif // BOOST_JSON_DOCS
81  
#endif // BOOST_JSON_DOCS
82  

82  

83  
    /** Constructors.
83  
    /** Constructors.
84  

84  

85  
        The serializer is constructed with no value to serialize The value may
85  
        The serializer is constructed with no value to serialize The value may
86  
        be set later by calling @ref reset. If serialization is attempted with
86  
        be set later by calling @ref reset. If serialization is attempted with
87  
        no value, the output is as if a null value is serialized.
87  
        no value, the output is as if a null value is serialized.
88  

88  

89  
        Overload **(3)** is a move constructor. The type is neither copyable
89  
        Overload **(3)** is a move constructor. The type is neither copyable
90  
        nor movable, so this constructor is deleted.
90  
        nor movable, so this constructor is deleted.
91  

91  

92  
        @par Complexity
92  
        @par Complexity
93  
        Constant.
93  
        Constant.
94  

94  

95  
        @par Exception Safety
95  
        @par Exception Safety
96  
        No-throw guarantee.
96  
        No-throw guarantee.
97  

97  

98  
        @param opts The options for the serializer. If this parameter is
98  
        @param opts The options for the serializer. If this parameter is
99  
        omitted, the serializer will output only standard JSON.
99  
        omitted, the serializer will output only standard JSON.
100  

100  

101  
        @{
101  
        @{
102  
    */
102  
    */
103  
    BOOST_JSON_DECL
103  
    BOOST_JSON_DECL
104  
    serializer( serialize_options const& opts = {} ) noexcept;
104  
    serializer( serialize_options const& opts = {} ) noexcept;
105  

105  

106  
    /** Overload
106  
    /** Overload
107  

107  

108  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
108  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
109  
        to use when producing partial output. Shared ownership of the memory
109  
        to use when producing partial output. Shared ownership of the memory
110  
        resource is retained until the serializer is destroyed.
110  
        resource is retained until the serializer is destroyed.
111  

111  

112  
        @param buf An optional static buffer to use for temporary storage when
112  
        @param buf An optional static buffer to use for temporary storage when
113  
        producing partial output.
113  
        producing partial output.
114  

114  

115  
        @param size The number of bytes of valid memory pointed to by
115  
        @param size The number of bytes of valid memory pointed to by
116  
        `buf`.
116  
        `buf`.
117  

117  

118  
        @param opts
118  
        @param opts
119  
    */
119  
    */
120  
    BOOST_JSON_DECL
120  
    BOOST_JSON_DECL
121  
    serializer(
121  
    serializer(
122  
        storage_ptr sp,
122  
        storage_ptr sp,
123  
        unsigned char* buf = nullptr,
123  
        unsigned char* buf = nullptr,
124  
        std::size_t size = 0,
124  
        std::size_t size = 0,
125  
        serialize_options const& opts = {}) noexcept;
125  
        serialize_options const& opts = {}) noexcept;
126  

126  

127  
    /// Overload
127  
    /// Overload
128  
    serializer(serializer&&) = delete;
128  
    serializer(serializer&&) = delete;
129  
    /// @}
129  
    /// @}
130  

130  

131  
    /** Check if the serialization is complete.
131  
    /** Check if the serialization is complete.
132  

132  

133  
        This function returns `true` when all of the characters in the
133  
        This function returns `true` when all of the characters in the
134  
        serialized representation of the value have been read.
134  
        serialized representation of the value have been read.
135  

135  

136  
        @par Complexity
136  
        @par Complexity
137  
        Constant.
137  
        Constant.
138  

138  

139  
        @par Exception Safety
139  
        @par Exception Safety
140  
        No-throw guarantee.
140  
        No-throw guarantee.
141  
    */
141  
    */
142  
    bool
142  
    bool
143  
    done() const noexcept
143  
    done() const noexcept
144  
    {
144  
    {
145  
        return done_;
145  
        return done_;
146  
    }
146  
    }
147  

147  

148  
    /** Reset the serializer for a new element.
148  
    /** Reset the serializer for a new element.
149  

149  

150  
        This function prepares the serializer to emit a new serialized JSON
150  
        This function prepares the serializer to emit a new serialized JSON
151  
        representing its argument: `*p` **(1)**--**(5)**, `sv` **(6)**, or
151  
        representing its argument: `*p` **(1)**--**(5)**, `sv` **(6)**, or
152  
        `np` **(7)**. Ownership is not transferred. The caller is responsible
152  
        `np` **(7)**. Ownership is not transferred. The caller is responsible
153  
        for ensuring that the lifetime of the object pointed to by the argument
153  
        for ensuring that the lifetime of the object pointed to by the argument
154  
        extends until it is no longer needed.
154  
        extends until it is no longer needed.
155  

155  

156  
        Any memory internally allocated for previous uses of this `serializer`
156  
        Any memory internally allocated for previous uses of this `serializer`
157  
        object is preserved and re-used for the new output.
157  
        object is preserved and re-used for the new output.
158  

158  

159  
        Overload **(5)** uses \<\<direct_conversion,direct serialization\>\>.
159  
        Overload **(5)** uses \<\<direct_conversion,direct serialization\>\>.
160  

160  

161  
        @param p A pointer to the element to serialize.
161  
        @param p A pointer to the element to serialize.
162  

162  

163  
        @{
163  
        @{
164  
    */
164  
    */
165  
    BOOST_JSON_DECL
165  
    BOOST_JSON_DECL
166  
    void
166  
    void
167  
    reset(value const* p) noexcept;
167  
    reset(value const* p) noexcept;
168  

168  

169  
    BOOST_JSON_DECL
169  
    BOOST_JSON_DECL
170  
    void
170  
    void
171  
    reset(array const* p) noexcept;
171  
    reset(array const* p) noexcept;
172  

172  

173  
    BOOST_JSON_DECL
173  
    BOOST_JSON_DECL
174  
    void
174  
    void
175  
    reset(object const* p) noexcept;
175  
    reset(object const* p) noexcept;
176  

176  

177  
    BOOST_JSON_DECL
177  
    BOOST_JSON_DECL
178  
    void
178  
    void
179  
    reset(string const* p) noexcept;
179  
    reset(string const* p) noexcept;
180  

180  

181  
    template<class T>
181  
    template<class T>
182  
    void
182  
    void
183  
    reset(T const* p) noexcept;
183  
    reset(T const* p) noexcept;
184  

184  

185  
    /** Overload
185  
    /** Overload
186  

186  

187  
        @param sv The characters representing a string.
187  
        @param sv The characters representing a string.
188  
    */
188  
    */
189  
    BOOST_JSON_DECL
189  
    BOOST_JSON_DECL
190  
    void
190  
    void
191  
    reset(string_view sv) noexcept;
191  
    reset(string_view sv) noexcept;
192  

192  

193  
    /** Overload
193  
    /** Overload
194  

194  

195  
        @param np Represents a null value.
195  
        @param np Represents a null value.
196  
    */
196  
    */
197  
    BOOST_JSON_DECL
197  
    BOOST_JSON_DECL
198  
    void
198  
    void
199  
    reset(std::nullptr_t np) noexcept;
199  
    reset(std::nullptr_t np) noexcept;
200  
    /// @}
200  
    /// @}
201  

201  

202  
    /** Read the next buffer of serialized JSON.
202  
    /** Read the next buffer of serialized JSON.
203  

203  

204  
        This function attempts to fill the caller provided buffer starting at
204  
        This function attempts to fill the caller provided buffer starting at
205  
        `dest` with up to `size` characters of the serialized JSON that
205  
        `dest` with up to `size` characters of the serialized JSON that
206  
        represents the value. If the buffer is not large enough, multiple calls
206  
        represents the value. If the buffer is not large enough, multiple calls
207  
        may be required.
207  
        may be required.
208  

208  

209  
        If serialization completes during this call; that is, that all of the
209  
        If serialization completes during this call; that is, that all of the
210  
        characters belonging to the serialized value have been written to
210  
        characters belonging to the serialized value have been written to
211  
        caller-provided buffers, the function @ref done will return `true`.
211  
        caller-provided buffers, the function @ref done will return `true`.
212  

212  

213  
        @pre
213  
        @pre
214  
        @code
214  
        @code
215  
        done() == false
215  
        done() == false
216  
        @endcode
216  
        @endcode
217  

217  

218  
        @par Complexity
218  
        @par Complexity
219  
        @li **(1)** linear in `size`.
219  
        @li **(1)** linear in `size`.
220  
        @li **(2)** linear in `N`.
220  
        @li **(2)** linear in `N`.
221  

221  

222  
        @par Exception Safety
222  
        @par Exception Safety
223  
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
223  
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
224  

224  

225  
        @return A @ref string_view containing the characters written, which may
225  
        @return A @ref string_view containing the characters written, which may
226  
        be less than `size` or `N`.
226  
        be less than `size` or `N`.
227  

227  

228  
        @param dest A pointer to storage to write into.
228  
        @param dest A pointer to storage to write into.
229  

229  

230  
        @param size The maximum number of characters to write to the memory
230  
        @param size The maximum number of characters to write to the memory
231  
        pointed to by `dest`.
231  
        pointed to by `dest`.
232  

232  

233  
        @{
233  
        @{
234  
    */
234  
    */
235  
    BOOST_JSON_DECL
235  
    BOOST_JSON_DECL
236  
    string_view
236  
    string_view
237  
    read(char* dest, std::size_t size);
237  
    read(char* dest, std::size_t size);
238  

238  

239  
    /** Overload
239  
    /** Overload
240  

240  

241  
        @tparam N The size of the array `dest`.
241  
        @tparam N The size of the array `dest`.
242  
        @param dest
242  
        @param dest
243  
    */
243  
    */
244  
    template<std::size_t N>
244  
    template<std::size_t N>
245  
    string_view
245  
    string_view
246  
    read(char(&dest)[N])
246  
    read(char(&dest)[N])
247  
    {
247  
    {
248  
        return read(dest, N);
248  
        return read(dest, N);
249  
    }
249  
    }
250  
    /// @}
250  
    /// @}
251  

251  

252  
#ifndef BOOST_JSON_DOCS
252  
#ifndef BOOST_JSON_DOCS
253  
    // Safety net for accidental buffer overflows
253  
    // Safety net for accidental buffer overflows
254  
    template<std::size_t N>
254  
    template<std::size_t N>
255  
    string_view
255  
    string_view
256  
    read(char(&dest)[N], std::size_t n)
256  
    read(char(&dest)[N], std::size_t n)
257  
    {
257  
    {
258  
        // If this goes off, check your parameters
258  
        // If this goes off, check your parameters
259  
        // closely, chances are you passed an array
259  
        // closely, chances are you passed an array
260  
        // thinking it was a pointer.
260  
        // thinking it was a pointer.
261  
        BOOST_ASSERT(n <= N);
261  
        BOOST_ASSERT(n <= N);
262  
        return read(dest, n);
262  
        return read(dest, n);
263  
    }
263  
    }
264  
#endif
264  
#endif
265  
};
265  
};
266  

266  

267  
} // namespace json
267  
} // namespace json
268  
} // namespace boost
268  
} // namespace boost
269  

269  

270  
#include <boost/json/impl/serializer.hpp>
270  
#include <boost/json/impl/serializer.hpp>
271  

271  

272  
#endif
272  
#endif