xrpld
Loading...
Searching...
No Matches
json_value.cpp
1#include <xrpl/json/json_value.h>
2
3#include <xrpl/basics/Number.h>
4#include <xrpl/beast/core/LexicalCast.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/json/detail/json_assert.h>
7#include <xrpl/json/json_forwards.h>
8#include <xrpl/json/json_writer.h>
9
10#include <cmath>
11#include <cstdint>
12#include <cstdlib>
13#include <cstring>
14#include <limits>
15#include <string>
16#include <utility>
17
18namespace json {
19
21
23{
24public:
25 ~DefaultValueAllocator() override = default;
26
27 char*
28 makeMemberName(char const* memberName) override
29 {
30 return duplicateStringValue(memberName);
31 }
32
33 void
34 releaseMemberName(char* memberName) override
35 {
36 releaseStringValue(memberName);
37 }
38
39 char*
40 duplicateStringValue(char const* value, unsigned int length = kUnknown) override
41 {
42 //@todo investigate this old optimization
43 // if ( !value || value[0] == 0 )
44 // return 0;
45
46 if (length == kUnknown)
47 length = (value != nullptr) ? (unsigned int)strlen(value) : 0;
48
49 char* newString = static_cast<char*>(malloc(length + 1));
50 if (value != nullptr)
51 memcpy(newString, value, length);
52 newString[length] = 0;
53 return newString;
54 }
55
56 void
57 releaseStringValue(char* value) override
58 {
59 if (value != nullptr)
60 free(value);
61 }
62};
63
64static ValueAllocator*&
66{
67 static ValueAllocator* kValueAllocator = new DefaultValueAllocator; // NOLINT TODO
68 return kValueAllocator;
69}
70
72{
74 {
75 valueAllocator(); // ensure valueAllocator() statics are initialized
76 // before main().
77 }
79
80// //////////////////////////////////////////////////////////////////
81// //////////////////////////////////////////////////////////////////
82// //////////////////////////////////////////////////////////////////
83// class Value::CZString
84// //////////////////////////////////////////////////////////////////
85// //////////////////////////////////////////////////////////////////
86// //////////////////////////////////////////////////////////////////
87
88// Notes: index_ indicates if the string was allocated when
89// a string is stored.
90
94
96 : cstr_(
97 allocate == DuplicationPolicy::Duplicate ? valueAllocator()->makeMemberName(cstr) : cstr)
98 , index_(static_cast<int>(allocate))
99{
100}
101
103 : cstr_(
104 other.index_ != static_cast<int>(DuplicationPolicy::NoDuplication) && other.cstr_ != 0
105 ? valueAllocator()->makeMemberName(other.cstr_)
106 : other.cstr_)
107 , index_([&]() -> int {
108 if (!other.cstr_)
109 return other.index_;
110 return other.index_ == static_cast<int>(DuplicationPolicy::NoDuplication)
111 ? static_cast<int>(DuplicationPolicy::NoDuplication)
112 : static_cast<int>(DuplicationPolicy::Duplicate);
113 }())
114{
115}
116
118{
119 if ((cstr_ != nullptr) && index_ == static_cast<int>(DuplicationPolicy::Duplicate))
120 valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
121}
122
123bool
124Value::CZString::operator<(CZString const& other) const
125{
126 if ((cstr_ != nullptr) && (other.cstr_ != nullptr))
127 return strcmp(cstr_, other.cstr_) < 0;
128
129 return index_ < other.index_;
130}
131
132bool
134{
135 if ((cstr_ != nullptr) && (other.cstr_ != nullptr))
136 return strcmp(cstr_, other.cstr_) == 0;
137
138 return index_ == other.index_;
139}
140
141int
143{
144 return index_;
145}
146
147char const*
149{
150 return cstr_;
151}
152
153bool
155{
156 return index_ == static_cast<int>(DuplicationPolicy::NoDuplication);
157}
158
159// //////////////////////////////////////////////////////////////////
160// //////////////////////////////////////////////////////////////////
161// //////////////////////////////////////////////////////////////////
162// class Value::Value
163// //////////////////////////////////////////////////////////////////
164// //////////////////////////////////////////////////////////////////
165// //////////////////////////////////////////////////////////////////
166
172{
173 switch (type)
174 {
175 case ValueType::Null:
176 break;
177
178 case ValueType::Int:
179 case ValueType::UInt:
180 value_.intVal = 0;
181 break;
182
183 case ValueType::Real:
184 value_.realVal = 0.0;
185 break;
186
188 value_.stringVal = 0;
189 break;
190
191 case ValueType::Array:
193 value_.mapVal = new ObjectValues();
194 break;
195
197 value_.boolVal = false;
198 break;
199
200 // LCOV_EXCL_START
201 default:
202 UNREACHABLE("json::Value::Value(ValueType) : invalid type");
203 // LCOV_EXCL_STOP
204 }
205}
206
208{
209 value_.intVal = value;
210}
211
213{
214 value_.uintVal = value;
215}
216
218{
219 value_.realVal = value;
220}
221
222Value::Value(char const* value) : type_(ValueType::String), allocated_(true)
223{
224 value_.stringVal = valueAllocator()->duplicateStringValue(value);
225}
226
228{
229 auto const tmp = to_string(value);
230 value_.stringVal = valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
231}
232
234{
235 value_.stringVal =
236 valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
237}
238
240{
241 value_.stringVal = const_cast<char*>(value.cStr());
242}
243
245{
246 value_.boolVal = value;
247}
248
249Value::Value(Value const& other) : type_(other.type_)
250{
251 switch (type_)
252 {
253 case ValueType::Null:
254 case ValueType::Int:
255 case ValueType::UInt:
256 case ValueType::Real:
258 value_ = other.value_;
259 break;
260
262 if (other.value_.stringVal != nullptr)
263 {
265 allocated_ = true;
266 }
267 else
268 {
269 value_.stringVal = 0;
270 }
271
272 break;
273
274 case ValueType::Array:
276 value_.mapVal = new ObjectValues(*other.value_.mapVal);
277 break;
278
279 // LCOV_EXCL_START
280 default:
281 UNREACHABLE("json::Value::Value(Value const&) : invalid type");
282 // LCOV_EXCL_STOP
283 }
284}
285
287{
288 switch (type_)
289 {
290 case ValueType::Null:
291 case ValueType::Int:
292 case ValueType::UInt:
293 case ValueType::Real:
295 break;
296
298 if (allocated_)
300
301 break;
302
303 case ValueType::Array:
305 if (value_.mapVal != nullptr)
306 delete value_.mapVal;
307 break;
308
309 // LCOV_EXCL_START
310 default:
311 UNREACHABLE("json::Value::~Value : invalid type");
312 // LCOV_EXCL_STOP
313 }
314}
315
316Value&
318{
319 Value tmp(other);
320 swap(tmp);
321 return *this;
322}
323
324Value::Value(Value&& other) noexcept
325 : value_(other.value_), type_(other.type_), allocated_(other.allocated_)
326{
327 other.type_ = ValueType::Null;
328 other.allocated_ = 0;
329}
330
331Value&
333{
334 Value tmp(std::move(other));
335 swap(tmp);
336 return *this;
337}
338
339void
340Value::swap(Value& other) noexcept
341{
342 std::swap(value_, other.value_);
343
344 ValueType const temp = type_;
345 type_ = other.type_;
346 other.type_ = temp;
347
348 int const temp2 = allocated_;
349 allocated_ = other.allocated_;
350 other.allocated_ = temp2;
351}
352
355{
356 return type_;
357}
358
359static int
361{
362 // All negative numbers are less than all unsigned numbers.
363 if (i < 0)
364 return -1;
365
366 // Now we can safely compare.
367 if (i < ui)
368 return -1;
369 return (i == ui) ? 0 : 1;
370}
371
372bool
373operator<(Value const& x, Value const& y)
374{
375 if (auto signum = static_cast<int>(x.type_) - static_cast<int>(y.type_))
376 {
377 if (x.type_ == ValueType::Int && y.type_ == ValueType::UInt)
378 {
379 signum = integerCmp(x.value_.intVal, y.value_.uintVal);
380 }
381 else if (x.type_ == ValueType::UInt && y.type_ == ValueType::Int)
382 {
383 signum = -integerCmp(y.value_.intVal, x.value_.uintVal);
384 }
385 return signum < 0;
386 }
387
388 switch (x.type_)
389 {
390 case ValueType::Null:
391 return false;
392
393 case ValueType::Int:
394 return x.value_.intVal < y.value_.intVal;
395
396 case ValueType::UInt:
397 return x.value_.uintVal < y.value_.uintVal;
398
399 case ValueType::Real:
400 return x.value_.realVal < y.value_.realVal;
401
403 return static_cast<int>(x.value_.boolVal) < static_cast<int>(y.value_.boolVal);
404
406 return (x.value_.stringVal == 0 && (y.value_.stringVal != nullptr)) ||
407 ((y.value_.stringVal != nullptr) && (x.value_.stringVal != nullptr) &&
408 strcmp(x.value_.stringVal, y.value_.stringVal) < 0);
409
410 case ValueType::Array:
411 case ValueType::Object: {
412 if (int const signum = int(x.value_.mapVal->size()) - y.value_.mapVal->size())
413 return signum < 0;
414
415 return *x.value_.mapVal < *y.value_.mapVal;
416 }
417
418 // LCOV_EXCL_START
419 default:
420 UNREACHABLE("json::operator<(Value, Value) : invalid type");
421 // LCOV_EXCL_STOP
422 }
423
424 return false; // unreachable
425}
426
427bool
428operator==(Value const& x, Value const& y)
429{
430 if (x.type_ != y.type_)
431 {
432 if (x.type_ == ValueType::Int && y.type_ == ValueType::UInt)
433 return integerCmp(x.value_.intVal, y.value_.uintVal) == 0;
434 if (x.type_ == ValueType::UInt && y.type_ == ValueType::Int)
435 return integerCmp(y.value_.intVal, x.value_.uintVal) == 0;
436 return false;
437 }
438
439 switch (x.type_)
440 {
441 case ValueType::Null:
442 return true;
443
444 case ValueType::Int:
445 return x.value_.intVal == y.value_.intVal;
446
447 case ValueType::UInt:
448 return x.value_.uintVal == y.value_.uintVal;
449
450 case ValueType::Real:
451 return x.value_.realVal == y.value_.realVal;
452
454 return x.value_.boolVal == y.value_.boolVal;
455
457 return x.value_.stringVal == y.value_.stringVal ||
458 ((y.value_.stringVal != nullptr) && (x.value_.stringVal != nullptr) &&
459 (strcmp(x.value_.stringVal, y.value_.stringVal) == 0));
460
461 case ValueType::Array:
463 return x.value_.mapVal->size() == y.value_.mapVal->size() &&
464 *x.value_.mapVal == *y.value_.mapVal;
465
466 // LCOV_EXCL_START
467 default:
468 UNREACHABLE("json::operator==(Value, Value) : invalid type");
469 // LCOV_EXCL_STOP
470 }
471
472 return false; // unreachable
473}
474
475char const*
477{
478 XRPL_ASSERT(type_ == ValueType::String, "json::Value::asCString : valid type");
479 return value_.stringVal;
480}
481
484{
485 switch (type_)
486 {
487 case ValueType::Null:
488 return "";
489
491 return (value_.stringVal != nullptr) ? value_.stringVal : "";
492
494 return value_.boolVal ? "true" : "false";
495
496 case ValueType::Int:
497 return std::to_string(value_.intVal);
498
499 case ValueType::UInt:
500 return std::to_string(value_.uintVal);
501
502 case ValueType::Real:
503 return std::to_string(value_.realVal);
504
505 case ValueType::Array:
507 JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
508
509 // LCOV_EXCL_START
510 default:
511 UNREACHABLE("json::Value::asString : invalid type");
512 // LCOV_EXCL_STOP
513 }
514
515 return ""; // unreachable
516}
517
520{
521 switch (type_)
522 {
523 case ValueType::Null:
524 return 0;
525
526 case ValueType::Int:
527 return value_.intVal;
528
529 case ValueType::UInt:
530 JSON_ASSERT_MESSAGE(
531 value_.uintVal < (unsigned)kMaxInt, "integer out of signed integer range");
532 return value_.uintVal;
533
534 case ValueType::Real:
535 JSON_ASSERT_MESSAGE(
536 (value_.realVal >= kMinInt && value_.realVal <= kMaxInt),
537 "Real out of signed integer range");
538 return Int(value_.realVal);
539
541 return value_.boolVal ? 1 : 0;
542
543 case ValueType::String: {
544 char const* const str{(value_.stringVal != nullptr) ? value_.stringVal : ""};
546 }
547
548 case ValueType::Array:
550 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
551
552 // LCOV_EXCL_START
553 default:
554 UNREACHABLE("json::Value::asInt : invalid type");
555 // LCOV_EXCL_STOP
556 }
557
558 return 0; // unreachable;
559}
560
561UInt
563{
564 switch (type_)
565 {
566 case ValueType::Null:
567 return 0;
568
569 case ValueType::Int: {
570 // Doing this conversion through int64 avoids overflow error for
571 // value_.intVal = -1 * 2^31 i.e. numeric_limits<int>::min().
572 if (value_.intVal < 0)
573 return static_cast<std::int64_t>(value_.intVal) * -1;
574 return value_.intVal;
575 }
576
577 case ValueType::UInt:
578 return value_.uintVal;
579
580 case ValueType::Real: {
581 if (value_.realVal < 0)
582 {
583 JSON_ASSERT_MESSAGE(
584 -1 * value_.realVal <= kMaxUInt, "Real out of unsigned integer range");
585 return UInt(-1 * value_.realVal);
586 }
587 JSON_ASSERT_MESSAGE(value_.realVal <= kMaxUInt, "Real out of unsigned integer range");
588 return UInt(value_.realVal);
589 }
590
592 return value_.boolVal ? 1 : 0;
593
594 case ValueType::String: {
595 char const* const str{(value_.stringVal != nullptr) ? value_.stringVal : ""};
596 auto const temp = beast::lexicalCastThrow<std::int64_t>(str);
597 if (temp < 0)
598 {
599 JSON_ASSERT_MESSAGE(-1 * temp <= kMaxUInt, "String out of unsigned integer range");
600 return -1 * temp;
601 }
602 JSON_ASSERT_MESSAGE(temp <= kMaxUInt, "String out of unsigned integer range");
603 return temp;
604 }
605
606 case ValueType::Array:
608 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
609
610 // LCOV_EXCL_START
611 default:
612 UNREACHABLE("json::Value::asAbsInt : invalid type");
613 // LCOV_EXCL_STOP
614 }
615
616 return 0; // unreachable;
617}
618
621{
622 switch (type_)
623 {
624 case ValueType::Null:
625 return 0;
626
627 case ValueType::Int:
628 JSON_ASSERT_MESSAGE(
629 value_.intVal >= 0, "Negative integer can not be converted to unsigned integer");
630 return value_.intVal;
631
632 case ValueType::UInt:
633 return value_.uintVal;
634
635 case ValueType::Real:
636 JSON_ASSERT_MESSAGE(
637 (value_.realVal >= 0 && value_.realVal <= kMaxUInt),
638 "Real out of unsigned integer range");
639 return UInt(value_.realVal);
640
642 return value_.boolVal ? 1 : 0;
643
644 case ValueType::String: {
645 char const* const str{(value_.stringVal != nullptr) ? value_.stringVal : ""};
647 }
648
649 case ValueType::Array:
651 JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
652
653 // LCOV_EXCL_START
654 default:
655 UNREACHABLE("json::Value::asUInt : invalid type");
656 // LCOV_EXCL_STOP
657 }
658
659 return 0; // unreachable;
660}
661
662double
664{
665 switch (type_)
666 {
667 case ValueType::Null:
668 return 0.0;
669
670 case ValueType::Int:
671 return value_.intVal;
672
673 case ValueType::UInt:
674 return value_.uintVal;
675
676 case ValueType::Real:
677 return value_.realVal;
678
680 return value_.boolVal ? 1.0 : 0.0;
681
683 case ValueType::Array:
685 JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
686
687 // LCOV_EXCL_START
688 default:
689 UNREACHABLE("json::Value::asDouble : invalid type");
690 // LCOV_EXCL_STOP
691 }
692
693 return 0; // unreachable;
694}
695
696bool
698{
699 switch (type_)
700 {
701 case ValueType::Null:
702 return false;
703
704 case ValueType::Int:
705 case ValueType::UInt:
706 return value_.intVal != 0;
707
708 case ValueType::Real:
709 return value_.realVal != 0.0;
710
712 return value_.boolVal;
713
715 return (value_.stringVal != nullptr) && value_.stringVal[0] != 0;
716
717 case ValueType::Array:
719 return !value_.mapVal->empty();
720
721 // LCOV_EXCL_START
722 default:
723 UNREACHABLE("json::Value::asBool : invalid type");
724 // LCOV_EXCL_STOP
725 }
726
727 return false; // unreachable;
728}
729
730bool
732{
733 switch (type_)
734 {
735 case ValueType::Null:
736 return true;
737
738 case ValueType::Int:
739 return (other == ValueType::Null && value_.intVal == 0) || other == ValueType::Int ||
740 (other == ValueType::UInt && value_.intVal >= 0) || other == ValueType::Real ||
741 other == ValueType::String || other == ValueType::Boolean;
742
743 case ValueType::UInt:
744 return (other == ValueType::Null && value_.uintVal == 0) ||
745 (other == ValueType::Int && value_.uintVal <= (unsigned)kMaxInt) ||
746 other == ValueType::UInt || other == ValueType::Real ||
747 other == ValueType::String || other == ValueType::Boolean;
748
749 case ValueType::Real:
750 return (other == ValueType::Null && value_.realVal == 0.0) ||
751 (other == ValueType::Int && value_.realVal >= kMinInt &&
752 value_.realVal <= kMaxInt) ||
753 (other == ValueType::UInt && value_.realVal >= 0 && value_.realVal <= kMaxUInt &&
754 std::fabs(round(value_.realVal) - value_.realVal) <
756 other == ValueType::Real || other == ValueType::String ||
757 other == ValueType::Boolean;
758
760 return (other == ValueType::Null && !value_.boolVal) || other == ValueType::Int ||
761 other == ValueType::UInt || other == ValueType::Real ||
762 other == ValueType::String || other == ValueType::Boolean;
763
765 return other == ValueType::String ||
766 (other == ValueType::Null &&
767 ((value_.stringVal == nullptr) || value_.stringVal[0] == 0));
768
769 case ValueType::Array:
770 return other == ValueType::Array ||
771 (other == ValueType::Null && value_.mapVal->empty());
772
774 return other == ValueType::Object ||
775 (other == ValueType::Null && value_.mapVal->empty());
776
777 // LCOV_EXCL_START
778 default:
779 UNREACHABLE("json::Value::isConvertible : invalid type");
780 // LCOV_EXCL_STOP
781 }
782
783 return false; // unreachable;
784}
785
789{
790 switch (type_)
791 {
792 case ValueType::Null:
793 case ValueType::Int:
794 case ValueType::UInt:
795 case ValueType::Real:
798 return 0;
799
800 case ValueType::Array: // size of the array is highest index + 1
801 if (!value_.mapVal->empty())
802 {
803 ObjectValues::const_iterator itLast = value_.mapVal->end();
804 --itLast;
805 return (*itLast).first.index() + 1;
806 }
807
808 return 0;
809
811 return Int(value_.mapVal->size());
812
813 // LCOV_EXCL_START
814 default:
815 UNREACHABLE("json::Value::size : invalid type");
816 // LCOV_EXCL_STOP
817 }
818
819 return 0; // unreachable;
820}
821
822Value::
823operator bool() const
824{
825 if (isNull())
826 return false;
827
828 if (isString())
829 {
830 auto s = asCString();
831 return (s != nullptr) && (s[0] != 0);
832 }
833
834 return !(isArray() || isObject()) || (size() != 0u);
835}
836
837void
839{
840 XRPL_ASSERT(
842 "json::Value::clear : valid type");
843
844 switch (type_)
845 {
846 case ValueType::Array:
848 value_.mapVal->clear();
849 break;
850
851 default:
852 break;
853 }
854}
855
856Value&
858{
859 XRPL_ASSERT(
861 "json::Value::operator[](UInt) : valid type");
862
863 if (type_ == ValueType::Null)
864 *this = Value(ValueType::Array);
865
866 CZString const key(index);
867 ObjectValues::iterator it = value_.mapVal->lower_bound(key);
868
869 if (it != value_.mapVal->end() && (*it).first == key)
870 return (*it).second;
871
872 ObjectValues::value_type const defaultValue(key, kNull);
873 it = value_.mapVal->insert(it, defaultValue);
874 return (*it).second;
875}
876
877Value const&
879{
880 XRPL_ASSERT(
882 "json::Value::operator[](UInt) const : valid type");
883
884 if (type_ == ValueType::Null)
885 return kNull;
886
887 CZString const key(index);
888 ObjectValues::const_iterator const it = value_.mapVal->find(key);
889
890 if (it == value_.mapVal->end())
891 return kNull;
892
893 return (*it).second;
894}
895
896Value&
897Value::operator[](char const* key)
898{
899 return resolveReference(key, false);
900}
901
902Value&
903Value::resolveReference(char const* key, bool isStatic)
904{
905 XRPL_ASSERT(
907 "json::Value::resolveReference : valid type");
908
909 if (type_ == ValueType::Null)
910 *this = Value(ValueType::Object);
911
912 CZString const actualKey(
913 key,
916 ObjectValues::iterator it = value_.mapVal->lower_bound(actualKey);
917
918 if (it != value_.mapVal->end() && (*it).first == actualKey)
919 return (*it).second;
920
921 ObjectValues::value_type const defaultValue(actualKey, kNull);
922 it = value_.mapVal->insert(it, defaultValue);
923 Value& value = (*it).second;
924 return value;
925}
926
927Value
928Value::get(UInt index, Value const& defaultValue) const
929{
930 Value const* value = &((*this)[index]);
931 return value == &kNull ? defaultValue : *value;
932}
933
934bool
936{
937 return index < size();
938}
939
940Value const&
941Value::operator[](char const* key) const
942{
943 XRPL_ASSERT(
945 "json::Value::operator[](const char*) const : valid type");
946
947 if (type_ == ValueType::Null)
948 return kNull;
949
951 ObjectValues::const_iterator const it = value_.mapVal->find(actualKey);
952
953 if (it == value_.mapVal->end())
954 return kNull;
955
956 return (*it).second;
957}
958
959Value&
961{
962 return (*this)[key.c_str()];
963}
964
965Value const&
967{
968 return (*this)[key.c_str()];
969}
970
971Value&
973{
974 return resolveReference(key, true);
975}
976
977Value const&
979{
980 return (*this)[key.cStr()];
981}
982
983Value&
984Value::append(Value const& value)
985{
986 return (*this)[size()] = value;
987}
988
989Value&
991{
992 return (*this)[size()] = std::move(value);
993}
994
995Value
996Value::get(char const* key, Value const& defaultValue) const
997{
998 Value const* value = &((*this)[key]);
999 return value == &kNull ? defaultValue : *value;
1000}
1001
1002Value
1003Value::get(std::string const& key, Value const& defaultValue) const
1004{
1005 return get(key.c_str(), defaultValue);
1006}
1007
1008Value
1009Value::removeMember(char const* key)
1010{
1011 XRPL_ASSERT(
1013 "json::Value::removeMember : valid type");
1014
1015 if (type_ == ValueType::Null)
1016 return kNull;
1017
1019 ObjectValues::iterator const it = value_.mapVal->find(actualKey);
1020
1021 if (it == value_.mapVal->end())
1022 return kNull;
1023
1024 Value old(it->second);
1025 value_.mapVal->erase(it);
1026 return old;
1027}
1028
1029Value
1031{
1032 return removeMember(key.c_str());
1033}
1034
1035bool
1036Value::isMember(char const* key) const
1037{
1038 if (type_ != ValueType::Object)
1039 return false;
1040
1041 Value const* value = &((*this)[key]);
1042 return value != &kNull;
1043}
1044
1045bool
1047{
1048 return isMember(key.c_str());
1049}
1050
1051bool
1053{
1054 return isMember(key.cStr());
1055}
1056
1059{
1060 XRPL_ASSERT(
1062 "json::Value::getMemberNames : valid type");
1063
1064 if (type_ == ValueType::Null)
1065 return Value::Members();
1066
1067 Members members;
1068 members.reserve(value_.mapVal->size());
1069 ObjectValues::const_iterator it = value_.mapVal->begin();
1070 ObjectValues::const_iterator const itEnd = value_.mapVal->end();
1071
1072 for (; it != itEnd; ++it)
1073 members.emplace_back((*it).first.cStr());
1074
1075 return members;
1076}
1077
1078bool
1080{
1081 return type_ == ValueType::Null;
1082}
1083
1084bool
1086{
1087 return type_ == ValueType::Boolean;
1088}
1089
1090bool
1092{
1093 return type_ == ValueType::Int;
1094}
1095
1096bool
1098{
1099 return type_ == ValueType::UInt;
1100}
1101
1102bool
1107
1108bool
1110{
1111 return type_ == ValueType::Real;
1112}
1113
1114bool
1116{
1117 return isIntegral() || isDouble();
1118}
1119
1120bool
1122{
1123 return type_ == ValueType::String;
1124}
1125
1126bool
1128{
1129 return type_ == ValueType::Array;
1130}
1131
1132bool
1134{
1136}
1137
1138bool
1140{
1141 return type_ == ValueType::Object;
1142}
1143
1144bool
1146{
1148}
1149
1152{
1153 StyledWriter writer;
1154 return writer.write(*this);
1155}
1156
1159{
1160 switch (type_)
1161 {
1162 case ValueType::Array:
1163 case ValueType::Object:
1164 if (value_.mapVal != nullptr)
1165 return const_iterator(value_.mapVal->begin());
1166
1167 break;
1168 default:
1169 break;
1170 }
1171
1172 return const_iterator();
1173}
1174
1177{
1178 switch (type_)
1179 {
1180 case ValueType::Array:
1181 case ValueType::Object:
1182 if (value_.mapVal != nullptr)
1183 return const_iterator(value_.mapVal->end());
1184
1185 break;
1186 default:
1187 break;
1188 }
1189
1190 return const_iterator();
1191}
1192
1195{
1196 switch (type_)
1197 {
1198 case ValueType::Array:
1199 case ValueType::Object:
1200 if (value_.mapVal != nullptr)
1201 return iterator(value_.mapVal->begin());
1202 break;
1203 default:
1204 break;
1205 }
1206
1207 return iterator();
1208}
1209
1212{
1213 switch (type_)
1214 {
1215 case ValueType::Array:
1216 case ValueType::Object:
1217 if (value_.mapVal != nullptr)
1218 return iterator(value_.mapVal->end());
1219 break;
1220 default:
1221 break;
1222 }
1223
1224 return iterator();
1225}
1226
1227} // namespace json
T c_str(T... args)
void releaseMemberName(char *memberName) override
~DefaultValueAllocator() override=default
char * duplicateStringValue(char const *value, unsigned int length=kUnknown) override
void releaseStringValue(char *value) override
char * makeMemberName(char const *memberName) override
Lightweight wrapper to tag static string.
Definition json_value.h:44
constexpr char const * cStr() const
Definition json_value.h:57
Writes a Value in JSON format in a human friendly way.
Definition json_writer.h:67
std::string write(Value const &root) override
Serialize a Value in JSON format.
Experimental do not use: Allocator to customize member name and string value memory management done b...
Definition json_value.h:473
virtual void releaseMemberName(char *memberName)=0
virtual void releaseStringValue(char *value)=0
virtual char * duplicateStringValue(char const *value, unsigned int length=kUnknown)=0
static constexpr auto kUnknown
Definition json_value.h:475
bool isStaticString() const
bool operator<(CZString const &other) const
char const * cStr() const
bool operator==(CZString const &other) const
Represents a JSON value.
Definition json_value.h:130
static constexpr Int kMaxInt
Definition json_value.h:143
const_iterator begin() const
bool isIntegral() const
bool isDouble() const
Value removeMember(char const *key)
Remove and return the named member.
bool isNull() const
isNull() tests to see if this field is null.
json::Int Int
Definition json_value.h:138
bool isObject() const
bool asBool() const
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
ValueConstIterator const_iterator
Definition json_value.h:136
std::vector< std::string > Members
Definition json_value.h:134
bool isBool() const
union json::Value::ValueHolder value_
bool isValidIndex(UInt index) const
Return true if index < size().
Value & resolveReference(char const *key, bool isStatic)
std::string toStyledString() const
bool isArray() const
UInt asAbsUInt() const
Correct absolute value from int or unsigned int.
bool isString() const
json::UInt UInt
Definition json_value.h:137
Value & append(Value const &value)
Append value to array at the end.
UInt size() const
Number of values in array or object.
ValueType type_
Definition json_value.h:424
Members getMemberNames() const
Return a list of the member names.
bool isNumeric() const
static constexpr Int kMinInt
Definition json_value.h:142
bool isArrayOrNull() const
const_iterator end() const
bool isUInt() const
ValueIterator iterator
Definition json_value.h:135
double asDouble() const
Value & operator=(Value const &other)
bool isInt() const
UInt asUInt() const
ValueType type() const
bool isConvertibleTo(ValueType other) const
std::string asString() const
Returns the unquoted string value.
void swap(Value &other) noexcept
Swap values.
static constexpr UInt kMaxUInt
Definition json_value.h:144
Value & operator[](UInt index)
Access an array element (zero based index ).
static Value const kNull
Definition json_value.h:141
Value(ValueType type=ValueType::Null)
Create a default Value of the given type.
char const * asCString() const
std::map< CZString, Value > ObjectValues
Definition json_value.h:175
bool isObjectOrNull() const
bool isMember(char const *key) const
Return true if the object has a member named key.
Int asInt() const
void clear()
Remove all object members and array elements.
Number is a floating point type that can represent a wide range of values.
Definition Number.h:306
T emplace_back(T... args)
T epsilon(T... args)
T fabs(T... args)
Out lexicalCastThrow(In in)
Convert from one type to another, throw on error.
JSON (JavaScript Object Notation).
Definition json_errors.h:5
static ValueAllocator *& valueAllocator()
int Int
std::string to_string(Value const &)
Writes a json::Value to an std::string.
Definition to_string.cpp:10
unsigned int UInt
bool operator==(StaticString x, StaticString y)
Definition json_value.h:67
ValueType
Type of the value held by a Value object.
Definition json_value.h:18
@ UInt
unsigned integer value
Definition json_value.h:21
@ Int
signed integer value
Definition json_value.h:20
@ String
UTF-8 string value.
Definition json_value.h:23
@ Boolean
bool value
Definition json_value.h:24
@ Array
array value (ordered list)
Definition json_value.h:25
@ Object
object value (collection of name/value pairs).
Definition json_value.h:26
@ Real
double value
Definition json_value.h:22
@ Null
'null' value
Definition json_value.h:19
static int integerCmp(Int i, UInt ui)
bool operator<(Value const &, Value const &)
static struct json::DummyValueAllocatorInitializer gDummyValueAllocatorInitializer
T reserve(T... args)
T size(T... args)
T swap(T... args)
T to_string(T... args)
ObjectValues * mapVal
Definition json_value.h:422