Sane C++ Libraries
C++ Platform Abstraction Libraries
SerializationJson.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Strings/SmallString.h"
5#include "../Strings/StringFormat.h" //StringFormatOutput
6#include "Internal/SerializationTextReadVersioned.h"
7#include "Internal/SerializationTextReadWriteExact.h"
8
9namespace SC
10{
11struct SC_COMPILER_EXPORT SerializationJson;
12} // namespace SC
13
19
22
45{
48 {
50 Options() { floatDigits = 2; }
51 };
52
62 template <typename T>
63 [[nodiscard]] static bool write(T& object, StringFormatOutput& output, Options options = Options())
64 {
65 Writer stream(output, options);
66 if (not stream.onSerializationStart())
67 return false;
68 if (not Serialization::SerializationTextReadWriteExact<Writer, T>::serialize(0, object, stream))
69 return false;
70 return stream.onSerializationEnd();
71 }
72
82 template <typename T>
83 [[nodiscard]] static bool loadExact(T& object, StringView text)
84 {
85 Reader stream(text);
86 return Serialization::SerializationTextReadWriteExact<Reader, T>::serialize(0, object, stream);
87 }
88
95 template <typename T>
96 [[nodiscard]] static bool loadVersioned(T& object, StringView text)
97 {
98 Reader stream(text);
99 return Serialization::SerializationTextReadVersioned<Reader, T>::loadVersioned(0, object, stream);
100 }
101
102 private:
105 struct SC_COMPILER_EXPORT Writer
106 {
107 StringFormatOutput& output;
108
109 Writer(StringFormatOutput& output, Options options) : output(output), options(options) {}
110
111 [[nodiscard]] bool onSerializationStart();
112 [[nodiscard]] bool onSerializationEnd();
113
114 [[nodiscard]] bool setOptions(Options opt);
115
116 [[nodiscard]] bool startObject(uint32_t index);
117 [[nodiscard]] bool endObject();
118
119 [[nodiscard]] bool startArray(uint32_t index);
120 [[nodiscard]] bool endArray();
121
122 template <typename Container>
123 [[nodiscard]] bool startArray(uint32_t index, Container& container, uint32_t& size)
124 {
125 if (not eventuallyAddComma(index))
126 return false;
127 size = static_cast<uint32_t>(container.size());
128 return output.append("["_a8);
129 }
130
131 template <typename Container>
132 [[nodiscard]] bool endArrayItem(Container&, uint32_t&)
133 {
134 return true;
135 }
136
137 [[nodiscard]] bool startObjectField(uint32_t index, StringView text);
138
139 [[nodiscard]] bool serialize(uint32_t index, const String& value);
140 [[nodiscard]] bool serialize(uint32_t index, float value);
141 [[nodiscard]] bool serialize(uint32_t index, double value);
142
143 template <typename T>
144 [[nodiscard]] bool serialize(uint32_t index, T value)
145 {
146 if (not eventuallyAddComma(index))
147 return false;
148 return StringFormatterFor<T>::format(output, StringView(), value);
149 }
150
151 private:
152 bool eventuallyAddComma(uint32_t index);
153
154 SmallString<64> 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, StringView& 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 [[nodiscard]] bool serialize(uint32_t index, String& text);
199
200 private:
201 [[nodiscard]] bool tokenizeArrayStart(uint32_t index);
202 [[nodiscard]] bool tokenizeArrayEnd(uint32_t& size);
203 [[nodiscard]] bool eventuallyExpectComma(uint32_t index);
204
205 StringView iteratorText;
206 StringIteratorASCII iterator;
207 };
208};
#define SC_COMPILER_EXPORT
Macro for symbol visibility in non-MSVC compilers.
Definition: Compiler.h:78
int int32_t
Platform independent (4) bytes signed int.
Definition: PrimitiveTypes.h:46
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition: PrimitiveTypes.h:36
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
Formatting options.
Definition: SerializationJson.h:48
uint8_t floatDigits
How many digits should be used when printing floating points.
Definition: SerializationJson.h:49
SC::SerializationJson reads or writes C++ structures to / from json using Reflection information.
Definition: SerializationJson.h:45
static bool loadVersioned(T &object, StringView text)
Parses a JSON buffer and writes C++ objects supporting reordered or missing fields.
Definition: SerializationJson.h:96
static bool write(T &object, StringFormatOutput &output, Options options=Options())
Writes a C++ object to JSON using Reflection.
Definition: SerializationJson.h:63
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:83
Allows pushing results of StringFormat to a buffer or to the console.
Definition: StringFormat.h:22
Non-owning view over a range of characters with UTF Encoding.
Definition: StringView.h:47