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>
62 [[nodiscard]] static bool write(T& object, StringFormatOutput& output, Options options = Options())
63 {
64 Writer stream(output, options);
65 if (not stream.onSerializationStart())
66 return false;
67 if (not Serialization::SerializationTextReadWriteExact<Writer, T>::serialize(0, object, stream))
68 return false;
69 return stream.onSerializationEnd();
70 }
71
81 template <typename T>
82 [[nodiscard]] static bool loadExact(T& object, StringView text)
83 {
84 Reader stream(text);
85 return Serialization::SerializationTextReadWriteExact<Reader, T>::serialize(0, object, stream);
86 }
87
94 template <typename T>
95 [[nodiscard]] static bool loadVersioned(T& object, StringView text)
96 {
97 Reader stream(text);
98 return Serialization::SerializationTextReadVersioned<Reader, T>::loadVersioned(0, object, stream);
99 }
100
101 private:
104 struct SC_COMPILER_EXPORT Writer
105 {
106 StringFormatOutput& output;
107
108 Writer(StringFormatOutput& output, Options options) : output(output), options(options) {}
109
110 [[nodiscard]] bool onSerializationStart();
111 [[nodiscard]] bool onSerializationEnd();
112
113 [[nodiscard]] bool setOptions(Options opt);
114
115 [[nodiscard]] bool startObject(uint32_t index);
116 [[nodiscard]] bool endObject();
117
118 [[nodiscard]] bool startArray(uint32_t index);
119 [[nodiscard]] bool endArray();
120
121 template <typename Container>
122 [[nodiscard]] bool startArray(uint32_t index, Container& container, uint32_t& size)
123 {
124 if (not eventuallyAddComma(index))
125 return false;
126 size = static_cast<uint32_t>(container.size());
127 return output.append("["_a8);
128 }
129
130 template <typename Container>
131 [[nodiscard]] bool endArrayItem(Container&, uint32_t&)
132 {
133 return true;
134 }
135
136 [[nodiscard]] bool startObjectField(uint32_t index, StringView text);
137
138 template <typename T>
139 [[nodiscard]] bool serialize(uint32_t index, T& text)
140 {
141 return serializeStringView(index, text.view());
142 }
143
144 [[nodiscard]] bool serialize(uint32_t index, float value);
145 [[nodiscard]] bool serialize(uint32_t index, double value);
146 [[nodiscard]] bool serialize(uint32_t index, int value);
147
148 private:
149 [[nodiscard]] bool serializeStringView(uint32_t index, StringView text);
150
151 bool eventuallyAddComma(uint32_t index);
152
153 char floatFormatStorage[5];
154 StringSpan floatFormat;
155 Options options;
156 };
157
160 struct SC_COMPILER_EXPORT Reader
161 {
162 Reader(StringView text) : iteratorText(text), iterator(text.getIterator<StringIteratorASCII>()) {}
163
164 [[nodiscard]] bool onSerializationStart() { return true; }
165 [[nodiscard]] bool onSerializationEnd() { return true; }
166
167 [[nodiscard]] bool startObject(uint32_t index);
168 [[nodiscard]] bool endObject();
169
170 [[nodiscard]] bool startArray(uint32_t index);
171 [[nodiscard]] bool endArray();
172
173 template <typename Container>
174 [[nodiscard]] bool startArray(uint32_t index, Container& container, uint32_t& size)
175 {
176 if (not tokenizeArrayStart(index))
177 return false;
178 return endArrayItem(container, size);
179 }
180
181 template <typename Container>
182 [[nodiscard]] bool endArrayItem(Container& container, uint32_t& size)
183 {
184 auto oldSize = size;
185 if (not tokenizeArrayEnd(size))
186 return false;
187 if (oldSize != size)
188 return Reflection::ExtendedTypeInfo<Container>::resize(container, size);
189 return true;
190 }
191
192 [[nodiscard]] bool startObjectField(uint32_t index, StringView text);
193 [[nodiscard]] bool getNextField(uint32_t index, StringSpan& text, bool& hasMore);
194
195 [[nodiscard]] bool serialize(uint32_t index, bool& value);
196 [[nodiscard]] bool serialize(uint32_t index, float& value);
197 [[nodiscard]] bool serialize(uint32_t index, int32_t& value);
198
199 template <typename T>
200 [[nodiscard]] bool serialize(uint32_t index, T& text)
201 {
202 bool succeeded;
203 auto result = serializeInternal(index, succeeded);
204 return succeeded and text.assign(result);
205 }
206
207 private:
208 [[nodiscard]] StringView serializeInternal(uint32_t index, bool& succeeded);
209
210 [[nodiscard]] bool tokenizeArrayStart(uint32_t index);
211 [[nodiscard]] bool tokenizeArrayEnd(uint32_t& size);
212 [[nodiscard]] bool eventuallyExpectComma(uint32_t index);
213
214 StringView iteratorText;
215 StringIteratorASCII iterator;
216 };
217};
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:95
static bool write(T &object, StringFormatOutput &output, Options options=Options())
Writes a C++ object to JSON using Reflection.
Definition SerializationJson.h:62
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:82
Definition StringFormat.h:26
Non-owning view over a range of characters with UTF Encoding.
Definition StringView.h:46