ChatPlexSDK-BS 1.0.1-v6.2.0
C++ ChatPlex BeatSaber SDK
Loading...
Searching...
No Matches
Json.hpp
1#pragma once
2
3#include "Il2cpp.hpp"
4
5#include <fstream>
6#include <map>
7#include <memory>
8#include <stdint.h>
9#include <vector>
10
11#include <beatsaber-hook/shared/config/config-utils.hpp>
12#include <UnityEngine/Color32.hpp>
13#include <UnityEngine/Color.hpp>
14#include <UnityEngine/Quaternion.hpp>
15#include <UnityEngine/Vector2.hpp>
16#include <UnityEngine/Vector3.hpp>
17
18#define CP_SDK_JSON_SERIALIZE_DECL() void Serialize(CP_SDK::Utils::Json::U16Value& p_Document, CP_SDK::Utils::Json::TAllocator& p_Allocator)
19#define CP_SDK_JSON_SERIALIZE_IMPL(__Type) void __Type::Serialize(CP_SDK::Utils::Json::U16Value& p_Document, CP_SDK::Utils::Json::TAllocator& p_Allocator)
20
21#define CP_SDK_JSON_UNSERIALIZE_DECL() void Unserialize(CP_SDK::Utils::Json::U16Value& p_Document)
22#define CP_SDK_JSON_UNSERIALIZE_IMPL(__Type) void __Type::Unserialize(CP_SDK::Utils::Json::U16Value& p_Document)
23
24#define CP_SDK_JSON_OPERATORS_INLINE(__Serialize, __Unserialize) \
25 void Serialize(CP_SDK::Utils::Json::U16Value& p_Document, CP_SDK::Utils::Json::TAllocator& p_Allocator) \
26 { __Serialize } \
27 void Unserialize(CP_SDK::Utils::Json::U16Value& p_Document) \
28 { __Unserialize }
29
30#define CP_SDK_JSON_SERIALIZE_BOOL(__Var) CP_SDK::Utils::Json::SerializeBool (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
31#define CP_SDK_JSON_SERIALIZE_COLOR32(__Var) CP_SDK::Utils::Json::SerializeColor32 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
32#define CP_SDK_JSON_SERIALIZE_COLOR(__Var) CP_SDK::Utils::Json::SerializeColor (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
33#define CP_SDK_JSON_SERIALIZE_FLOAT(__Var) CP_SDK::Utils::Json::SerializeFloat (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
34#define CP_SDK_JSON_SERIALIZE_INT32(__Var) CP_SDK::Utils::Json::SerializeInt32 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
35#define CP_SDK_JSON_SERIALIZE_INT64(__Var) CP_SDK::Utils::Json::SerializeInt64 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
36#define CP_SDK_JSON_SERIALIZE_QUATERNION(__Var) CP_SDK::Utils::Json::SerializeQuaternion (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
37#define CP_SDK_JSON_SERIALIZE_STRING(__Var) CP_SDK::Utils::Json::SerializeString (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
38#define CP_SDK_JSON_SERIALIZE_UINT32(__Var) CP_SDK::Utils::Json::SerializeUInt32 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
39#define CP_SDK_JSON_SERIALIZE_UINT64(__Var) CP_SDK::Utils::Json::SerializeUInt64 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
40#define CP_SDK_JSON_SERIALIZE_VECTOR2(__Var) CP_SDK::Utils::Json::SerializeVector2 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
41#define CP_SDK_JSON_SERIALIZE_VECTOR3(__Var) CP_SDK::Utils::Json::SerializeVector3 (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
42#define CP_SDK_JSON_SERIALIZE_ENUM(__Var, __EnumT) CP_SDK::Utils::Json::SerializeEnum<__EnumT>(p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
43#define CP_SDK_JSON_SERIALIZE_OBJECT(__Var) CP_SDK::Utils::Json::SerializeObject (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
44#define CP_SDK_JSON_SERIALIZE_OBJECT_ARRAY(__Var) CP_SDK::Utils::Json::SerializeObjectArray (p_Document, p_Allocator, __Var, CP_SDK_U16STR(__Var))
45
46#define CP_SDK_JSON_UNSERIALIZE_BOOL(__Var) CP_SDK::Utils::Json::UnserializeBool (p_Document, __Var, CP_SDK_U16STR(__Var))
47#define CP_SDK_JSON_UNSERIALIZE_COLOR32(__Var) CP_SDK::Utils::Json::UnserializeColor32 (p_Document, __Var, CP_SDK_U16STR(__Var))
48#define CP_SDK_JSON_UNSERIALIZE_COLOR(__Var) CP_SDK::Utils::Json::UnserializeColor (p_Document, __Var, CP_SDK_U16STR(__Var))
49#define CP_SDK_JSON_UNSERIALIZE_FLOAT(__Var) CP_SDK::Utils::Json::UnserializeFloat (p_Document, __Var, CP_SDK_U16STR(__Var))
50#define CP_SDK_JSON_UNSERIALIZE_INT32(__Var) CP_SDK::Utils::Json::UnserializeInt32 (p_Document, __Var, CP_SDK_U16STR(__Var))
51#define CP_SDK_JSON_UNSERIALIZE_INT64(__Var) CP_SDK::Utils::Json::UnserializeInt64 (p_Document, __Var, CP_SDK_U16STR(__Var))
52#define CP_SDK_JSON_UNSERIALIZE_QUATERNION(__Var) CP_SDK::Utils::Json::UnserializeQuaternion (p_Document, __Var, CP_SDK_U16STR(__Var))
53#define CP_SDK_JSON_UNSERIALIZE_STRING(__Var) CP_SDK::Utils::Json::UnserializeString (p_Document, __Var, CP_SDK_U16STR(__Var))
54#define CP_SDK_JSON_UNSERIALIZE_UINT32(__Var) CP_SDK::Utils::Json::UnserializeUInt32 (p_Document, __Var, CP_SDK_U16STR(__Var))
55#define CP_SDK_JSON_UNSERIALIZE_UINT64(__Var) CP_SDK::Utils::Json::UnserializeUInt64 (p_Document, __Var, CP_SDK_U16STR(__Var))
56#define CP_SDK_JSON_UNSERIALIZE_VECTOR2(__Var) CP_SDK::Utils::Json::UnserializeVector2 (p_Document, __Var, CP_SDK_U16STR(__Var))
57#define CP_SDK_JSON_UNSERIALIZE_VECTOR3(__Var) CP_SDK::Utils::Json::UnserializeVector3 (p_Document, __Var, CP_SDK_U16STR(__Var))
58#define CP_SDK_JSON_UNSERIALIZE_ENUM(__Var, __EnumT, __Def) CP_SDK::Utils::Json::UnserializeEnum<__EnumT>(p_Document, __Var, CP_SDK_U16STR(__Var), __Def)
59#define CP_SDK_JSON_UNSERIALIZE_OBJECT(__Var) CP_SDK::Utils::Json::UnserializeObject (p_Document, __Var, CP_SDK_U16STR(__Var))
60#define CP_SDK_JSON_UNSERIALIZE_OBJECT_ARRAY(__Var) CP_SDK::Utils::Json::UnserializeObjectArray (p_Document, __Var, CP_SDK_U16STR(__Var))
61
62#define CP_SDK_JSON_ENSURE_TYPE(__Check) if (!p_Document[p_Name]. __Check ()) throw std::runtime_error("_Unserialize<T>: Field " + U16StrToStr(p_Name) + " doesn't exist or is of the wrong type")
63
64namespace CP_SDK::Utils {
65
67 class Json
68 {
69 CP_SDK_NO_DEF_CTORS(Json);
70
71 public:
72 using UTF8 = rapidjson::UTF8<char>;
73 using UTF16 = rapidjson::UTF16<char16_t>;
74 using U16Value = rapidjson::GenericValue<UTF16>;
75 using U16Document = rapidjson::GenericDocument<UTF16>;
76 using U8GenericStringBuffer = rapidjson::GenericStringBuffer<UTF8>;
77 using U16GenericStringBuffer = rapidjson::GenericStringBuffer<UTF16>;
78
79 template <typename t_Writter> using U16Writter = rapidjson::Writer<t_Writter, UTF16, UTF16>;
80 template <typename t_Writter> using U16ToU8Writter = rapidjson::Writer<t_Writter, UTF16, UTF8>;
81 template <typename t_Writter> using U16PrettyWritter = rapidjson::PrettyWriter<t_Writter, UTF16, UTF16>;
82 template <typename t_Writter> using U16ToU8PrettyWritter = rapidjson::PrettyWriter<t_Writter, UTF16, UTF8>;
83
84 using TAllocator = U16Document::AllocatorType;
85
86 public:
92 static bool TryFromU8String(std::string_view p_Str, U16Document& p_Document, std::u16string* p_Error = nullptr);
98 static bool TryFromU8Stream(std::ifstream& p_Stream, U16Document& p_Document, std::u16string* p_Error = nullptr);
104 static bool TryFromU16String(std::u16string_view p_Str, U16Document& p_Document, std::u16string* p_Error = nullptr);
105
106 public:
111 static std::string ToU8String(U16Value& p_Value, bool p_Pretty);
117 static bool TryToU8Stream(U16Value& p_Value, bool p_Pretty, std::ofstream& p_Stream);
122 static std::u16string ToU16String(U16Value& p_Value, bool p_Pretty);
123
124 public:
125 static void SerializeBool (U16Value& p_Document, TAllocator& p_Allocator, bool p_Value, const char16_t* p_Name);
126 static void SerializeColor32 (U16Value& p_Document, TAllocator& p_Allocator, UnityEngine::Color32 p_Value, const char16_t* p_Name);
127 static void SerializeColor (U16Value& p_Document, TAllocator& p_Allocator, UnityEngine::Color p_Value, const char16_t* p_Name);
128 static void SerializeFloat (U16Value& p_Document, TAllocator& p_Allocator, float p_Value, const char16_t* p_Name);
129 static void SerializeInt32 (U16Value& p_Document, TAllocator& p_Allocator, int32_t p_Value, const char16_t* p_Name);
130 static void SerializeInt64 (U16Value& p_Document, TAllocator& p_Allocator, int64_t p_Value, const char16_t* p_Name);
131 static void SerializeQuaternion(U16Value& p_Document, TAllocator& p_Allocator, UnityEngine::Quaternion p_Value, const char16_t* p_Name);
132 static void SerializeString (U16Value& p_Document, TAllocator& p_Allocator, const std::u16string& p_Value, const char16_t* p_Name);
133 static void SerializeUInt32 (U16Value& p_Document, TAllocator& p_Allocator, uint32_t p_Value, const char16_t* p_Name);
134 static void SerializeUInt64 (U16Value& p_Document, TAllocator& p_Allocator, uint64_t p_Value, const char16_t* p_Name);
135 static void SerializeVector2 (U16Value& p_Document, TAllocator& p_Allocator, UnityEngine::Vector2 p_Value, const char16_t* p_Name);
136 static void SerializeVector3 (U16Value& p_Document, TAllocator& p_Allocator, UnityEngine::Vector3 p_Value, const char16_t* p_Name);
137
138 template<typename t_Enum>
139 static void SerializeEnum(U16Value& p_Document, TAllocator& p_Allocator, typename t_Enum::E p_Value, const char16_t* p_Name)
140 {
141 if (p_Document.HasMember(p_Name))
142 throw std::runtime_error("_Serialize<T>: Field " + U16StrToStr(p_Name) + " is already serialized");
143
144 auto l_Str = t_Enum::ToStr(p_Value);
145 p_Document.AddMember(rapidjson::StringRef(p_Name), rapidjson::StringRef(l_Str.data(), l_Str.size()), p_Allocator);
146 }
147 template<typename t_Object>
148 static void SerializeObject(U16Value& p_Document, TAllocator& p_Allocator, std::shared_ptr<t_Object>& p_Object, const char16_t* p_Name)
149 {
150 if (p_Document.HasMember(p_Name))
151 throw std::runtime_error("_Serialize<T>: Field " + U16StrToStr(p_Name) + " is already serialized");
152
153 U16Value l_Object;
154 l_Object.SetObject();
155
156 p_Object->Serialize(l_Object, p_Allocator);
157
158 p_Document.AddMember(rapidjson::StringRef(p_Name), l_Object, p_Allocator);
159 }
160 template<typename t_Object> requires(!std::is_pointer_v<t_Object>)
161 static void SerializeObject(U16Value& p_Document, TAllocator& p_Allocator, std::optional<t_Object>& p_Object, const char16_t* p_Name)
162 {
163 if (!p_Object.has_value())
164 return;
165 if (p_Document.HasMember(p_Name))
166 throw std::runtime_error("_Serialize<T>: Field " + U16StrToStr(p_Name) + " is already serialized");
167
168 U16Value l_Object;
169 l_Object.SetObject();
170
171 p_Object.value().Serialize(l_Object, p_Allocator);
172
173 p_Document.AddMember(rapidjson::StringRef(p_Name), l_Object, p_Allocator);
174 }
175 template<typename t_Object>
176 static void SerializeObjectArray(U16Value& p_Document, TAllocator& p_Allocator, std::vector<std::shared_ptr<t_Object>>& p_Array, const char16_t* p_Name)
177 {
178 if (p_Document.HasMember(p_Name))
179 throw std::runtime_error("_Serialize<T>: Field " + U16StrToStr(p_Name) + " is already serialized");
180
181 U16Value l_Array;
182 l_Array.SetArray();
183
184 for (auto& l_Current : p_Array)
185 {
186 U16Value l_Object;
187 l_Object.SetObject();
188 l_Current->Serialize(l_Object, p_Allocator);
189 l_Array.PushBack(l_Object, p_Allocator);
190 }
191
192 p_Document.AddMember(rapidjson::StringRef(p_Name), l_Array, p_Allocator);
193 }
194
195 public:
196 static void UnserializeBool (U16Value& p_Document, bool& p_Value, const char16_t* p_Name);
197 static void UnserializeColor32 (U16Value& p_Document, UnityEngine::Color32& p_Value, const char16_t* p_Name);
198 static void UnserializeColor (U16Value& p_Document, UnityEngine::Color& p_Value, const char16_t* p_Name);
199 static void UnserializeFloat (U16Value& p_Document, float& p_Value, const char16_t* p_Name);
200 static void UnserializeInt32 (U16Value& p_Document, int32_t& p_Value, const char16_t* p_Name);
201 static void UnserializeInt64 (U16Value& p_Document, int64_t& p_Value, const char16_t* p_Name);
202 static void UnserializeQuaternion(U16Value& p_Document, UnityEngine::Quaternion& p_Value, const char16_t* p_Name);
203 static void UnserializeString (U16Value& p_Document, std::u16string& p_Value, const char16_t* p_Name);
204 static void UnserializeUInt32 (U16Value& p_Document, uint32_t& p_Value, const char16_t* p_Name);
205 static void UnserializeUInt64 (U16Value& p_Document, uint64_t& p_Value, const char16_t* p_Name);
206 static void UnserializeVector2 (U16Value& p_Document, UnityEngine::Vector2& p_Value, const char16_t* p_Name);
207 static void UnserializeVector3 (U16Value& p_Document, UnityEngine::Vector3& p_Value, const char16_t* p_Name);
208
209 template<typename t_Enum>
210 static void UnserializeEnum(U16Value& p_Document, typename t_Enum::E& p_Value, const char16_t* p_Name, typename t_Enum::E p_Default)
211 {
212 if (!p_Document.HasMember(p_Name))
213 {
214 p_Value = p_Default;
215 return;
216 }
217 CP_SDK_JSON_ENSURE_TYPE(IsString);
218
219 auto l_U16String = p_Document[p_Name].GetString();
220 p_Value = t_Enum::ToEnum(l_U16String);
221
222 if (t_Enum::ToStr(p_Value) != l_U16String)
223 p_Value = p_Default;
224 }
225 template<typename t_Object>
226 static void UnserializeObject(U16Value& p_Document, std::shared_ptr<t_Object>& p_Object, const char16_t* p_Name)
227 {
228 if (!p_Document.HasMember(p_Name)) return;
229 if (p_Document[p_Name].IsNull())
230 {
231 p_Object = nullptr;
232 return;
233 }
234 CP_SDK_JSON_ENSURE_TYPE(IsObject);
235
236 auto l_Object = p_Document[p_Name].GetObject();
237
238 p_Object->Unserialize(l_Object);
239 }
240 template<typename t_Object> requires(!std::is_pointer_v<t_Object>)
241 static void UnserializeObject(U16Value& p_Document, std::optional<t_Object>& p_Object, const char16_t* p_Name)
242 {
243 if (!p_Document.HasMember(p_Name)) return;
244 if (p_Document[p_Name].IsNull())
245 {
246 p_Object = std::nullopt;
247 return;
248 }
249 CP_SDK_JSON_ENSURE_TYPE(IsObject);
250
251 auto l_Object = p_Document[p_Name].GetObject();
252
253 if (!p_Object.has_value())
254 p_Object = t_Object {};
255
256 p_Object.value().Unserialize(l_Object);
257 }
258 template<typename t_Object>
259 static void UnserializeObjectArray(U16Value& p_Document, std::vector<std::shared_ptr<t_Object>>& p_Array, const char16_t* p_Name)
260 {
261 if (!p_Document.HasMember(p_Name)) return;
262 CP_SDK_JSON_ENSURE_TYPE(IsArray);
263
264 auto l_Array = p_Document[p_Name].GetArray();
265 p_Array.clear();
266 p_Array.reserve(l_Array.Size());
267
268 for (auto l_I = 0; l_I < l_Array.Size(); ++l_I)
269 {
270 auto l_Object = l_Array[l_I].IsNull() ? nullptr : std::make_shared<t_Object>();
271 if (l_Object) l_Object->Unserialize(l_Array[l_I]);
272
273 p_Array.push_back(l_Object);
274 }
275 }
276 };
277
278}
Json utils.
Definition Json.hpp:68
static std::string ToU8String(U16Value &p_Value, bool p_Pretty)
Encode to utf8 string.
static bool TryFromU16String(std::u16string_view p_Str, U16Document &p_Document, std::u16string *p_Error=nullptr)
Try parse from utf8 string.
static std::u16string ToU16String(U16Value &p_Value, bool p_Pretty)
Encode to utf16 string.
static bool TryFromU8Stream(std::ifstream &p_Stream, U16Document &p_Document, std::u16string *p_Error=nullptr)
Try parse from utf8 string.
static bool TryFromU8String(std::string_view p_Str, U16Document &p_Document, std::u16string *p_Error=nullptr)
Try parse from utf8 string.
static bool TryToU8Stream(U16Value &p_Value, bool p_Pretty, std::ofstream &p_Stream)
Encode to utf8 string.
Various platform utils like Delegate/Action/Function/Event system.
Definition Delegate.hpp:8