Line data Source code
1 : /***************************************************************************\
2 : * Name : Public API for JSON *
3 : * Description : all json serialize and deserialize functions *
4 : * Author : antonin.kriz@gmail.com *
5 : * ------------------------------------------------------------------------- *
6 : * This is free software; you can redistribute it and/or modify it under the *
7 : * terms of the MIT license. A copy of the license can be found in the file *
8 : * "LICENSE" at the root of this distribution. *
9 : \***************************************************************************/
10 : #pragma once
11 :
12 : #include "spb/io/io.hpp"
13 : #include "spb/json/field.hpp"
14 : #include "json/deserialize.hpp"
15 : #include "json/field.hpp"
16 : #include "json/serialize.hpp"
17 : #include <cstdlib>
18 :
19 : namespace spb::json
20 : {
21 : /**
22 : * @brief serialize message via writer
23 : *
24 : * @param[in] message to be serialized
25 : * @param[in] on_write function for handling the writes
26 : * @param[in] options
27 : * @return serialized size in bytes
28 : * @throws exceptions only from `on_write`
29 : */
30 378 : size_t serialize(const auto &message, spb::io::writer on_write)
31 : {
32 378 : auto stream = detail::ostream_writer{on_write};
33 378 : detail::serialize<detail::field_attributes{}>(stream, message);
34 378 : return stream.size;
35 : }
36 :
37 : /**
38 : * @brief return JSON serialized size in bytes
39 : *
40 : * @param[in] message to be serialized
41 : * @param[in] options
42 : * @return serialized size in bytes
43 : */
44 379 : [[nodiscard]] size_t serialize_size(const auto &message)
45 : {
46 379 : return detail::serialize_size(message);
47 : }
48 :
49 911 : size_t serialize(const auto &message, void *buffer)
50 : {
51 911 : const auto start = (uint8_t *)buffer;
52 911 : auto stream = detail::ostream_buffer((uint8_t *)buffer);
53 911 : detail::serialize<detail::field_attributes{}>(stream, message);
54 878 : return stream.p_buffer - start;
55 : }
56 :
57 : /**
58 : * @brief serialize message into JSON
59 : *
60 : * @param[in] message to be serialized
61 : * @param[in] options
62 : * @param[out] result serialized JSON
63 : * @return serialized size in bytes
64 : * @throws std::runtime_error on error
65 : * @example `std::string json;`
66 : * `spb::json::serialize(message, json);`
67 : */
68 912 : template <spb::resizable_container Container> size_t serialize(const auto &message, Container &result)
69 : {
70 : static_assert(sizeof(*result.data()) == sizeof(uint8_t));
71 :
72 912 : const auto size = detail::serialize_size(message);
73 911 : result.resize(size);
74 911 : return serialize(message, result.data());
75 : }
76 :
77 : /**
78 : * @brief serialize message into JSON
79 : *
80 : * @param[in] message to be serialized
81 : * @param[in] options
82 : * @return serialized JSON
83 : * @throws std::runtime_error on error
84 : * @example `auto serialized_message = spb::json::serialize< std::vector< std::byte > >( message );`
85 : */
86 : template <spb::resizable_container Container = std::string>
87 534 : [[nodiscard]] Container serialize(const auto &message)
88 : {
89 534 : auto result = Container();
90 534 : serialize(message, result);
91 500 : return result;
92 34 : }
93 :
94 1374 : size_t deserialize(auto &message, const void *buffer, size_t size)
95 : {
96 1374 : detail::istream_buffer stream((const uint8_t *)buffer, size);
97 1374 : deserialize<detail::field_attributes{}>(stream, message);
98 1930 : return size - stream.size();
99 : }
100 :
101 : /**
102 : * @brief deserialize message from JSON
103 : *
104 : * @param[in] reader function for handling reads
105 : * @param[in] options
106 : * @param[out] message deserialized message
107 : * @throws std::runtime_error on error
108 : */
109 378 : size_t deserialize(auto &message, spb::io::reader reader)
110 : {
111 378 : detail::istream_reader stream{reader};
112 378 : deserialize<detail::field_attributes{}>(stream, message);
113 756 : return stream.consumed_size();
114 : }
115 :
116 : /**
117 : * @brief deserialize message from JSON
118 : *
119 : * @param[in] JSON string with JSON
120 : * @param[in] options
121 : * @param[out] message deserialized message
122 : * @throws std::runtime_error on error
123 : * @example `auto serialized = std::vector<std::byte>( ... );`
124 : * `auto message = Message();`
125 : * `spb::json::deserialize(message, serialized);`
126 : */
127 398 : size_t deserialize(auto &message, const spb::size_container auto &json)
128 : {
129 398 : return deserialize(message, json.data(), json.size());
130 : }
131 :
132 : /**
133 : * @brief deserialize message from JSON
134 : *
135 : * @param[in] JSON serialized JSON
136 : * @param[in] options
137 : * @return deserialized message
138 : * @throws std::runtime_error on error
139 : * @example `auto serialized = std::vector< std::byte >( ... );`
140 : * `auto message = spb::json::deserialize< Message >( serialized );`
141 : */
142 976 : template <typename Message> [[nodiscard]] Message deserialize(const spb::size_container auto &json)
143 : {
144 976 : auto message = Message{};
145 976 : deserialize(message, json.data(), json.size());
146 567 : return message;
147 355 : }
148 :
149 : /**
150 : * @brief deserialize message from reader
151 : *
152 : * @param[in] reader function for handling reads
153 : * @param[in] options
154 : * @return deserialized message
155 : * @throws std::runtime_error on error
156 : */
157 : template <typename Message> [[nodiscard]] Message deserialize(spb::io::reader reader)
158 : {
159 : auto message = Message{};
160 : deserialize(message, reader);
161 : return message;
162 : }
163 : } // namespace spb::json
|