Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
SerializationJson.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Strings/StringFormat.h" //StringFormatOutput
5#include "Internal/SerializationTextReadVersioned.h"
6#include "Internal/SerializationTextReadWriteExact.h"
7
8namespace SC
9{
10struct SC_COMPILER_EXPORT SerializationJson;
11} // namespace SC
12
18
21
44{
46 struct SC_COMPILER_EXPORT Options
47 {
49 Options() { floatDigits = 2; }
50 };
51
61 template <typename T, typename B>
62 [[nodiscard]] static bool write(T& object, B& buffer, Options options = Options())
63 {
64 GrowableBuffer<B> gb = {buffer};
65 StringFormatOutput output(StringEncoding::Ascii, gb);
66
67 Writer stream(output, options);
68 if (not stream.onSerializationStart())
69 return false;
70 if (not Serialization::SerializationTextReadWriteExact<Writer, T>::serialize(0, object, stream))
71 return false;
72 return stream.onSerializationEnd();
73 }
74
84 template <typename T>
85 [[nodiscard]] static bool loadExact(T& object, StringView text)
86 {
87 Reader stream(text);
88 return Serialization::SerializationTextReadWriteExact<Reader, T>::serialize(0, object, stream);
89 }
90
97 template <typename T>
98 [[nodiscard]] static bool loadVersioned(T& object, StringView text)
99 {
100 Reader stream(text);
101 return Serialization::SerializationTextReadVersioned<Reader, T>::loadVersioned(0, object, stream);
102 }
103
104 private:
107 struct SC_COMPILER_EXPORT Writer
108 {
109 StringFormatOutput& output;
110
111 Writer(StringFormatOutput& output, Options options) : output(output), options(options) {}
112
113 [[nodiscard]] bool onSerializationStart();
114 [[nodiscard]] bool onSerializationEnd();
115
116 [[nodiscard]] bool setOptions(Options opt);
117
118 [[nodiscard]] bool startObject(uint32_t index);
119 [[nodiscard]] bool endObject();
120
121 [[nodiscard]] bool startArray(uint32_t index);
122 [[nodiscard]] bool endArray();
123
124 template <typename Container>
125 [[nodiscard]] bool startArray(uint32_t index, Container& container, uint32_t& size)
126 {
127 if (not eventuallyAddComma(index))
128 return false;
129 size = static_cast<uint32_t>(container.size());
130 return output.append("["_a8);
131 }
132
133 template <typename Container>
134 [[nodiscard]] bool endArrayItem(Container&, uint32_t&)
135 {
136 return true;
137 }
138
139 [[nodiscard]] bool startObjectField(uint32_t index, StringView text);
140
141 template <typename T>
142 [[nodiscard]] bool serialize(uint32_t index, T& text)
143 {
144 return serializeStringView(index, text.view());
145 }
146
147 [[nodiscard]] bool serialize(uint32_t index, float value);
148 [[nodiscard]] bool serialize(uint32_t index, double value);
149 [[nodiscard]] bool serialize(uint32_t index, int value);
150
151 private:
152 [[nodiscard]] bool serializeStringView(uint32_t index, StringView text);
153
154 bool eventuallyAddComma(uint32_t index);
155
156 char floatFormatStorage[5];
157 StringSpan floatFormat;
158 Options options;
159 };
160
163 struct SC_COMPILER_EXPORT Reader
164 {
165 Reader(StringView text) : iteratorText(text), iterator(text.getIterator<StringIteratorASCII>()) {}
166
167 [[nodiscard]] bool onSerializationStart() { return true; }
168 [[nodiscard]] bool onSerializationEnd() { return true; }
169
170 [[nodiscard]] bool startObject(uint32_t index);
171 [[nodiscard]] bool endObject();
172
173 [[nodiscard]] bool startArray(uint32_t index);
174 [[nodiscard]] bool endArray();
175
176 template <typename Container>
177 [[nodiscard]] bool startArray(uint32_t index, Container& container, uint32_t& size)
178 {
179 if (not tokenizeArrayStart(index))
180 return false;
181 return endArrayItem(container, size);
182 }
183
184 template <typename Container>
185 [[nodiscard]] bool endArrayItem(Container& container, uint32_t& size)
186 {
187 auto oldSize = size;
188 if (not tokenizeArrayEnd(size))
189 return false;
190 if (oldSize != size)
191 return Reflection::ExtendedTypeInfo<Container>::resize(container, size);
192 return true;
193 }
194
195 [[nodiscard]] bool startObjectField(uint32_t index, StringView text);
196 [[nodiscard]] bool getNextField(uint32_t index, StringSpan& text, bool& hasMore);
197
198 [[nodiscard]] bool serialize(uint32_t index, bool& value);
199 [[nodiscard]] bool serialize(uint32_t index, float& value);
200 [[nodiscard]] bool serialize(uint32_t index, int32_t& value);
201
202 template <typename T>
203 [[nodiscard]] bool serialize(uint32_t index, T& text)
204 {
205 bool succeeded;
206 auto result = serializeInternal(index, succeeded);
207 return succeeded and text.assign(result);
208 }
209
210 private:
211 [[nodiscard]] StringView serializeInternal(uint32_t index, bool& succeeded);
212
213 [[nodiscard]] bool tokenizeArrayStart(uint32_t index);
214 [[nodiscard]] bool tokenizeArrayEnd(uint32_t& size);
215 [[nodiscard]] bool eventuallyExpectComma(uint32_t index);
216
217 StringView iteratorText;
218 StringIteratorASCII iterator;
219 };
220};
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:36
Formatting options.
Definition SerializationJson.h:47
uint8_t floatDigits
How many digits should be used when printing floating points.
Definition SerializationJson.h:48
SC::SerializationJson reads or writes C++ structures to / from json using Reflection information.
Definition SerializationJson.h:44
static bool loadVersioned(T &object, StringView text)
Parses a JSON buffer and writes C++ objects supporting reordered or missing fields.
Definition SerializationJson.h:98
static bool loadExact(T &object, StringView text)
Parses a JSON produced by SerializationJson::write loading its values into a C++ object Read a JSON b...
Definition SerializationJson.h:85
static bool write(T &object, B &buffer, Options options=Options())
Writes a C++ object to JSON using Reflection.
Definition SerializationJson.h:62
Definition StringFormat.h:26
Non-owning view over a range of characters with UTF Encoding.
Definition StringView.h:46