Tileson 1.4.0
A helpful json parser for Tiled maps
Loading...
Searching...
No Matches
Gason.hpp
Go to the documentation of this file.
1//
2// Created by robin on 14.01.2021.
3//
4
5#ifndef TILESON_GASON_HPP
6#define TILESON_GASON_HPP
7
8namespace tson
9{
10 class Gason : public tson::IJson
11 {
12 public:
13 inline Gason() = default;
14
15 IJson &operator[](std::string_view key) override
16 {
17 if(m_arrayCache.count(key.data()) == 0)
18 {
19 if(m_json.getTag() == gason::JSON_OBJECT)
20 {
21 m_arrayCache[key.data()] = std::make_unique<Gason>(m_objectCache[key.data()]);
22 }
23 }
24
25 return *m_arrayCache[key.data()].get();
26 }
27
28 inline explicit Gason(gason::JsonValue json) : m_json {json}
29 {
30 createObjCache();
31 }
32
33 inline IJson& at(std::string_view key) override
34 {
35 if(m_arrayCache.count(key.data()) == 0)
36 {
37 if(m_json.getTag() == gason::JSON_OBJECT)
38 {
39 m_arrayCache[key.data()] = std::make_unique<Gason>(m_objectCache[key.data()]);
40 }
41 }
42 return *m_arrayCache[key.data()].get();
43 }
44
45 inline IJson& at(size_t pos) override
46 {
47 if(m_arrayPosCache.count(pos) == 0)
48 {
49 size_t i = 0;
50 for (auto item : m_json)
51 {
52 if(i == pos)
53 {
54 m_arrayPosCache[pos] = std::make_unique<Gason>(item->value);
55 break;
56 }
57 }
58 }
59
60 return *m_arrayPosCache[pos];
61 }
62
63 std::vector<std::unique_ptr<IJson>> array() override
64 {
65 std::vector<std::unique_ptr<IJson>> vec;
66 if(m_json.getTag() == gason::JSON_ARRAY)
67 {
68 for (auto item : m_json)
69 {
70 vec.emplace_back(std::make_unique<Gason>(item->value));
71 }
72 }
73
74 return vec;
75 }
76
77 inline std::vector<std::unique_ptr<IJson>> &array(std::string_view key) override
78 {
79 if(m_arrayListDataCache.count(key.data()) == 0)
80 {
81 if(count(key.data()) > 0)
82 {
83 if(isObject())
84 {
85 gason::JsonValue v = m_objectCache[key.data()];
86 if(v.getTag() == gason::JSON_ARRAY)
87 {
88 for (auto item : v)
89 {
90 m_arrayListDataCache[key.data()].emplace_back(std::make_unique<Gason>(item->value));
91 }
92 }
93 }
94 }
95 }
96
97
98 return m_arrayListDataCache[key.data()];
99 }
100
101 [[nodiscard]] inline size_t size() const override
102 {
103
104 return m_objectCache.size();
105 }
106
107 inline bool parse(const fs::path &path) override
108 {
109 clearCache();
110 m_data = nullptr;
111 if (fs::exists(path) && fs::is_regular_file(path))
112 {
113 std::ifstream file(path.generic_string());
114 std::string str;
115 m_path = path.parent_path();
116
117 file.seekg(0, std::ios::end);
118 str.reserve(static_cast<size_t>(file.tellg()));
119 file.seekg(0, std::ios::beg);
120
121 str.assign((std::istreambuf_iterator<char>(file)),
122 std::istreambuf_iterator<char>());
123
124 m_data = std::make_unique<gason::JsonValue>();
125 m_allocator = std::make_unique<gason::JsonAllocator>();
126
127 try
128 {
129 int status = gason::jsonParse(str.data(), &m_endptr, m_data.get(), *m_allocator);
130 if (status != gason::JSON_OK) {
131 fprintf(stderr, "%s at %zd\n", gason::jsonStrError(status), m_endptr - str.data());
132 return false;
133 }
134 m_json = *m_data;
135 createObjCache();
136 }
137 catch (const std::exception &error)
138 {
139 std::string message = "Parse error: ";
140 message += std::string(error.what());
141 message += std::string("\n");
142 std::cerr << message;
143 return false;
144 }
145 return true;
146 }
147 return false;
148 }
149
150 inline bool parse(const void *data, size_t size) override
151 {
152 clearCache();
153 std::string str;
154
155 str.reserve(size);
156
157 tson::MemoryStream mem{(uint8_t *) data, size};
158 //mem >> str;
159 str.assign((std::istreambuf_iterator<char>(mem)),
160 std::istreambuf_iterator<char>());
161
162 m_data = std::make_unique<gason::JsonValue>();
163 m_allocator = std::make_unique<gason::JsonAllocator>();
164
165 try
166 {
167 int status = gason::jsonParse(str.data(), &m_endptr, m_data.get(), *m_allocator);
168 if (status != gason::JSON_OK) {
169 fprintf(stderr, "%s at %zd\n", gason::jsonStrError(status), m_endptr - str.data());
170 return false;
171 }
172 m_json = *m_data;
173 createObjCache();
174 }
175 catch (const std::exception &error)
176 {
177 std::string message = "Parse error: ";
178 message += std::string(error.what());
179 message += std::string("\n");
180 std::cerr << message;
181 return false;
182 }
183 return true;
184 }
185
186 [[nodiscard]] inline size_t count(std::string_view key) const override
187 {
188 if (isObject())
189 {
190 return m_objectCache.count(key.data());
191 }
192
193 return 0;
194 }
195
196 [[nodiscard]] inline bool any(std::string_view key) const override
197 {
198 return count(key) > 0;
199 }
200
201 [[nodiscard]] inline bool isArray() const override
202 {
203 return m_json.getTag() == gason::JSON_ARRAY;
204 }
205
206 [[nodiscard]] inline bool isObject() const override
207 {
208 return m_json.getTag() == gason::JSON_OBJECT;
209 }
210
211 [[nodiscard]] inline bool isNull() const override
212 {
213 return m_json.getTag() == gason::JSON_NULL;
214 }
215
216 fs::path directory() const override
217 {
218 return m_path;
219 }
220
221 void directory(const fs::path &directory) override
222 {
223 m_path = directory;
224 }
225
226 std::unique_ptr<IJson> create() override
227 {
228 return std::make_unique<Gason>();
229 }
230
231 protected:
232 [[nodiscard]] inline int32_t getInt32(std::string_view key) override
233 {
234 return static_cast<int32_t>(getDouble(key));
235 }
236
237 [[nodiscard]] inline uint32_t getUInt32(std::string_view key) override
238 {
239 return static_cast<uint32_t>(getDouble(key));
240 }
241
242 [[nodiscard]] inline int64_t getInt64(std::string_view key) override
243 {
244 return static_cast<int64_t>(getDouble(key));
245 }
246
247 [[nodiscard]] inline uint64_t getUInt64(std::string_view key) override
248 {
249 return static_cast<uint64_t>(getDouble(key));
250 }
251
252 [[nodiscard]] inline double getDouble(std::string_view key) override
253 {
254 return obj(key.data())->toNumber();
255 }
256
257 [[nodiscard]] inline std::string getString(std::string_view key) override
258 {
259 return obj(key.data())->toString(); // .get<std::string>();
260 }
261
262 [[nodiscard]] inline bool getBool(std::string_view key) override
263 {
264 return obj(key.data())->getTag() == gason::JSON_TRUE;
265 }
266
267 [[nodiscard]] float getFloat(std::string_view key) override
268 {
269 return static_cast<float>(getDouble(key));
270 }
271
272 [[nodiscard]] inline int32_t getInt32() override
273 {
274 return static_cast<int32_t>(getDouble());
275 }
276
277 [[nodiscard]] inline uint32_t getUInt32() override
278 {
279 return static_cast<uint32_t>(getDouble());
280 }
281
282 [[nodiscard]] inline int64_t getInt64() override
283 {
284 return static_cast<int64_t>(getDouble());
285 }
286
287 [[nodiscard]] inline uint64_t getUInt64() override
288 {
289 return static_cast<uint64_t>(getDouble());
290 }
291
292 [[nodiscard]] inline double getDouble() override
293 {
294 return m_json.toNumber();
295 }
296
297 [[nodiscard]] inline std::string getString() override
298 {
299 return m_json.toString();
300 }
301
302 [[nodiscard]] inline bool getBool() override
303 {
304 return m_json.getTag() == gason::JSON_TRUE;
305 }
306
307 [[nodiscard]] float getFloat() override
308 {
309 return static_cast<float>(getDouble());
310 }
311
312 private:
317 const gason::JsonValue *obj(std::string_view key)
318 {
319 //createObjCache();
320 return &m_objectCache[key.data()];
321 }
322
323 void createObjCache()
324 {
325 if(m_objectCache.empty())
326 {
327 if(m_json.getTag() == gason::JSON_OBJECT)
328 {
329 for (auto i : m_json)
330 {
331 m_objectCache[i->key] = i->value;
332 }
333 }
334 }
335 }
336
337 inline void clearCache()
338 {
339 m_objectCache.clear();
340 m_arrayCache.clear();
341 m_arrayPosCache.clear();
342 m_arrayListDataCache.clear();
343 }
344
345 //Owner values
346 char *m_endptr;
347 std::unique_ptr<gason::JsonValue> m_data = nullptr; //Only used if this is the owner json!
348 std::unique_ptr<gason::JsonAllocator> m_allocator = nullptr;
349
350 gason::JsonValue m_json;
351 fs::path m_path;
352
353 //Cache!
354 std::map<std::string, gason::JsonValue> m_objectCache;
355
356 std::map<std::string, std::unique_ptr<IJson>> m_arrayCache;
357 std::map<size_t, std::unique_ptr<IJson>> m_arrayPosCache;
358 std::map<std::string, std::vector<std::unique_ptr<IJson>>> m_arrayListDataCache;
359
360 };
361}
362
363#endif //TILESON_GASON_HPP
Definition Gason.hpp:11
IJson & at(size_t pos) override
Definition Gason.hpp:45
std::string getString() override
Definition Gason.hpp:297
bool isArray() const override
Definition Gason.hpp:201
uint64_t getUInt64(std::string_view key) override
Definition Gason.hpp:247
std::unique_ptr< IJson > create() override
Definition Gason.hpp:226
int64_t getInt64(std::string_view key) override
Definition Gason.hpp:242
std::vector< std::unique_ptr< IJson > > & array(std::string_view key) override
Definition Gason.hpp:77
int64_t getInt64() override
Definition Gason.hpp:282
std::vector< std::unique_ptr< IJson > > array() override
Definition Gason.hpp:63
float getFloat(std::string_view key) override
Definition Gason.hpp:267
uint32_t getUInt32(std::string_view key) override
Definition Gason.hpp:237
bool parse(const void *data, size_t size) override
Definition Gason.hpp:150
bool isObject() const override
Definition Gason.hpp:206
double getDouble() override
Definition Gason.hpp:292
double getDouble(std::string_view key) override
Definition Gason.hpp:252
Gason(gason::JsonValue json)
Definition Gason.hpp:28
bool getBool(std::string_view key) override
Definition Gason.hpp:262
int32_t getInt32() override
Definition Gason.hpp:272
bool any(std::string_view key) const override
Definition Gason.hpp:196
void directory(const fs::path &directory) override
Definition Gason.hpp:221
fs::path directory() const override
Definition Gason.hpp:216
float getFloat() override
Definition Gason.hpp:307
bool getBool() override
Definition Gason.hpp:302
bool parse(const fs::path &path) override
Definition Gason.hpp:107
int32_t getInt32(std::string_view key) override
Definition Gason.hpp:232
IJson & at(std::string_view key) override
Definition Gason.hpp:33
size_t size() const override
Definition Gason.hpp:101
uint32_t getUInt32() override
Definition Gason.hpp:277
uint64_t getUInt64() override
Definition Gason.hpp:287
std::string getString(std::string_view key) override
Definition Gason.hpp:257
Gason()=default
size_t count(std::string_view key) const override
Definition Gason.hpp:186
bool isNull() const override
Definition Gason.hpp:211
IJson & operator[](std::string_view key) override
Definition Gason.hpp:15
Definition IJson.hpp:11
Definition MemoryStream.hpp:12
Definition Base64.hpp:12