Corelink CPP Client
Corelink C++ client library
 
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1#pragma once
2
13
14namespace corelink
15{
16 namespace utils
17 {
22 class CORELINK_EXPORT json
23 {
27 rapidjson::Document m_document;
28 public:
34 explicit json(bool root_type_array = false)
35 {
36 if (root_type_array)
37 m_document.SetArray();
38 else
39 m_document.SetObject();
40 }
41
48 explicit json(in<std::string> json_str)
49 {
50 m_document.Parse(json_str.c_str(), json_str.size());
51 }
52
57 json(rvref<json> rhs) noexcept
58 : m_document(std::move(rhs.m_document))
59 {}
60
66 json &operator=(rvref<json> rhs) noexcept
67 {
68 m_document = std::move(rhs.m_document);
69 return *this;
70 }
71
78 {
79 m_document.CopyFrom(rhs.m_document, m_document.GetAllocator());
80 return *this;
81 }
82
88 {
89 (*this) = rhs; // use the copy assignment operator.
90 }
91
95 ~json() = default;
96
102 rapidjson::Document &operator()()
103 {
104 return m_document;
105 }
106
115 {
116 return m_document;
117 }
118
126 inline int32_t get_int(in<std::string> name, int32_t def_val = 0) const
127 {
128 auto member = m_document.FindMember(name.c_str());
129 return member != m_document.MemberEnd()
130 && member->value.IsInt()
131 ? member->value.GetInt() : def_val;
132 }
133
141 inline int64_t get_int64(in<std::string> name, int64_t def_val = 0) const
142 {
143 auto member = m_document.FindMember(name.c_str());
144 return member != m_document.MemberEnd()
145 && member->value.IsInt64()
146 ? member->value.GetInt64() : def_val;
147 }
148
156 inline std::string get_str(in<std::string> name, in<std::string> def_val = "") const
157 {
158 auto member = m_document.FindMember(name.c_str());
159 return member != m_document.MemberEnd()
160 && member->value.IsString()
161 ? member->value.GetString() : def_val;
162 }
163
171 inline double get_double(in<std::string> name, double def_val = 0.0) const
172 {
173 auto member = m_document.FindMember(name.c_str());
174 return member != m_document.MemberEnd()
175 && member->value.IsDouble()
176 ? member->value.GetDouble() : def_val;
177 }
178
186 inline bool get_bool(in<std::string> name, bool def_val = false) const
187 {
188 auto member = m_document.FindMember(name.c_str());
189 return member != m_document.MemberEnd()
190 && member->value.IsBool()
191 ? member->value.GetBool() : def_val;
192 }
193
201 inline uint32_t get_uint(in<std::string> name, uint32_t def_val = false) const
202 {
203 auto member = m_document.FindMember(name.c_str());
204 return member != m_document.MemberEnd()
205 && member->value.IsUint()
206 ? member->value.GetUint() : def_val;
207 }
208
216 inline uint64_t get_uint64(in<std::string> name, uint64_t def_val = false) const
217 {
218 auto member = m_document.FindMember(name.c_str());
219 return member != m_document.MemberEnd()
220 && member->value.IsUint64()
221 ? member->value.GetUint64() : def_val;
222 }
223
230 bool try_parse(const std::string &json_str, std::string &error) noexcept
231 {
232 try
233 {
234 m_document.Parse(json_str.c_str(), json_str.size());
235 return true;
236 }
237 catch (const std::exception &e)
238 {
239 error += e.what();
240 }
241 return false;
242 }
243
251 std::string to_string(bool pretty_print = false) const
252 {
253 rapidjson::StringBuffer sb;
254 if (pretty_print)
255 {
256 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
257 m_document.Accept(writer);
258
259 }
260 else
261 {
262 rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
263 m_document.Accept(writer);
264 }
265 return sb.GetString();
266 }
267
275 template<class T>
276 json &append(const std::vector<std::map<std::string, T>> &arr_items)
277 {
278 if (m_document.IsArray() && !arr_items.empty())
279 {
280 for (auto &arr_item: arr_items)
281 {
282 if (!arr_item.empty())
283 {
284 rapidjson::Value my_value(rapidjson::kObjectType);
285 for (auto &obj_item: arr_item)
286 {
287 my_value.AddMember(
288 rapidjson::Value(obj_item.first.c_str(), m_document.GetAllocator()),
289 rapidjson::Value(obj_item.second),
290 m_document.GetAllocator()
291 );
292 }
293 m_document.PushBack(my_value.Move(), m_document.GetAllocator());
294 }
295 }
296 }
297 return *this;
298 }
299
306 json &append(const std::vector<std::map<std::string, std::string>> &arr_items)
307 {
308 if (m_document.IsArray() && !arr_items.empty())
309 {
310 for (auto &arr_item: arr_items)
311 {
312 if (arr_item.empty())
313 continue;
314
315 rapidjson::Value my_value(rapidjson::kObjectType);
316 for (auto &obj_item: arr_item)
317 {
318 my_value.AddMember(
319 rapidjson::Value(obj_item.first.c_str(), m_document.GetAllocator()),
320 rapidjson::Value(obj_item.second.c_str(), m_document.GetAllocator()),
321 m_document.GetAllocator()
322 );
323 }
324 m_document.PushBack(my_value.Move(), m_document.GetAllocator());
325 }
326 }
327 return *this;
328 }
329
337 template<class T>
338 json &append(const std::vector<std::map<std::string, std::vector<T>>> &arr_items)
339 {
340 if (m_document.IsArray() && !arr_items.empty())
341 {
342 for (auto &arr_item: arr_items)
343 {
344 if (arr_item.empty())
345 continue;
346
347 rapidjson::Value my_object(rapidjson::kObjectType);
348 for (auto &map_item: arr_item)
349 {
350 if (map_item.first.empty())
351 continue;
352
353 rapidjson::Value my_arr_value(rapidjson::kArrayType);
354 for (auto &one_value: map_item.second)
355 {
356 my_arr_value.PushBack(rapidjson::Value(one_value).Move(), m_document.GetAllocator());
357 }
358 my_object.AddMember(
359 rapidjson::Value(map_item.first.c_str(), m_document.GetAllocator()),
360 my_arr_value,
361 m_document.GetAllocator()
362 );
363 }
364 m_document.PushBack(my_object, m_document.GetAllocator());
365 }
366 }
367 return *this;
368 }
369
376 json &append(const std::vector<std::map<std::string, std::vector<std::string>>> &arr_items)
377 {
378 if (m_document.IsArray() && !arr_items.empty())
379 {
380 for (auto &arr_item: arr_items)
381 {
382 if (arr_item.empty())
383 continue;
384
385 rapidjson::Value my_object(rapidjson::kObjectType);
386 for (auto &map_item: arr_item)
387 {
388 if (map_item.first.empty())
389 continue;
390
391 rapidjson::Value my_arr_value(rapidjson::kArrayType);
392 for (auto &one_value: map_item.second)
393 {
394 my_arr_value.PushBack(
395 rapidjson::Value(one_value.c_str(), m_document.GetAllocator()).Move(),
396 m_document.GetAllocator());
397 }
398 my_object.AddMember(
399 rapidjson::Value(map_item.first.c_str(), m_document.GetAllocator()),
400 my_arr_value,
401 m_document.GetAllocator()
402 );
403 }
404 m_document.PushBack(my_object, m_document.GetAllocator());
405 }
406 }
407 return *this;
408 }
409
419 template<class T>
420 json &append(const std::string &key, const T &val)
421 {
422 if (!key.empty())
423 {
424 if (m_document.IsObject() && !m_document.HasMember(key.c_str()))
425 {
426 m_document.AddMember(
427 rapidjson::Value(key.c_str(), m_document.GetAllocator()),
428 rapidjson::Value(val),
429 m_document.GetAllocator());
430 }
431 else if (m_document.IsArray())
432 {
433 std::map<std::string, T> mp = {
434 std::make_pair(key, val)
435 };
436 std::vector<std::map<std::string, T>> vec = {mp};
437 append(vec);
438 }
439 }
440 return *this;
441 }
442
451 json &append(const std::string &key, const std::string &val)
452 {
453 if (!key.empty())
454 {
455 if (m_document.IsObject() && !m_document.HasMember(key.c_str()))
456 {
457 m_document.AddMember(
458 rapidjson::Value(key.c_str(), m_document.GetAllocator()),
459 rapidjson::Value(val.c_str(), m_document.GetAllocator()),
460 m_document.GetAllocator()
461 );
462 }
463 else if (m_document.IsArray())
464 {
465 std::map<std::string, std::string> mp = {
466 std::make_pair(key, val)
467 };
468 append({mp});
469 }
470 }
471 return *this;
472 }
473
483 template<class T>
484 json &append(const std::string &key, const std::vector<T> &val)
485 {
486 if (!key.empty())
487 {
488 if (m_document.IsObject() && !m_document.HasMember(key.c_str()))
489 {
490 rapidjson::Value value(rapidjson::kArrayType);
491 if (!val.empty())
492 {
493 for (auto &arr_item: val)
494 value.PushBack(rapidjson::Value(arr_item).Move(), m_document.GetAllocator());
495 }
496 m_document.AddMember(
497 rapidjson::Value(key.c_str(), m_document.GetAllocator()),
498 value,
499 m_document.GetAllocator());
500 }
501 else if (m_document.IsArray())
502 {
503 std::map<std::string, std::vector<T>> mp = {
504 std::make_pair(key, val)
505 };
506 std::vector<decltype(mp)> vec = {mp};
507 append(vec);
508 }
509 }
510 return *this;
511 }
512
521 json &append(const std::string &key, const std::vector<std::string> &val)
522 {
523 if (!key.empty())
524 {
525 if (m_document.IsObject() && !m_document.HasMember(key.c_str()))
526 {
527 rapidjson::Value value(rapidjson::kArrayType);
528 if (!val.empty())
529 {
530 for (auto &arr_item: val)
531 value.PushBack(
532 rapidjson::Value(arr_item.c_str(), m_document.GetAllocator()),
533 m_document.GetAllocator()
534 );
535 }
536 m_document.AddMember(
537 rapidjson::Value(key.c_str(), m_document.GetAllocator()),
538 value,
539 m_document.GetAllocator());
540 }
541 else if (m_document.IsArray())
542 {
543 std::map<std::string, std::vector<std::string>> mp = {
544 std::make_pair(key, val)
545 };
546 std::vector<decltype(mp)> vec = {mp};
547 append(vec);
548 }
549 }
550 return *this;
551 }
552
561 template<class T>
562 json &append(const std::map<std::string, T> &kv_items)
563 {
564 if (!kv_items.empty())
565 {
566 if (m_document.IsObject())
567 {
568 for (auto &item: kv_items)
569 {
570 m_document.AddMember(rapidjson::Value(item.first.c_str(), m_document.GetAllocator()),
571 rapidjson::Value(item.second),
572 m_document.GetAllocator());
573 }
574 }
575 else if (m_document.IsArray())
576 {
577 append(
578 {kv_items}
579 );
580 }
581 }
582 return *this;
583 }
584
592 json &append(const std::map<std::string, std::string> &kv_items)
593 {
594 if (!kv_items.empty())
595 {
596 if (m_document.IsObject())
597 {
598 for (auto &item: kv_items)
599 {
600 m_document.AddMember(
601 rapidjson::Value(item.first.c_str(), m_document.GetAllocator()),
602 rapidjson::Value(item.second.c_str(), m_document.GetAllocator()),
603 m_document.GetAllocator()
604 );
605 }
606 }
607 else if (m_document.IsArray())
608 {
609 std::vector<std::map<std::string, std::string>> v{kv_items};
610 append(v);
611 }
612 }
613 return *this;
614 }
615
624 template<class T>
625 json &append(const std::map<std::string, std::vector<T>> &kv_items)
626 {
627 if (!kv_items.empty())
628 {
629 if (m_document.IsObject())
630 {
631 for (auto &item: kv_items)
632 {
633 rapidjson::Value value(rapidjson::kArrayType);
634 for (const T &arr_item: item.second)
635 {
636 value.PushBack(rapidjson::Value(arr_item).Move(), m_document.GetAllocator());
637 }
638
639 m_document.AddMember(rapidjson::Value(item.first.c_str(), m_document.GetAllocator()), value,
640 m_document.GetAllocator());
641 }
642 }
643 else if (m_document.IsArray())
644 {
645 append({kv_items});
646 }
647 }
648 return *this;
649 }
650
658 json &append(const std::map<std::string, std::vector<std::string>> &kv_items)
659 {
660 if (!kv_items.empty())
661 {
662 if (m_document.IsObject())
663 {
664 for (auto &item: kv_items)
665 {
666 rapidjson::Value value(rapidjson::kArrayType);
667 if (item.second.empty())
668 continue;
669 for (auto &arr_item: item.second)
670 {
671 value.PushBack(rapidjson::Value(
672 arr_item.c_str(),
673 m_document.GetAllocator()
674 ).Move(),
675 m_document.GetAllocator());
676 }
677
678 m_document.AddMember(rapidjson::Value(item.first.c_str(), m_document.GetAllocator()), value,
679 m_document.GetAllocator());
680 }
681 }
682 else if (m_document.IsArray())
683 {
684 std::vector<std::map<std::string, std::vector<std::string>>> v{kv_items};
685 append(v);
686 }
687 }
688 return *this;
689 }
690
697 CORELINK_CPP_ATTR_MAYBE_UNUSED
698 json &remove(const std::string &key)
699 {
700 if (!key.empty() && m_document.IsObject())
701 {
702 if (m_document.HasMember(key.c_str()))
703 m_document.RemoveMember(key.c_str());
704 }
705 return *this;
706 }
707
712 CORELINK_CPP_ATTR_MAYBE_UNUSED json &clear()
713 {
714 if (!m_document.Empty())
715 m_document.Clear();
716 return *this;
717 }
718 };
719 }
720}