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