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 "json/deserialize.hpp"
14 : #include "json/serialize.hpp"
15 : #include <cstdlib>
16 :
17 : namespace spb::json
18 : {
19 :
20 : /**
21 : * @brief serialize message via writer
22 : *
23 : * @param message to be serialized
24 : * @param on_write function for handling the writes
25 : * @return serialized size in bytes
26 : * @throws exceptions only from `on_write`
27 : */
28 2129 : static inline auto serialize(const auto &message, spb::io::writer on_write) -> size_t
29 : {
30 2129 : return detail::serialize(message, on_write);
31 : }
32 :
33 : /**
34 : * @brief return json-string serialized size in bytes
35 : *
36 : * @param message to be serialized
37 : * @return serialized size in bytes
38 : */
39 1267 : [[nodiscard]] static inline auto serialize_size(const auto &message) -> size_t
40 : {
41 1267 : return serialize(message, spb::io::writer(nullptr));
42 : }
43 :
44 : /**
45 : * @brief serialize message into json-string
46 : *
47 : * @param message to be serialized
48 : * @return serialized json
49 : * @throws std::runtime_error on error
50 : * @example `auto serialized = std::vector< std::byte >();`
51 : * `spb::json::serialize( message, serialized );`
52 : */
53 : template <typename Message, spb::resizable_container Container>
54 896 : static inline auto serialize(const Message &message, Container &result) -> size_t
55 : {
56 896 : const auto size = serialize_size(message);
57 862 : result.resize(size);
58 8068 : auto writer = [ptr = result.data()](const void *data, size_t size) mutable
59 : {
60 7206 : memcpy(ptr, data, size);
61 7206 : ptr += size;
62 : };
63 :
64 862 : serialize(message, writer);
65 862 : return size;
66 : }
67 :
68 : /**
69 : * @brief serialize message into json
70 : *
71 : * @param[in] message to be serialized
72 : * @return serialized json
73 : * @throws std::runtime_error on error
74 : * @example `auto serialized_message = spb::json::serialize( message );`
75 : */
76 : template <spb::resizable_container Container = std::string, typename Message>
77 896 : [[nodiscard]] static inline auto serialize(const Message &message) -> Container
78 : {
79 896 : auto result = Container();
80 896 : serialize<Message, Container>(message, result);
81 862 : return result;
82 34 : }
83 :
84 : /**
85 : * @brief deserialize json-string into variable
86 : *
87 : * @param on_read function for handling reads
88 : * @param result deserialized json
89 : * @throws std::runtime_error on error
90 : */
91 1358 : static inline void deserialize(auto &result, spb::io::reader on_read)
92 : {
93 1358 : return detail::deserialize(result, on_read);
94 : }
95 :
96 : /**
97 : * @brief deserialize json-string into variable
98 : *
99 : * @param json string with json
100 : * @param message deserialized json
101 : * @throws std::runtime_error on error
102 : * @example `auto serialized = std::string( ... );`
103 : * `auto message = Message();`
104 : * `spb::json::deserialize( message, serialized );`
105 : */
106 : template <typename Message, spb::size_container Container>
107 1358 : static inline void deserialize(Message &message, const Container &json)
108 : {
109 1358 : auto ptr = json.data();
110 1358 : const auto end = json.data() + json.size();
111 :
112 4059 : auto reader = [ptr, end](void *data, size_t size) mutable -> size_t
113 : {
114 2701 : const size_t bytes_left = end - ptr;
115 :
116 2701 : size = std::min(size, bytes_left);
117 2701 : memcpy(data, ptr, size);
118 2701 : ptr += size;
119 2701 : return size;
120 : };
121 2307 : return deserialize(message, reader);
122 : }
123 :
124 : /**
125 : * @brief deserialize json-string into variable
126 : *
127 : * @param json string with json
128 : * @return deserialized json or throw an exception
129 : * @example `auto serialized = std::string( ... );`
130 : * `auto message = spb::json::deserialize< Message >( serialized );`
131 : */
132 : template <typename Message, spb::size_container Container>
133 968 : [[nodiscard]] static inline auto deserialize(const Container &json) -> Message
134 : {
135 968 : auto message = Message{};
136 968 : deserialize(message, json);
137 559 : return message;
138 355 : }
139 :
140 : /**
141 : * @brief deserialize json-string into variable
142 : *
143 : * @param on_read function for handling reads
144 : * @return deserialized json
145 : * @throws std::runtime_error on error
146 : * @example `auto message = spb::json::deserialize< Message >( reader )`
147 : */
148 : template <typename Message> [[nodiscard]] static inline auto deserialize(spb::io::reader on_read) -> Message
149 : {
150 : auto message = Message{};
151 : return deserialize(message, on_read);
152 : }
153 :
154 : } // namespace spb::json
|