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 ? (unsigned int)strlen(value) : 0;
44
45 char* newString = static_cast<char*>(malloc(length + 1));
46 if (value)
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)
56 free(value);
57 }
58};
59
60static ValueAllocator*&
66
68{
70 {
71 valueAllocator(); // ensure valueAllocator() statics are initialized
72 // before main().
73 }
75
76// //////////////////////////////////////////////////////////////////
77// //////////////////////////////////////////////////////////////////
78// //////////////////////////////////////////////////////////////////
79// class Value::CZString
80// //////////////////////////////////////////////////////////////////
81// //////////////////////////////////////////////////////////////////
82// //////////////////////////////////////////////////////////////////
83
84// Notes: index_ indicates if the string was allocated when
85// a string is stored.
86
87Value::CZString::CZString(int index) : cstr_(0), index_(index)
88{
89}
90
92 : cstr_(allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr), index_(allocate)
93{
94}
95
97 : cstr_(
98 other.index_ != noDuplication && other.cstr_ != 0 ? valueAllocator()->makeMemberName(other.cstr_)
99 : other.cstr_)
100 , index_(other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_)
101{
102}
103
105{
106 if (cstr_ && index_ == duplicate)
107 valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
108}
109
110bool
111Value::CZString::operator<(CZString const& other) const
112{
113 if (cstr_ && other.cstr_)
114 return strcmp(cstr_, other.cstr_) < 0;
115
116 return index_ < other.index_;
117}
118
119bool
121{
122 if (cstr_ && other.cstr_)
123 return strcmp(cstr_, other.cstr_) == 0;
124
125 return index_ == other.index_;
126}
127
128int
130{
131 return index_;
132}
133
134char const*
136{
137 return cstr_;
138}
139
140bool
142{
143 return index_ == noDuplication;
144}
145
146// //////////////////////////////////////////////////////////////////
147// //////////////////////////////////////////////////////////////////
148// //////////////////////////////////////////////////////////////////
149// class Value::Value
150// //////////////////////////////////////////////////////////////////
151// //////////////////////////////////////////////////////////////////
152// //////////////////////////////////////////////////////////////////
153
159{
160 switch (type)
161 {
162 case nullValue:
163 break;
164
165 case intValue:
166 case uintValue:
167 value_.int_ = 0;
168 break;
169
170 case realValue:
171 value_.real_ = 0.0;
172 break;
173
174 case stringValue:
175 value_.string_ = 0;
176 break;
177
178 case arrayValue:
179 case objectValue:
180 value_.map_ = new ObjectValues();
181 break;
182
183 case booleanValue:
184 value_.bool_ = false;
185 break;
186
187 // LCOV_EXCL_START
188 default:
189 UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
190 // LCOV_EXCL_STOP
191 }
192}
193
194Value::Value(Int value) : type_(intValue)
195{
196 value_.int_ = value;
197}
198
200{
201 value_.uint_ = value;
202}
203
204Value::Value(double value) : type_(realValue)
205{
206 value_.real_ = value;
207}
208
209Value::Value(char const* value) : type_(stringValue), allocated_(true)
210{
212}
213
214Value::Value(xrpl::Number const& value) : type_(stringValue), allocated_(true)
215{
216 auto const tmp = to_string(value);
217 value_.string_ = valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
218}
219
220Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
221{
222 value_.string_ = valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
223}
224
225Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
226{
227 value_.string_ = const_cast<char*>(value.c_str());
228}
229
230Value::Value(bool value) : type_(booleanValue)
231{
232 value_.bool_ = value;
233}
234
235Value::Value(Value const& other) : type_(other.type_)
236{
237 switch (type_)
238 {
239 case nullValue:
240 case intValue:
241 case uintValue:
242 case realValue:
243 case booleanValue:
244 value_ = other.value_;
245 break;
246
247 case stringValue:
248 if (other.value_.string_)
249 {
251 allocated_ = true;
252 }
253 else
254 value_.string_ = 0;
255
256 break;
257
258 case arrayValue:
259 case objectValue:
260 value_.map_ = new ObjectValues(*other.value_.map_);
261 break;
262
263 // LCOV_EXCL_START
264 default:
265 UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
266 // LCOV_EXCL_STOP
267 }
268}
269
271{
272 switch (type_)
273 {
274 case nullValue:
275 case intValue:
276 case uintValue:
277 case realValue:
278 case booleanValue:
279 break;
280
281 case stringValue:
282 if (allocated_)
284
285 break;
286
287 case arrayValue:
288 case objectValue:
289 if (value_.map_)
290 delete value_.map_;
291 break;
292
293 // LCOV_EXCL_START
294 default:
295 UNREACHABLE("Json::Value::~Value : invalid type");
296 // LCOV_EXCL_STOP
297 }
298}
299
300Value&
302{
303 Value tmp(other);
304 swap(tmp);
305 return *this;
306}
307
308Value::Value(Value&& other) noexcept : value_(other.value_), type_(other.type_), allocated_(other.allocated_)
309{
310 other.type_ = nullValue;
311 other.allocated_ = 0;
312}
313
314Value&
316{
317 Value tmp(std::move(other));
318 swap(tmp);
319 return *this;
320}
321
322void
323Value::swap(Value& other) noexcept
324{
325 std::swap(value_, other.value_);
326
327 ValueType temp = type_;
328 type_ = other.type_;
329 other.type_ = temp;
330
331 int temp2 = allocated_;
332 allocated_ = other.allocated_;
333 other.allocated_ = temp2;
334}
335
338{
339 return type_;
340}
341
342static int
344{
345 // All negative numbers are less than all unsigned numbers.
346 if (i < 0)
347 return -1;
348
349 // Now we can safely compare.
350 return (i < ui) ? -1 : (i == ui) ? 0 : 1;
351}
352
353bool
354operator<(Value const& x, Value const& y)
355{
356 if (auto signum = x.type_ - y.type_)
357 {
358 if (x.type_ == intValue && y.type_ == uintValue)
359 signum = integerCmp(x.value_.int_, y.value_.uint_);
360 else if (x.type_ == uintValue && y.type_ == intValue)
361 signum = -integerCmp(y.value_.int_, x.value_.uint_);
362 return signum < 0;
363 }
364
365 switch (x.type_)
366 {
367 case nullValue:
368 return false;
369
370 case intValue:
371 return x.value_.int_ < y.value_.int_;
372
373 case uintValue:
374 return x.value_.uint_ < y.value_.uint_;
375
376 case realValue:
377 return x.value_.real_ < y.value_.real_;
378
379 case booleanValue:
380 return x.value_.bool_ < y.value_.bool_;
381
382 case stringValue:
383 return (x.value_.string_ == 0 && y.value_.string_) ||
384 (y.value_.string_ && x.value_.string_ && strcmp(x.value_.string_, y.value_.string_) < 0);
385
386 case arrayValue:
387 case objectValue: {
388 if (int signum = int(x.value_.map_->size()) - y.value_.map_->size())
389 return signum < 0;
390
391 return *x.value_.map_ < *y.value_.map_;
392 }
393
394 // LCOV_EXCL_START
395 default:
396 UNREACHABLE("Json::operator<(Value, Value) : invalid type");
397 // LCOV_EXCL_STOP
398 }
399
400 return 0; // unreachable
401}
402
403bool
404operator==(Value const& x, Value const& y)
405{
406 if (x.type_ != y.type_)
407 {
408 if (x.type_ == intValue && y.type_ == uintValue)
409 return !integerCmp(x.value_.int_, y.value_.uint_);
410 if (x.type_ == uintValue && y.type_ == intValue)
411 return !integerCmp(y.value_.int_, x.value_.uint_);
412 return false;
413 }
414
415 switch (x.type_)
416 {
417 case nullValue:
418 return true;
419
420 case intValue:
421 return x.value_.int_ == y.value_.int_;
422
423 case uintValue:
424 return x.value_.uint_ == y.value_.uint_;
425
426 case realValue:
427 return x.value_.real_ == y.value_.real_;
428
429 case booleanValue:
430 return x.value_.bool_ == y.value_.bool_;
431
432 case stringValue:
433 return x.value_.string_ == y.value_.string_ ||
434 (y.value_.string_ && x.value_.string_ && !strcmp(x.value_.string_, y.value_.string_));
435
436 case arrayValue:
437 case objectValue:
438 return x.value_.map_->size() == y.value_.map_->size() && *x.value_.map_ == *y.value_.map_;
439
440 // LCOV_EXCL_START
441 default:
442 UNREACHABLE("Json::operator==(Value, Value) : invalid type");
443 // LCOV_EXCL_STOP
444 }
445
446 return 0; // unreachable
447}
448
449char const*
451{
452 XRPL_ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
453 return value_.string_;
454}
455
458{
459 switch (type_)
460 {
461 case nullValue:
462 return "";
463
464 case stringValue:
465 return value_.string_ ? value_.string_ : "";
466
467 case booleanValue:
468 return value_.bool_ ? "true" : "false";
469
470 case intValue:
471 return std::to_string(value_.int_);
472
473 case uintValue:
475
476 case realValue:
478
479 case arrayValue:
480 case objectValue:
481 JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
482
483 // LCOV_EXCL_START
484 default:
485 UNREACHABLE("Json::Value::asString : invalid type");
486 // LCOV_EXCL_STOP
487 }
488
489 return ""; // unreachable
490}
491
494{
495 switch (type_)
496 {
497 case nullValue:
498 return 0;
499
500 case intValue:
501 return value_.int_;
502
503 case uintValue:
504 JSON_ASSERT_MESSAGE(value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
505 return value_.uint_;
506
507 case realValue:
508 JSON_ASSERT_MESSAGE(value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
509 return Int(value_.real_);
510
511 case booleanValue:
512 return value_.bool_ ? 1 : 0;
513
514 case stringValue: {
515 char const* const str{value_.string_ ? value_.string_ : ""};
516 return beast::lexicalCastThrow<int>(str);
517 }
518
519 case arrayValue:
520 case objectValue:
521 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
522
523 // LCOV_EXCL_START
524 default:
525 UNREACHABLE("Json::Value::asInt : invalid type");
526 // LCOV_EXCL_STOP
527 }
528
529 return 0; // unreachable;
530}
531
532UInt
534{
535 switch (type_)
536 {
537 case nullValue:
538 return 0;
539
540 case intValue: {
541 // Doing this conversion through int64 avoids overflow error for
542 // value_.int_ = -1 * 2^31 i.e. numeric_limits<int>::min().
543 if (value_.int_ < 0)
544 return static_cast<std::int64_t>(value_.int_) * -1;
545 return value_.int_;
546 }
547
548 case uintValue:
549 return value_.uint_;
550
551 case realValue: {
552 if (value_.real_ < 0)
553 {
554 JSON_ASSERT_MESSAGE(-1 * value_.real_ <= maxUInt, "Real out of unsigned integer range");
555 return UInt(-1 * value_.real_);
556 }
557 JSON_ASSERT_MESSAGE(value_.real_ <= maxUInt, "Real out of unsigned integer range");
558 return UInt(value_.real_);
559 }
560
561 case booleanValue:
562 return value_.bool_ ? 1 : 0;
563
564 case stringValue: {
565 char const* const str{value_.string_ ? value_.string_ : ""};
566 auto const temp = beast::lexicalCastThrow<std::int64_t>(str);
567 if (temp < 0)
568 {
569 JSON_ASSERT_MESSAGE(-1 * temp <= maxUInt, "String out of unsigned integer range");
570 return -1 * temp;
571 }
572 JSON_ASSERT_MESSAGE(temp <= maxUInt, "String out of unsigned integer range");
573 return temp;
574 }
575
576 case arrayValue:
577 case objectValue:
578 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
579
580 // LCOV_EXCL_START
581 default:
582 UNREACHABLE("Json::Value::asAbsInt : invalid type");
583 // LCOV_EXCL_STOP
584 }
585
586 return 0; // unreachable;
587}
588
591{
592 switch (type_)
593 {
594 case nullValue:
595 return 0;
596
597 case intValue:
598 JSON_ASSERT_MESSAGE(value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
599 return value_.int_;
600
601 case uintValue:
602 return value_.uint_;
603
604 case realValue:
605 JSON_ASSERT_MESSAGE(value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
606 return UInt(value_.real_);
607
608 case booleanValue:
609 return value_.bool_ ? 1 : 0;
610
611 case stringValue: {
612 char const* const str{value_.string_ ? value_.string_ : ""};
613 return beast::lexicalCastThrow<unsigned int>(str);
614 }
615
616 case arrayValue:
617 case objectValue:
618 JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
619
620 // LCOV_EXCL_START
621 default:
622 UNREACHABLE("Json::Value::asUInt : invalid type");
623 // LCOV_EXCL_STOP
624 }
625
626 return 0; // unreachable;
627}
628
629double
631{
632 switch (type_)
633 {
634 case nullValue:
635 return 0.0;
636
637 case intValue:
638 return value_.int_;
639
640 case uintValue:
641 return value_.uint_;
642
643 case realValue:
644 return value_.real_;
645
646 case booleanValue:
647 return value_.bool_ ? 1.0 : 0.0;
648
649 case stringValue:
650 case arrayValue:
651 case objectValue:
652 JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
653
654 // LCOV_EXCL_START
655 default:
656 UNREACHABLE("Json::Value::asDouble : invalid type");
657 // LCOV_EXCL_STOP
658 }
659
660 return 0; // unreachable;
661}
662
663bool
665{
666 switch (type_)
667 {
668 case nullValue:
669 return false;
670
671 case intValue:
672 case uintValue:
673 return value_.int_ != 0;
674
675 case realValue:
676 return value_.real_ != 0.0;
677
678 case booleanValue:
679 return value_.bool_;
680
681 case stringValue:
682 return value_.string_ && value_.string_[0] != 0;
683
684 case arrayValue:
685 case objectValue:
686 return value_.map_->size() != 0;
687
688 // LCOV_EXCL_START
689 default:
690 UNREACHABLE("Json::Value::asBool : invalid type");
691 // LCOV_EXCL_STOP
692 }
693
694 return false; // unreachable;
695}
696
697bool
699{
700 switch (type_)
701 {
702 case nullValue:
703 return true;
704
705 case intValue:
706 return (other == nullValue && value_.int_ == 0) || other == intValue ||
707 (other == uintValue && value_.int_ >= 0) || other == realValue || other == stringValue ||
708 other == booleanValue;
709
710 case uintValue:
711 return (other == nullValue && value_.uint_ == 0) ||
712 (other == intValue && value_.uint_ <= (unsigned)maxInt) || other == uintValue || other == realValue ||
713 other == stringValue || other == booleanValue;
714
715 case realValue:
716 return (other == nullValue && value_.real_ == 0.0) ||
717 (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt) ||
718 (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt &&
720 other == realValue || other == stringValue || other == booleanValue;
721
722 case booleanValue:
723 return (other == nullValue && value_.bool_ == false) || other == intValue || other == uintValue ||
724 other == realValue || other == stringValue || other == booleanValue;
725
726 case stringValue:
727 return other == stringValue || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
728
729 case arrayValue:
730 return other == arrayValue || (other == nullValue && value_.map_->size() == 0);
731
732 case objectValue:
733 return other == objectValue || (other == nullValue && value_.map_->size() == 0);
734
735 // LCOV_EXCL_START
736 default:
737 UNREACHABLE("Json::Value::isConvertible : invalid type");
738 // LCOV_EXCL_STOP
739 }
740
741 return false; // unreachable;
742}
743
747{
748 switch (type_)
749 {
750 case nullValue:
751 case intValue:
752 case uintValue:
753 case realValue:
754 case booleanValue:
755 case stringValue:
756 return 0;
757
758 case arrayValue: // size of the array is highest index + 1
759 if (!value_.map_->empty())
760 {
761 ObjectValues::const_iterator itLast = value_.map_->end();
762 --itLast;
763 return (*itLast).first.index() + 1;
764 }
765
766 return 0;
767
768 case objectValue:
769 return Int(value_.map_->size());
770
771 // LCOV_EXCL_START
772 default:
773 UNREACHABLE("Json::Value::size : invalid type");
774 // LCOV_EXCL_STOP
775 }
776
777 return 0; // unreachable;
778}
779
780Value::operator bool() const
781{
782 if (isNull())
783 return false;
784
785 if (isString())
786 {
787 auto s = asCString();
788 return s && s[0];
789 }
790
791 return !(isArray() || isObject()) || size();
792}
793
794void
796{
797 XRPL_ASSERT(type_ == nullValue || type_ == arrayValue || type_ == objectValue, "Json::Value::clear : valid type");
798
799 switch (type_)
800 {
801 case arrayValue:
802 case objectValue:
803 value_.map_->clear();
804 break;
805
806 default:
807 break;
808 }
809}
810
811Value&
813{
814 XRPL_ASSERT(type_ == nullValue || type_ == arrayValue, "Json::Value::operator[](UInt) : valid type");
815
816 if (type_ == nullValue)
817 *this = Value(arrayValue);
818
819 CZString key(index);
820 ObjectValues::iterator it = value_.map_->lower_bound(key);
821
822 if (it != value_.map_->end() && (*it).first == key)
823 return (*it).second;
824
825 ObjectValues::value_type defaultValue(key, null);
826 it = value_.map_->insert(it, defaultValue);
827 return (*it).second;
828}
829
830Value const&
832{
833 XRPL_ASSERT(type_ == nullValue || type_ == arrayValue, "Json::Value::operator[](UInt) const : valid type");
834
835 if (type_ == nullValue)
836 return null;
837
838 CZString key(index);
839 ObjectValues::const_iterator it = value_.map_->find(key);
840
841 if (it == value_.map_->end())
842 return null;
843
844 return (*it).second;
845}
846
847Value&
848Value::operator[](char const* key)
849{
850 return resolveReference(key, false);
851}
852
853Value&
854Value::resolveReference(char const* key, bool isStatic)
855{
856 XRPL_ASSERT(type_ == nullValue || type_ == objectValue, "Json::Value::resolveReference : valid type");
857
858 if (type_ == nullValue)
859 *this = Value(objectValue);
860
862 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
863
864 if (it != value_.map_->end() && (*it).first == actualKey)
865 return (*it).second;
866
867 ObjectValues::value_type defaultValue(actualKey, null);
868 it = value_.map_->insert(it, defaultValue);
869 Value& value = (*it).second;
870 return value;
871}
872
873Value
874Value::get(UInt index, Value const& defaultValue) const
875{
876 Value const* value = &((*this)[index]);
877 return value == &null ? defaultValue : *value;
878}
879
880bool
882{
883 return index < size();
884}
885
886Value const&
887Value::operator[](char const* key) const
888{
889 XRPL_ASSERT(type_ == nullValue || type_ == objectValue, "Json::Value::operator[](const char*) const : valid type");
890
891 if (type_ == nullValue)
892 return null;
893
894 CZString actualKey(key, CZString::noDuplication);
895 ObjectValues::const_iterator it = value_.map_->find(actualKey);
896
897 if (it == value_.map_->end())
898 return null;
899
900 return (*it).second;
901}
902
903Value&
905{
906 return (*this)[key.c_str()];
907}
908
909Value const&
911{
912 return (*this)[key.c_str()];
913}
914
915Value&
917{
918 return resolveReference(key, true);
919}
920
921Value const&
923{
924 return (*this)[key.c_str()];
925}
926
927Value&
928Value::append(Value const& value)
929{
930 return (*this)[size()] = value;
931}
932
933Value&
935{
936 return (*this)[size()] = std::move(value);
937}
938
939Value
940Value::get(char const* key, Value const& defaultValue) const
941{
942 Value const* value = &((*this)[key]);
943 return value == &null ? defaultValue : *value;
944}
945
946Value
947Value::get(std::string const& key, Value const& defaultValue) const
948{
949 return get(key.c_str(), defaultValue);
950}
951
952Value
953Value::removeMember(char const* key)
954{
955 XRPL_ASSERT(type_ == nullValue || type_ == objectValue, "Json::Value::removeMember : valid type");
956
957 if (type_ == nullValue)
958 return null;
959
960 CZString actualKey(key, CZString::noDuplication);
961 ObjectValues::iterator it = value_.map_->find(actualKey);
962
963 if (it == value_.map_->end())
964 return null;
965
966 Value old(it->second);
967 value_.map_->erase(it);
968 return old;
969}
970
971Value
973{
974 return removeMember(key.c_str());
975}
976
977bool
978Value::isMember(char const* key) const
979{
980 if (type_ != objectValue)
981 return false;
982
983 Value const* value = &((*this)[key]);
984 return value != &null;
985}
986
987bool
989{
990 return isMember(key.c_str());
991}
992
993bool
995{
996 return isMember(key.c_str());
997}
998
1001{
1002 XRPL_ASSERT(type_ == nullValue || type_ == objectValue, "Json::Value::getMemberNames : valid type");
1003
1004 if (type_ == nullValue)
1005 return Value::Members();
1006
1007 Members members;
1008 members.reserve(value_.map_->size());
1009 ObjectValues::const_iterator it = value_.map_->begin();
1010 ObjectValues::const_iterator itEnd = value_.map_->end();
1011
1012 for (; it != itEnd; ++it)
1013 members.push_back(std::string((*it).first.c_str()));
1014
1015 return members;
1016}
1017
1018bool
1020{
1021 return type_ == nullValue;
1022}
1023
1024bool
1026{
1027 return type_ == booleanValue;
1028}
1029
1030bool
1032{
1033 return type_ == intValue;
1034}
1035
1036bool
1038{
1039 return type_ == uintValue;
1040}
1041
1042bool
1044{
1045 return type_ == intValue || type_ == uintValue || type_ == booleanValue;
1046}
1047
1048bool
1050{
1051 return type_ == realValue;
1052}
1053
1054bool
1056{
1057 return isIntegral() || isDouble();
1058}
1059
1060bool
1062{
1063 return type_ == stringValue;
1064}
1065
1066bool
1068{
1069 return type_ == arrayValue;
1070}
1071
1072bool
1074{
1075 return type_ == nullValue || type_ == arrayValue;
1076}
1077
1078bool
1080{
1081 return type_ == objectValue;
1082}
1083
1084bool
1086{
1087 return type_ == nullValue || type_ == objectValue;
1088}
1089
1092{
1093 StyledWriter writer;
1094 return writer.write(*this);
1095}
1096
1099{
1100 switch (type_)
1101 {
1102 case arrayValue:
1103 case objectValue:
1104 if (value_.map_)
1105 return const_iterator(value_.map_->begin());
1106
1107 break;
1108 default:
1109 break;
1110 }
1111
1112 return const_iterator();
1113}
1114
1117{
1118 switch (type_)
1119 {
1120 case arrayValue:
1121 case objectValue:
1122 if (value_.map_)
1123 return const_iterator(value_.map_->end());
1124
1125 break;
1126 default:
1127 break;
1128 }
1129
1130 return const_iterator();
1131}
1132
1135{
1136 switch (type_)
1137 {
1138 case arrayValue:
1139 case objectValue:
1140 if (value_.map_)
1141 return iterator(value_.map_->begin());
1142 break;
1143 default:
1144 break;
1145 }
1146
1147 return iterator();
1148}
1149
1152{
1153 switch (type_)
1154 {
1155 case arrayValue:
1156 case objectValue:
1157 if (value_.map_)
1158 return iterator(value_.map_->end());
1159 break;
1160 default:
1161 break;
1162 }
1163
1164 return iterator();
1165}
1166
1167} // 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:45
constexpr char const * c_str() const
Definition json_value.h:58
Writes a Value in JSON format in a human friendly way.
Definition json_writer.h:72
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 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:558
Iterator for object and array value.
Definition json_value.h:619
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:131
const_iterator begin() const
Json::UInt UInt
Definition json_value.h:138
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:142
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:136
ValueConstIterator const_iterator
Definition json_value.h:137
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:135
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:139
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:144
bool isIntegral() const
bool asBool() const
ValueType type_
Definition json_value.h:424
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:143
std::map< CZString, Value > ObjectValues
Definition json_value.h:175
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:145
bool isInt() const
Number is a floating point type that can represent a wide range of values.
Definition Number.h:208
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:6
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:19
@ booleanValue
bool value
Definition json_value.h:25
@ nullValue
'null' value
Definition json_value.h:20
@ stringValue
UTF-8 string value.
Definition json_value.h:24
@ realValue
double value
Definition json_value.h:23
@ arrayValue
array value (ordered list)
Definition json_value.h:26
@ intValue
signed integer value
Definition json_value.h:21
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
@ uintValue
unsigned integer value
Definition json_value.h:22
bool operator<(Value const &, Value const &)
bool operator==(StaticString x, StaticString y)
Definition json_value.h:68
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)