rippled
Loading...
Searching...
No Matches
json_value.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/beast/core/LexicalCast.h>
21#include <xrpl/beast/utility/instrumentation.h>
22#include <xrpl/json/detail/json_assert.h>
23#include <xrpl/json/json_forwards.h>
24#include <xrpl/json/json_value.h>
25#include <xrpl/json/json_writer.h>
26
27#include <cmath>
28#include <cstdlib>
29#include <cstring>
30#include <string>
31#include <utility>
32
33namespace Json {
34
35Value const Value::null;
36Int const Value::minInt = Int(~(UInt(-1) / 2));
37Int const Value::maxInt = Int(UInt(-1) / 2);
38UInt const Value::maxUInt = UInt(-1);
39
41{
42public:
43 virtual ~DefaultValueAllocator() = default;
44
45 char*
46 makeMemberName(char const* memberName) override
47 {
48 return duplicateStringValue(memberName);
49 }
50
51 void
52 releaseMemberName(char* memberName) override
53 {
54 releaseStringValue(memberName);
55 }
56
57 char*
58 duplicateStringValue(char const* value, unsigned int length = unknown)
59 override
60 {
61 //@todo investigate this old optimization
62 // if ( !value || value[0] == 0 )
63 // return 0;
64
65 if (length == unknown)
66 length = value ? (unsigned int)strlen(value) : 0;
67
68 char* newString = static_cast<char*>(malloc(length + 1));
69 if (value)
70 memcpy(newString, value, length);
71 newString[length] = 0;
72 return newString;
73 }
74
75 void
76 releaseStringValue(char* value) override
77 {
78 if (value)
79 free(value);
80 }
81};
82
83static ValueAllocator*&
89
91{
93 {
94 valueAllocator(); // ensure valueAllocator() statics are initialized
95 // before main().
96 }
98
99// //////////////////////////////////////////////////////////////////
100// //////////////////////////////////////////////////////////////////
101// //////////////////////////////////////////////////////////////////
102// class Value::CZString
103// //////////////////////////////////////////////////////////////////
104// //////////////////////////////////////////////////////////////////
105// //////////////////////////////////////////////////////////////////
106
107// Notes: index_ indicates if the string was allocated when
108// a string is stored.
109
110Value::CZString::CZString(int index) : cstr_(0), index_(index)
111{
112}
113
115 : cstr_(
116 allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr)
117 , index_(allocate)
118{
119}
120
122 : cstr_(
123 other.index_ != noDuplication && other.cstr_ != 0
124 ? valueAllocator()->makeMemberName(other.cstr_)
125 : other.cstr_)
126 , index_(
127 other.cstr_
128 ? (other.index_ == noDuplication ? noDuplication : duplicate)
129 : other.index_)
130{
131}
132
134{
135 if (cstr_ && index_ == duplicate)
136 valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
137}
138
139bool
140Value::CZString::operator<(CZString const& other) const
141{
142 if (cstr_ && other.cstr_)
143 return strcmp(cstr_, other.cstr_) < 0;
144
145 return index_ < other.index_;
146}
147
148bool
150{
151 if (cstr_ && other.cstr_)
152 return strcmp(cstr_, other.cstr_) == 0;
153
154 return index_ == other.index_;
155}
156
157int
159{
160 return index_;
161}
162
163char const*
165{
166 return cstr_;
167}
168
169bool
171{
172 return index_ == noDuplication;
173}
174
175// //////////////////////////////////////////////////////////////////
176// //////////////////////////////////////////////////////////////////
177// //////////////////////////////////////////////////////////////////
178// class Value::Value
179// //////////////////////////////////////////////////////////////////
180// //////////////////////////////////////////////////////////////////
181// //////////////////////////////////////////////////////////////////
182
188{
189 switch (type)
190 {
191 case nullValue:
192 break;
193
194 case intValue:
195 case uintValue:
196 value_.int_ = 0;
197 break;
198
199 case realValue:
200 value_.real_ = 0.0;
201 break;
202
203 case stringValue:
204 value_.string_ = 0;
205 break;
206
207 case arrayValue:
208 case objectValue:
209 value_.map_ = new ObjectValues();
210 break;
211
212 case booleanValue:
213 value_.bool_ = false;
214 break;
215
216 // LCOV_EXCL_START
217 default:
218 UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
219 // LCOV_EXCL_STOP
220 }
221}
222
223Value::Value(Int value) : type_(intValue)
224{
225 value_.int_ = value;
226}
227
229{
230 value_.uint_ = value;
231}
232
233Value::Value(double value) : type_(realValue)
234{
235 value_.real_ = value;
236}
237
238Value::Value(char const* value) : type_(stringValue), allocated_(true)
239{
241}
242
243Value::Value(ripple::Number const& value) : type_(stringValue), allocated_(true)
244{
245 auto const tmp = to_string(value);
247 valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
248}
249
250Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
251{
253 value.c_str(), (unsigned int)value.length());
254}
255
256Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
257{
258 value_.string_ = const_cast<char*>(value.c_str());
259}
260
261Value::Value(bool value) : type_(booleanValue)
262{
263 value_.bool_ = value;
264}
265
266Value::Value(Value const& other) : type_(other.type_)
267{
268 switch (type_)
269 {
270 case nullValue:
271 case intValue:
272 case uintValue:
273 case realValue:
274 case booleanValue:
275 value_ = other.value_;
276 break;
277
278 case stringValue:
279 if (other.value_.string_)
280 {
282 other.value_.string_);
283 allocated_ = true;
284 }
285 else
286 value_.string_ = 0;
287
288 break;
289
290 case arrayValue:
291 case objectValue:
292 value_.map_ = new ObjectValues(*other.value_.map_);
293 break;
294
295 // LCOV_EXCL_START
296 default:
297 UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
298 // LCOV_EXCL_STOP
299 }
300}
301
303{
304 switch (type_)
305 {
306 case nullValue:
307 case intValue:
308 case uintValue:
309 case realValue:
310 case booleanValue:
311 break;
312
313 case stringValue:
314 if (allocated_)
316
317 break;
318
319 case arrayValue:
320 case objectValue:
321 if (value_.map_)
322 delete value_.map_;
323 break;
324
325 // LCOV_EXCL_START
326 default:
327 UNREACHABLE("Json::Value::~Value : invalid type");
328 // LCOV_EXCL_STOP
329 }
330}
331
332Value&
334{
335 Value tmp(other);
336 swap(tmp);
337 return *this;
338}
339
340Value::Value(Value&& other) noexcept
341 : value_(other.value_), type_(other.type_), allocated_(other.allocated_)
342{
343 other.type_ = nullValue;
344 other.allocated_ = 0;
345}
346
347Value&
349{
350 Value tmp(std::move(other));
351 swap(tmp);
352 return *this;
353}
354
355void
356Value::swap(Value& other) noexcept
357{
358 std::swap(value_, other.value_);
359
360 ValueType temp = type_;
361 type_ = other.type_;
362 other.type_ = temp;
363
364 int temp2 = allocated_;
365 allocated_ = other.allocated_;
366 other.allocated_ = temp2;
367}
368
371{
372 return type_;
373}
374
375static int
377{
378 // All negative numbers are less than all unsigned numbers.
379 if (i < 0)
380 return -1;
381
382 // Now we can safely compare.
383 return (i < ui) ? -1 : (i == ui) ? 0 : 1;
384}
385
386bool
387operator<(Value const& x, Value const& y)
388{
389 if (auto signum = x.type_ - y.type_)
390 {
391 if (x.type_ == intValue && y.type_ == uintValue)
392 signum = integerCmp(x.value_.int_, y.value_.uint_);
393 else if (x.type_ == uintValue && y.type_ == intValue)
394 signum = -integerCmp(y.value_.int_, x.value_.uint_);
395 return signum < 0;
396 }
397
398 switch (x.type_)
399 {
400 case nullValue:
401 return false;
402
403 case intValue:
404 return x.value_.int_ < y.value_.int_;
405
406 case uintValue:
407 return x.value_.uint_ < y.value_.uint_;
408
409 case realValue:
410 return x.value_.real_ < y.value_.real_;
411
412 case booleanValue:
413 return x.value_.bool_ < y.value_.bool_;
414
415 case stringValue:
416 return (x.value_.string_ == 0 && y.value_.string_) ||
417 (y.value_.string_ && x.value_.string_ &&
418 strcmp(x.value_.string_, y.value_.string_) < 0);
419
420 case arrayValue:
421 case objectValue: {
422 if (int signum = int(x.value_.map_->size()) - y.value_.map_->size())
423 return signum < 0;
424
425 return *x.value_.map_ < *y.value_.map_;
426 }
427
428 // LCOV_EXCL_START
429 default:
430 UNREACHABLE("Json::operator<(Value, Value) : invalid type");
431 // LCOV_EXCL_STOP
432 }
433
434 return 0; // unreachable
435}
436
437bool
438operator==(Value const& x, Value const& y)
439{
440 if (x.type_ != y.type_)
441 {
442 if (x.type_ == intValue && y.type_ == uintValue)
443 return !integerCmp(x.value_.int_, y.value_.uint_);
444 if (x.type_ == uintValue && y.type_ == intValue)
445 return !integerCmp(y.value_.int_, x.value_.uint_);
446 return false;
447 }
448
449 switch (x.type_)
450 {
451 case nullValue:
452 return true;
453
454 case intValue:
455 return x.value_.int_ == y.value_.int_;
456
457 case uintValue:
458 return x.value_.uint_ == y.value_.uint_;
459
460 case realValue:
461 return x.value_.real_ == y.value_.real_;
462
463 case booleanValue:
464 return x.value_.bool_ == y.value_.bool_;
465
466 case stringValue:
467 return x.value_.string_ == y.value_.string_ ||
468 (y.value_.string_ && x.value_.string_ &&
469 !strcmp(x.value_.string_, y.value_.string_));
470
471 case arrayValue:
472 case objectValue:
473 return x.value_.map_->size() == y.value_.map_->size() &&
474 *x.value_.map_ == *y.value_.map_;
475
476 // LCOV_EXCL_START
477 default:
478 UNREACHABLE("Json::operator==(Value, Value) : invalid type");
479 // LCOV_EXCL_STOP
480 }
481
482 return 0; // unreachable
483}
484
485char const*
487{
488 XRPL_ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
489 return value_.string_;
490}
491
494{
495 switch (type_)
496 {
497 case nullValue:
498 return "";
499
500 case stringValue:
501 return value_.string_ ? value_.string_ : "";
502
503 case booleanValue:
504 return value_.bool_ ? "true" : "false";
505
506 case intValue:
507 return std::to_string(value_.int_);
508
509 case uintValue:
511
512 case realValue:
514
515 case arrayValue:
516 case objectValue:
517 JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
518
519 // LCOV_EXCL_START
520 default:
521 UNREACHABLE("Json::Value::asString : invalid type");
522 // LCOV_EXCL_STOP
523 }
524
525 return ""; // unreachable
526}
527
530{
531 switch (type_)
532 {
533 case nullValue:
534 return 0;
535
536 case intValue:
537 return value_.int_;
538
539 case uintValue:
540 JSON_ASSERT_MESSAGE(
541 value_.uint_ < (unsigned)maxInt,
542 "integer out of signed integer range");
543 return value_.uint_;
544
545 case realValue:
546 JSON_ASSERT_MESSAGE(
548 "Real out of signed integer range");
549 return Int(value_.real_);
550
551 case booleanValue:
552 return value_.bool_ ? 1 : 0;
553
554 case stringValue: {
555 char const* const str{value_.string_ ? value_.string_ : ""};
556 return beast::lexicalCastThrow<int>(str);
557 }
558
559 case arrayValue:
560 case objectValue:
561 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
562
563 // LCOV_EXCL_START
564 default:
565 UNREACHABLE("Json::Value::asInt : invalid type");
566 // LCOV_EXCL_STOP
567 }
568
569 return 0; // unreachable;
570}
571
574{
575 switch (type_)
576 {
577 case nullValue:
578 return 0;
579
580 case intValue:
581 JSON_ASSERT_MESSAGE(
582 value_.int_ >= 0,
583 "Negative integer can not be converted to unsigned integer");
584 return value_.int_;
585
586 case uintValue:
587 return value_.uint_;
588
589 case realValue:
590 JSON_ASSERT_MESSAGE(
591 value_.real_ >= 0 && value_.real_ <= maxUInt,
592 "Real out of unsigned integer range");
593 return UInt(value_.real_);
594
595 case booleanValue:
596 return value_.bool_ ? 1 : 0;
597
598 case stringValue: {
599 char const* const str{value_.string_ ? value_.string_ : ""};
600 return beast::lexicalCastThrow<unsigned int>(str);
601 }
602
603 case arrayValue:
604 case objectValue:
605 JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
606
607 // LCOV_EXCL_START
608 default:
609 UNREACHABLE("Json::Value::asUInt : invalid type");
610 // LCOV_EXCL_STOP
611 }
612
613 return 0; // unreachable;
614}
615
616double
618{
619 switch (type_)
620 {
621 case nullValue:
622 return 0.0;
623
624 case intValue:
625 return value_.int_;
626
627 case uintValue:
628 return value_.uint_;
629
630 case realValue:
631 return value_.real_;
632
633 case booleanValue:
634 return value_.bool_ ? 1.0 : 0.0;
635
636 case stringValue:
637 case arrayValue:
638 case objectValue:
639 JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
640
641 // LCOV_EXCL_START
642 default:
643 UNREACHABLE("Json::Value::asDouble : invalid type");
644 // LCOV_EXCL_STOP
645 }
646
647 return 0; // unreachable;
648}
649
650bool
652{
653 switch (type_)
654 {
655 case nullValue:
656 return false;
657
658 case intValue:
659 case uintValue:
660 return value_.int_ != 0;
661
662 case realValue:
663 return value_.real_ != 0.0;
664
665 case booleanValue:
666 return value_.bool_;
667
668 case stringValue:
669 return value_.string_ && value_.string_[0] != 0;
670
671 case arrayValue:
672 case objectValue:
673 return value_.map_->size() != 0;
674
675 // LCOV_EXCL_START
676 default:
677 UNREACHABLE("Json::Value::asBool : invalid type");
678 // LCOV_EXCL_STOP
679 }
680
681 return false; // unreachable;
682}
683
684bool
686{
687 switch (type_)
688 {
689 case nullValue:
690 return true;
691
692 case intValue:
693 return (other == nullValue && value_.int_ == 0) ||
694 other == intValue || (other == uintValue && value_.int_ >= 0) ||
695 other == realValue || other == stringValue ||
696 other == booleanValue;
697
698 case uintValue:
699 return (other == nullValue && value_.uint_ == 0) ||
700 (other == intValue && value_.uint_ <= (unsigned)maxInt) ||
701 other == uintValue || other == realValue ||
702 other == stringValue || other == booleanValue;
703
704 case realValue:
705 return (other == nullValue && value_.real_ == 0.0) ||
706 (other == intValue && value_.real_ >= minInt &&
707 value_.real_ <= maxInt) ||
708 (other == uintValue && value_.real_ >= 0 &&
709 value_.real_ <= maxUInt &&
710 std::fabs(round(value_.real_) - value_.real_) <
712 other == realValue || other == stringValue ||
713 other == booleanValue;
714
715 case booleanValue:
716 return (other == nullValue && value_.bool_ == false) ||
717 other == intValue || other == uintValue || other == realValue ||
718 other == stringValue || other == booleanValue;
719
720 case stringValue:
721 return other == stringValue ||
722 (other == nullValue &&
723 (!value_.string_ || value_.string_[0] == 0));
724
725 case arrayValue:
726 return other == arrayValue ||
727 (other == nullValue && value_.map_->size() == 0);
728
729 case objectValue:
730 return other == objectValue ||
731 (other == nullValue && value_.map_->size() == 0);
732
733 // LCOV_EXCL_START
734 default:
735 UNREACHABLE("Json::Value::isConvertible : invalid type");
736 // LCOV_EXCL_STOP
737 }
738
739 return false; // unreachable;
740}
741
745{
746 switch (type_)
747 {
748 case nullValue:
749 case intValue:
750 case uintValue:
751 case realValue:
752 case booleanValue:
753 case stringValue:
754 return 0;
755
756 case arrayValue: // size of the array is highest index + 1
757 if (!value_.map_->empty())
758 {
759 ObjectValues::const_iterator itLast = value_.map_->end();
760 --itLast;
761 return (*itLast).first.index() + 1;
762 }
763
764 return 0;
765
766 case objectValue:
767 return Int(value_.map_->size());
768
769 // LCOV_EXCL_START
770 default:
771 UNREACHABLE("Json::Value::size : invalid type");
772 // LCOV_EXCL_STOP
773 }
774
775 return 0; // unreachable;
776}
777
778Value::operator bool() const
779{
780 if (isNull())
781 return false;
782
783 if (isString())
784 {
785 auto s = asCString();
786 return s && s[0];
787 }
788
789 return !(isArray() || isObject()) || size();
790}
791
792void
794{
795 XRPL_ASSERT(
797 "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(
816 "Json::Value::operator[](UInt) : valid type");
817
818 if (type_ == nullValue)
819 *this = Value(arrayValue);
820
821 CZString key(index);
822 ObjectValues::iterator it = value_.map_->lower_bound(key);
823
824 if (it != value_.map_->end() && (*it).first == key)
825 return (*it).second;
826
827 ObjectValues::value_type defaultValue(key, null);
828 it = value_.map_->insert(it, defaultValue);
829 return (*it).second;
830}
831
832Value const&
834{
835 XRPL_ASSERT(
837 "Json::Value::operator[](UInt) const : valid type");
838
839 if (type_ == nullValue)
840 return null;
841
842 CZString key(index);
843 ObjectValues::const_iterator it = value_.map_->find(key);
844
845 if (it == value_.map_->end())
846 return null;
847
848 return (*it).second;
849}
850
851Value&
852Value::operator[](char const* key)
853{
854 return resolveReference(key, false);
855}
856
857Value&
858Value::resolveReference(char const* key, bool isStatic)
859{
860 XRPL_ASSERT(
862 "Json::Value::resolveReference : valid type");
863
864 if (type_ == nullValue)
865 *this = Value(objectValue);
866
867 CZString actualKey(
869 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
870
871 if (it != value_.map_->end() && (*it).first == actualKey)
872 return (*it).second;
873
874 ObjectValues::value_type defaultValue(actualKey, null);
875 it = value_.map_->insert(it, defaultValue);
876 Value& value = (*it).second;
877 return value;
878}
879
880Value
881Value::get(UInt index, Value const& defaultValue) const
882{
883 Value const* value = &((*this)[index]);
884 return value == &null ? defaultValue : *value;
885}
886
887bool
889{
890 return index < size();
891}
892
893Value const&
894Value::operator[](char const* key) const
895{
896 XRPL_ASSERT(
898 "Json::Value::operator[](const char*) const : valid type");
899
900 if (type_ == nullValue)
901 return null;
902
903 CZString actualKey(key, CZString::noDuplication);
904 ObjectValues::const_iterator it = value_.map_->find(actualKey);
905
906 if (it == value_.map_->end())
907 return null;
908
909 return (*it).second;
910}
911
912Value&
914{
915 return (*this)[key.c_str()];
916}
917
918Value const&
920{
921 return (*this)[key.c_str()];
922}
923
924Value&
926{
927 return resolveReference(key, true);
928}
929
930Value const&
932{
933 return (*this)[key.c_str()];
934}
935
936Value&
937Value::append(Value const& value)
938{
939 return (*this)[size()] = value;
940}
941
942Value&
944{
945 return (*this)[size()] = std::move(value);
946}
947
948Value
949Value::get(char const* key, Value const& defaultValue) const
950{
951 Value const* value = &((*this)[key]);
952 return value == &null ? defaultValue : *value;
953}
954
955Value
956Value::get(std::string const& key, Value const& defaultValue) const
957{
958 return get(key.c_str(), defaultValue);
959}
960
961Value
962Value::removeMember(char const* key)
963{
964 XRPL_ASSERT(
966 "Json::Value::removeMember : valid type");
967
968 if (type_ == nullValue)
969 return null;
970
971 CZString actualKey(key, CZString::noDuplication);
972 ObjectValues::iterator it = value_.map_->find(actualKey);
973
974 if (it == value_.map_->end())
975 return null;
976
977 Value old(it->second);
978 value_.map_->erase(it);
979 return old;
980}
981
982Value
984{
985 return removeMember(key.c_str());
986}
987
988bool
989Value::isMember(char const* key) const
990{
991 if (type_ != objectValue)
992 return false;
993
994 Value const* value = &((*this)[key]);
995 return value != &null;
996}
997
998bool
1000{
1001 return isMember(key.c_str());
1002}
1003
1006{
1007 XRPL_ASSERT(
1009 "Json::Value::getMemberNames : valid type");
1010
1011 if (type_ == nullValue)
1012 return Value::Members();
1013
1014 Members members;
1015 members.reserve(value_.map_->size());
1016 ObjectValues::const_iterator it = value_.map_->begin();
1017 ObjectValues::const_iterator itEnd = value_.map_->end();
1018
1019 for (; it != itEnd; ++it)
1020 members.push_back(std::string((*it).first.c_str()));
1021
1022 return members;
1023}
1024
1025bool
1027{
1028 return type_ == nullValue;
1029}
1030
1031bool
1033{
1034 return type_ == booleanValue;
1035}
1036
1037bool
1039{
1040 return type_ == intValue;
1041}
1042
1043bool
1045{
1046 return type_ == uintValue;
1047}
1048
1049bool
1051{
1052 return type_ == intValue || type_ == uintValue || type_ == booleanValue;
1053}
1054
1055bool
1057{
1058 return type_ == realValue;
1059}
1060
1061bool
1063{
1064 return isIntegral() || isDouble();
1065}
1066
1067bool
1069{
1070 return type_ == stringValue;
1071}
1072
1073bool
1075{
1076 return type_ == arrayValue;
1077}
1078
1079bool
1081{
1082 return type_ == nullValue || type_ == arrayValue;
1083}
1084
1085bool
1087{
1088 return type_ == objectValue;
1089}
1090
1091bool
1093{
1094 return type_ == nullValue || type_ == objectValue;
1095}
1096
1099{
1100 StyledWriter writer;
1101 return writer.write(*this);
1102}
1103
1106{
1107 switch (type_)
1108 {
1109 case arrayValue:
1110 case objectValue:
1111 if (value_.map_)
1112 return const_iterator(value_.map_->begin());
1113
1114 break;
1115 default:
1116 break;
1117 }
1118
1119 return const_iterator();
1120}
1121
1124{
1125 switch (type_)
1126 {
1127 case arrayValue:
1128 case objectValue:
1129 if (value_.map_)
1130 return const_iterator(value_.map_->end());
1131
1132 break;
1133 default:
1134 break;
1135 }
1136
1137 return const_iterator();
1138}
1139
1142{
1143 switch (type_)
1144 {
1145 case arrayValue:
1146 case objectValue:
1147 if (value_.map_)
1148 return iterator(value_.map_->begin());
1149 break;
1150 default:
1151 break;
1152 }
1153
1154 return iterator();
1155}
1156
1159{
1160 switch (type_)
1161 {
1162 case arrayValue:
1163 case objectValue:
1164 if (value_.map_)
1165 return iterator(value_.map_->end());
1166 break;
1167 default:
1168 break;
1169 }
1170
1171 return iterator();
1172}
1173
1174} // 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:63
constexpr char const * c_str() const
Definition json_value.h:76
Writes a Value in JSON format in a human friendly way.
Definition json_writer.h:91
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:488
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:573
Iterator for object and array value.
Definition json_value.h:634
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:149
const_iterator begin() const
Json::UInt UInt
Definition json_value.h:156
bool isArray() const
static Int const minInt
Definition json_value.h:161
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:160
bool isDouble() const
static UInt const maxUInt
Definition json_value.h:163
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:154
ValueConstIterator const_iterator
Definition json_value.h:155
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:153
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:157
bool isValidIndex(UInt index) const
Return true if index < size().
std::string asString() const
Returns the unquoted string value.
bool isBool() const
bool isIntegral() const
bool asBool() const
ValueType type_
Definition json_value.h:439
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.
std::map< CZString, Value > ObjectValues
Definition json_value.h:197
static Int const maxInt
Definition json_value.h:162
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 ).
bool isInt() const
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:25
std::string to_string(Value const &)
Writes a Json::Value to an std::string.
Definition to_string.cpp:28
static struct Json::DummyValueAllocatorInitializer dummyValueAllocatorInitializer
ValueType
Type of the value held by a Value object.
Definition json_value.h:37
@ booleanValue
bool value
Definition json_value.h:43
@ nullValue
'null' value
Definition json_value.h:38
@ stringValue
UTF-8 string value.
Definition json_value.h:42
@ realValue
double value
Definition json_value.h:41
@ arrayValue
array value (ordered list)
Definition json_value.h:44
@ intValue
signed integer value
Definition json_value.h:39
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:45
@ uintValue
unsigned integer value
Definition json_value.h:40
bool operator<(Value const &, Value const &)
bool operator==(StaticString x, StaticString y)
Definition json_value.h:86
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)