Tileson  1.3.0
A helpful json parser for Tiled maps
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 
8 namespace 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  int 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.u8string());
114  std::string str;
115  m_path = path.parent_path();
116 
117  file.seekg(0, std::ios::end);
118  str.reserve(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  protected:
227  [[nodiscard]] inline int32_t getInt32(std::string_view key) override
228  {
229  return static_cast<int32_t>(getDouble(key));
230  }
231 
232  [[nodiscard]] inline uint32_t getUInt32(std::string_view key) override
233  {
234  return static_cast<uint32_t>(getDouble(key));
235  }
236 
237  [[nodiscard]] inline int64_t getInt64(std::string_view key) override
238  {
239  return static_cast<int64_t>(getDouble(key));
240  }
241 
242  [[nodiscard]] inline uint64_t getUInt64(std::string_view key) override
243  {
244  return static_cast<uint64_t>(getDouble(key));
245  }
246 
247  [[nodiscard]] inline double getDouble(std::string_view key) override
248  {
249  return obj(key.data())->toNumber();
250  }
251 
252  [[nodiscard]] inline std::string getString(std::string_view key) override
253  {
254  return obj(key.data())->toString(); // .get<std::string>();
255  }
256 
257  [[nodiscard]] inline bool getBool(std::string_view key) override
258  {
259  return obj(key.data())->getTag() == gason::JSON_TRUE;
260  }
261 
262  [[nodiscard]] float getFloat(std::string_view key) override
263  {
264  return static_cast<float>(getDouble(key));
265  }
266 
267  [[nodiscard]] inline int32_t getInt32() override
268  {
269  return static_cast<int32_t>(getDouble());
270  }
271 
272  [[nodiscard]] inline uint32_t getUInt32() override
273  {
274  return static_cast<uint32_t>(getDouble());
275  }
276 
277  [[nodiscard]] inline int64_t getInt64() override
278  {
279  return static_cast<int64_t>(getDouble());
280  }
281 
282  [[nodiscard]] inline uint64_t getUInt64() override
283  {
284  return static_cast<uint64_t>(getDouble());
285  }
286 
287  [[nodiscard]] inline double getDouble() override
288  {
289  return m_json.toNumber();
290  }
291 
292  [[nodiscard]] inline std::string getString() override
293  {
294  return m_json.toString();
295  }
296 
297  [[nodiscard]] inline bool getBool() override
298  {
299  return m_json.getTag() == gason::JSON_TRUE;
300  }
301 
302  [[nodiscard]] float getFloat() override
303  {
304  return static_cast<float>(getDouble());
305  }
306 
307  private:
312  const gason::JsonValue *obj(std::string_view key)
313  {
314  //createObjCache();
315  return &m_objectCache[key.data()];
316  }
317 
318  void createObjCache()
319  {
320  if(m_objectCache.empty())
321  {
322  if(m_json.getTag() == gason::JSON_OBJECT)
323  {
324  for (auto i : m_json)
325  {
326  m_objectCache[i->key] = i->value;
327  }
328  }
329  }
330  }
331 
332  inline void clearCache()
333  {
334  m_objectCache.clear();
335  m_arrayCache.clear();
336  m_arrayPosCache.clear();
337  m_arrayListDataCache.clear();
338  }
339 
340  //Owner values
341  char *m_endptr;
342  std::unique_ptr<gason::JsonValue> m_data = nullptr; //Only used if this is the owner json!
343  std::unique_ptr<gason::JsonAllocator> m_allocator = nullptr;
344 
345  gason::JsonValue m_json;
346  fs::path m_path;
347 
348  //Cache!
349  std::map<std::string, gason::JsonValue> m_objectCache;
350 
351  std::map<std::string, std::unique_ptr<IJson>> m_arrayCache;
352  std::map<size_t, std::unique_ptr<IJson>> m_arrayPosCache;
353  std::map<std::string, std::vector<std::unique_ptr<IJson>>> m_arrayListDataCache;
354 
355  };
356 }
357 
358 #endif //TILESON_GASON_HPP
Definition: Gason.hpp:11
std::string getString() override
Definition: Gason.hpp:292
bool isArray() const override
Definition: Gason.hpp:201
uint64_t getUInt64(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(std::string_view key) override
Definition: Gason.hpp:237
int64_t getInt64() override
Definition: Gason.hpp:277
float getFloat(std::string_view key) override
Definition: Gason.hpp:262
uint32_t getUInt32(std::string_view key) override
Definition: Gason.hpp:232
bool parse(const void *data, size_t size) override
Definition: Gason.hpp:150
bool isObject() const override
Definition: Gason.hpp:206
IJson & at(std::string_view key) override
Definition: Gason.hpp:33
std::vector< std::unique_ptr< IJson > > array() override
Definition: Gason.hpp:63
double getDouble() override
Definition: Gason.hpp:287
IJson & at(size_t pos) override
Definition: Gason.hpp:45
double getDouble(std::string_view key) override
Definition: Gason.hpp:247
Gason(gason::JsonValue json)
Definition: Gason.hpp:28
bool getBool(std::string_view key) override
Definition: Gason.hpp:257
int32_t getInt32() override
Definition: Gason.hpp:267
bool any(std::string_view key) const override
Definition: Gason.hpp:196
void directory(const fs::path &directory) override
Definition: Gason.hpp:221
IJson & operator[](std::string_view key) override
Definition: Gason.hpp:15
fs::path directory() const override
Definition: Gason.hpp:216
float getFloat() override
Definition: Gason.hpp:302
bool getBool() override
Definition: Gason.hpp:297
bool parse(const fs::path &path) override
Definition: Gason.hpp:107
int32_t getInt32(std::string_view key) override
Definition: Gason.hpp:227
size_t size() const override
Definition: Gason.hpp:101
uint32_t getUInt32() override
Definition: Gason.hpp:272
uint64_t getUInt64() override
Definition: Gason.hpp:282
std::string getString(std::string_view key) override
Definition: Gason.hpp:252
Gason()=default
size_t count(std::string_view key) const override
Definition: Gason.hpp:186
bool isNull() const override
Definition: Gason.hpp:211
Definition: IJson.hpp:11
Definition: MemoryStream.hpp:12
Definition: Base64.hpp:12