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