Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmjsoncpp/src/lib_json/json_value.cpp
3158 views
1
// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
2
// Distributed under MIT license, or public domain if desired and
3
// recognized in your jurisdiction.
4
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
6
#if !defined(JSON_IS_AMALGAMATION)
7
#include <json/assertions.h>
8
#include <json/value.h>
9
#include <json/writer.h>
10
#endif // if !defined(JSON_IS_AMALGAMATION)
11
#include <algorithm>
12
#include <cassert>
13
#include <cmath>
14
#include <cstddef>
15
#include <cstring>
16
#include <iostream>
17
#include <sstream>
18
#include <utility>
19
20
// Provide implementation equivalent of std::snprintf for older _MSC compilers
21
#if defined(_MSC_VER) && _MSC_VER < 1900
22
#include <stdarg.h>
23
static int msvc_pre1900_c99_vsnprintf(char* outBuf, size_t size,
24
const char* format, va_list ap) {
25
int count = -1;
26
if (size != 0)
27
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
28
if (count == -1)
29
count = _vscprintf(format, ap);
30
return count;
31
}
32
33
int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
34
const char* format, ...) {
35
va_list ap;
36
va_start(ap, format);
37
const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap);
38
va_end(ap);
39
return count;
40
}
41
#endif
42
43
// Disable warning C4702 : unreachable code
44
#if defined(_MSC_VER)
45
#pragma warning(disable : 4702)
46
#endif
47
48
#define JSON_ASSERT_UNREACHABLE assert(false)
49
50
namespace Json {
51
template <typename T>
52
static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) {
53
std::unique_ptr<T> r;
54
if (p) {
55
r = std::unique_ptr<T>(new T(*p));
56
}
57
return r;
58
}
59
60
// This is a walkaround to avoid the static initialization of Value::null.
61
// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
62
// 8 (instead of 4) as a bit of future-proofing.
63
#if defined(__ARMEL__)
64
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
65
#else
66
#define ALIGNAS(byte_alignment)
67
#endif
68
69
// static
70
Value const& Value::nullSingleton() {
71
static Value const nullStatic;
72
return nullStatic;
73
}
74
75
#if JSON_USE_NULLREF
76
// for backwards compatibility, we'll leave these global references around, but
77
// DO NOT use them in JSONCPP library code any more!
78
// static
79
Value const& Value::null = Value::nullSingleton();
80
81
// static
82
Value const& Value::nullRef = Value::nullSingleton();
83
#endif
84
85
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
86
template <typename T, typename U>
87
static inline bool InRange(double d, T min, U max) {
88
// The casts can lose precision, but we are looking only for
89
// an approximate range. Might fail on edge cases though. ~cdunn
90
return d >= static_cast<double>(min) && d <= static_cast<double>(max);
91
}
92
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
93
static inline double integerToDouble(Json::UInt64 value) {
94
return static_cast<double>(Int64(value / 2)) * 2.0 +
95
static_cast<double>(Int64(value & 1));
96
}
97
98
template <typename T> static inline double integerToDouble(T value) {
99
return static_cast<double>(value);
100
}
101
102
template <typename T, typename U>
103
static inline bool InRange(double d, T min, U max) {
104
return d >= integerToDouble(min) && d <= integerToDouble(max);
105
}
106
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
107
108
/** Duplicates the specified string value.
109
* @param value Pointer to the string to duplicate. Must be zero-terminated if
110
* length is "unknown".
111
* @param length Length of the value. if equals to unknown, then it will be
112
* computed using strlen(value).
113
* @return Pointer on the duplicate instance of string.
114
*/
115
static inline char* duplicateStringValue(const char* value, size_t length) {
116
// Avoid an integer overflow in the call to malloc below by limiting length
117
// to a sane value.
118
if (length >= static_cast<size_t>(Value::maxInt))
119
length = Value::maxInt - 1;
120
121
auto newString = static_cast<char*>(malloc(length + 1));
122
if (newString == nullptr) {
123
throwRuntimeError("in Json::Value::duplicateStringValue(): "
124
"Failed to allocate string value buffer");
125
}
126
memcpy(newString, value, length);
127
newString[length] = 0;
128
return newString;
129
}
130
131
/* Record the length as a prefix.
132
*/
133
static inline char* duplicateAndPrefixStringValue(const char* value,
134
unsigned int length) {
135
// Avoid an integer overflow in the call to malloc below by limiting length
136
// to a sane value.
137
JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) -
138
sizeof(unsigned) - 1U,
139
"in Json::Value::duplicateAndPrefixStringValue(): "
140
"length too big for prefixing");
141
size_t actualLength = sizeof(length) + length + 1;
142
auto newString = static_cast<char*>(malloc(actualLength));
143
if (newString == nullptr) {
144
throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): "
145
"Failed to allocate string value buffer");
146
}
147
*reinterpret_cast<unsigned*>(newString) = length;
148
memcpy(newString + sizeof(unsigned), value, length);
149
newString[actualLength - 1U] =
150
0; // to avoid buffer over-run accidents by users later
151
return newString;
152
}
153
inline static void decodePrefixedString(bool isPrefixed, char const* prefixed,
154
unsigned* length, char const** value) {
155
if (!isPrefixed) {
156
*length = static_cast<unsigned>(strlen(prefixed));
157
*value = prefixed;
158
} else {
159
*length = *reinterpret_cast<unsigned const*>(prefixed);
160
*value = prefixed + sizeof(unsigned);
161
}
162
}
163
/** Free the string duplicated by
164
* duplicateStringValue()/duplicateAndPrefixStringValue().
165
*/
166
#if JSONCPP_USING_SECURE_MEMORY
167
static inline void releasePrefixedStringValue(char* value) {
168
unsigned length = 0;
169
char const* valueDecoded;
170
decodePrefixedString(true, value, &length, &valueDecoded);
171
size_t const size = sizeof(unsigned) + length + 1U;
172
memset(value, 0, size);
173
free(value);
174
}
175
static inline void releaseStringValue(char* value, unsigned length) {
176
// length==0 => we allocated the strings memory
177
size_t size = (length == 0) ? strlen(value) : length;
178
memset(value, 0, size);
179
free(value);
180
}
181
#else // !JSONCPP_USING_SECURE_MEMORY
182
static inline void releasePrefixedStringValue(char* value) { free(value); }
183
static inline void releaseStringValue(char* value, unsigned) { free(value); }
184
#endif // JSONCPP_USING_SECURE_MEMORY
185
186
} // namespace Json
187
188
// //////////////////////////////////////////////////////////////////
189
// //////////////////////////////////////////////////////////////////
190
// //////////////////////////////////////////////////////////////////
191
// ValueInternals...
192
// //////////////////////////////////////////////////////////////////
193
// //////////////////////////////////////////////////////////////////
194
// //////////////////////////////////////////////////////////////////
195
#if !defined(JSON_IS_AMALGAMATION)
196
197
#include "json_valueiterator.inl"
198
#endif // if !defined(JSON_IS_AMALGAMATION)
199
200
namespace Json {
201
202
#if JSON_USE_EXCEPTION
203
Exception::Exception(String msg) : msg_(std::move(msg)) {}
204
Exception::~Exception() noexcept = default;
205
char const* Exception::what() const noexcept { return msg_.c_str(); }
206
RuntimeError::RuntimeError(String const& msg) : Exception(msg) {}
207
LogicError::LogicError(String const& msg) : Exception(msg) {}
208
JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
209
throw RuntimeError(msg);
210
}
211
JSONCPP_NORETURN void throwLogicError(String const& msg) {
212
throw LogicError(msg);
213
}
214
#else // !JSON_USE_EXCEPTION
215
JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
216
std::cerr << msg << std::endl;
217
abort();
218
}
219
JSONCPP_NORETURN void throwLogicError(String const& msg) {
220
std::cerr << msg << std::endl;
221
abort();
222
}
223
#endif
224
225
// //////////////////////////////////////////////////////////////////
226
// //////////////////////////////////////////////////////////////////
227
// //////////////////////////////////////////////////////////////////
228
// class Value::CZString
229
// //////////////////////////////////////////////////////////////////
230
// //////////////////////////////////////////////////////////////////
231
// //////////////////////////////////////////////////////////////////
232
233
// Notes: policy_ indicates if the string was allocated when
234
// a string is stored.
235
236
Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {}
237
238
Value::CZString::CZString(char const* str, unsigned length,
239
DuplicationPolicy allocate)
240
: cstr_(str) {
241
// allocate != duplicate
242
storage_.policy_ = allocate & 0x3;
243
storage_.length_ = length & 0x3FFFFFFF;
244
}
245
246
Value::CZString::CZString(const CZString& other) {
247
cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr
248
? duplicateStringValue(other.cstr_, other.storage_.length_)
249
: other.cstr_);
250
storage_.policy_ =
251
static_cast<unsigned>(
252
other.cstr_
253
? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
254
noDuplication
255
? noDuplication
256
: duplicate)
257
: static_cast<DuplicationPolicy>(other.storage_.policy_)) &
258
3U;
259
storage_.length_ = other.storage_.length_;
260
}
261
262
Value::CZString::CZString(CZString&& other) noexcept
263
: cstr_(other.cstr_), index_(other.index_) {
264
other.cstr_ = nullptr;
265
}
266
267
Value::CZString::~CZString() {
268
if (cstr_ && storage_.policy_ == duplicate) {
269
releaseStringValue(const_cast<char*>(cstr_),
270
storage_.length_ + 1U); // +1 for null terminating
271
// character for sake of
272
// completeness but not actually
273
// necessary
274
}
275
}
276
277
void Value::CZString::swap(CZString& other) {
278
std::swap(cstr_, other.cstr_);
279
std::swap(index_, other.index_);
280
}
281
282
Value::CZString& Value::CZString::operator=(const CZString& other) {
283
cstr_ = other.cstr_;
284
index_ = other.index_;
285
return *this;
286
}
287
288
Value::CZString& Value::CZString::operator=(CZString&& other) noexcept {
289
cstr_ = other.cstr_;
290
index_ = other.index_;
291
other.cstr_ = nullptr;
292
return *this;
293
}
294
295
bool Value::CZString::operator<(const CZString& other) const {
296
if (!cstr_)
297
return index_ < other.index_;
298
// return strcmp(cstr_, other.cstr_) < 0;
299
// Assume both are strings.
300
unsigned this_len = this->storage_.length_;
301
unsigned other_len = other.storage_.length_;
302
unsigned min_len = std::min<unsigned>(this_len, other_len);
303
JSON_ASSERT(this->cstr_ && other.cstr_);
304
int comp = memcmp(this->cstr_, other.cstr_, min_len);
305
if (comp < 0)
306
return true;
307
if (comp > 0)
308
return false;
309
return (this_len < other_len);
310
}
311
312
bool Value::CZString::operator==(const CZString& other) const {
313
if (!cstr_)
314
return index_ == other.index_;
315
// return strcmp(cstr_, other.cstr_) == 0;
316
// Assume both are strings.
317
unsigned this_len = this->storage_.length_;
318
unsigned other_len = other.storage_.length_;
319
if (this_len != other_len)
320
return false;
321
JSON_ASSERT(this->cstr_ && other.cstr_);
322
int comp = memcmp(this->cstr_, other.cstr_, this_len);
323
return comp == 0;
324
}
325
326
ArrayIndex Value::CZString::index() const { return index_; }
327
328
// const char* Value::CZString::c_str() const { return cstr_; }
329
const char* Value::CZString::data() const { return cstr_; }
330
unsigned Value::CZString::length() const { return storage_.length_; }
331
bool Value::CZString::isStaticString() const {
332
return storage_.policy_ == noDuplication;
333
}
334
335
// //////////////////////////////////////////////////////////////////
336
// //////////////////////////////////////////////////////////////////
337
// //////////////////////////////////////////////////////////////////
338
// class Value::Value
339
// //////////////////////////////////////////////////////////////////
340
// //////////////////////////////////////////////////////////////////
341
// //////////////////////////////////////////////////////////////////
342
343
/*! internal Default constructor initialization must be equivalent to:
344
* memset( this, 0, sizeof(Value) )
345
* This optimization is used in ValueInternalMap fast allocator.
346
*/
347
Value::Value(ValueType type) {
348
static char const emptyString[] = "";
349
initBasic(type);
350
switch (type) {
351
case nullValue:
352
break;
353
case intValue:
354
case uintValue:
355
value_.int_ = 0;
356
break;
357
case realValue:
358
value_.real_ = 0.0;
359
break;
360
case stringValue:
361
// allocated_ == false, so this is safe.
362
value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
363
break;
364
case arrayValue:
365
case objectValue:
366
value_.map_ = new ObjectValues();
367
break;
368
case booleanValue:
369
value_.bool_ = false;
370
break;
371
default:
372
JSON_ASSERT_UNREACHABLE;
373
}
374
}
375
376
Value::Value(Int value) {
377
initBasic(intValue);
378
value_.int_ = value;
379
}
380
381
Value::Value(UInt value) {
382
initBasic(uintValue);
383
value_.uint_ = value;
384
}
385
#if defined(JSON_HAS_INT64)
386
Value::Value(Int64 value) {
387
initBasic(intValue);
388
value_.int_ = value;
389
}
390
Value::Value(UInt64 value) {
391
initBasic(uintValue);
392
value_.uint_ = value;
393
}
394
#endif // defined(JSON_HAS_INT64)
395
396
Value::Value(double value) {
397
initBasic(realValue);
398
value_.real_ = value;
399
}
400
401
Value::Value(const char* value) {
402
initBasic(stringValue, true);
403
JSON_ASSERT_MESSAGE(value != nullptr,
404
"Null Value Passed to Value Constructor");
405
value_.string_ = duplicateAndPrefixStringValue(
406
value, static_cast<unsigned>(strlen(value)));
407
}
408
409
Value::Value(const char* begin, const char* end) {
410
initBasic(stringValue, true);
411
value_.string_ =
412
duplicateAndPrefixStringValue(begin, static_cast<unsigned>(end - begin));
413
}
414
415
Value::Value(const String& value) {
416
initBasic(stringValue, true);
417
value_.string_ = duplicateAndPrefixStringValue(
418
value.data(), static_cast<unsigned>(value.length()));
419
}
420
421
Value::Value(const StaticString& value) {
422
initBasic(stringValue);
423
value_.string_ = const_cast<char*>(value.c_str());
424
}
425
426
Value::Value(bool value) {
427
initBasic(booleanValue);
428
value_.bool_ = value;
429
}
430
431
Value::Value(const Value& other) {
432
dupPayload(other);
433
dupMeta(other);
434
}
435
436
Value::Value(Value&& other) noexcept {
437
initBasic(nullValue);
438
swap(other);
439
}
440
441
Value::~Value() {
442
releasePayload();
443
value_.uint_ = 0;
444
}
445
446
Value& Value::operator=(const Value& other) {
447
Value(other).swap(*this);
448
return *this;
449
}
450
451
Value& Value::operator=(Value&& other) noexcept {
452
other.swap(*this);
453
return *this;
454
}
455
456
void Value::swapPayload(Value& other) {
457
std::swap(bits_, other.bits_);
458
std::swap(value_, other.value_);
459
}
460
461
void Value::copyPayload(const Value& other) {
462
releasePayload();
463
dupPayload(other);
464
}
465
466
void Value::swap(Value& other) {
467
swapPayload(other);
468
std::swap(comments_, other.comments_);
469
std::swap(start_, other.start_);
470
std::swap(limit_, other.limit_);
471
}
472
473
void Value::copy(const Value& other) {
474
copyPayload(other);
475
dupMeta(other);
476
}
477
478
ValueType Value::type() const {
479
return static_cast<ValueType>(bits_.value_type_);
480
}
481
482
int Value::compare(const Value& other) const {
483
if (*this < other)
484
return -1;
485
if (*this > other)
486
return 1;
487
return 0;
488
}
489
490
bool Value::operator<(const Value& other) const {
491
int typeDelta = type() - other.type();
492
if (typeDelta)
493
return typeDelta < 0;
494
switch (type()) {
495
case nullValue:
496
return false;
497
case intValue:
498
return value_.int_ < other.value_.int_;
499
case uintValue:
500
return value_.uint_ < other.value_.uint_;
501
case realValue:
502
return value_.real_ < other.value_.real_;
503
case booleanValue:
504
return value_.bool_ < other.value_.bool_;
505
case stringValue: {
506
if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
507
return other.value_.string_ != nullptr;
508
}
509
unsigned this_len;
510
unsigned other_len;
511
char const* this_str;
512
char const* other_str;
513
decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
514
&this_str);
515
decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
516
&other_str);
517
unsigned min_len = std::min<unsigned>(this_len, other_len);
518
JSON_ASSERT(this_str && other_str);
519
int comp = memcmp(this_str, other_str, min_len);
520
if (comp < 0)
521
return true;
522
if (comp > 0)
523
return false;
524
return (this_len < other_len);
525
}
526
case arrayValue:
527
case objectValue: {
528
auto thisSize = value_.map_->size();
529
auto otherSize = other.value_.map_->size();
530
if (thisSize != otherSize)
531
return thisSize < otherSize;
532
return (*value_.map_) < (*other.value_.map_);
533
}
534
default:
535
JSON_ASSERT_UNREACHABLE;
536
}
537
return false; // unreachable
538
}
539
540
bool Value::operator<=(const Value& other) const { return !(other < *this); }
541
542
bool Value::operator>=(const Value& other) const { return !(*this < other); }
543
544
bool Value::operator>(const Value& other) const { return other < *this; }
545
546
bool Value::operator==(const Value& other) const {
547
if (type() != other.type())
548
return false;
549
switch (type()) {
550
case nullValue:
551
return true;
552
case intValue:
553
return value_.int_ == other.value_.int_;
554
case uintValue:
555
return value_.uint_ == other.value_.uint_;
556
case realValue:
557
return value_.real_ == other.value_.real_;
558
case booleanValue:
559
return value_.bool_ == other.value_.bool_;
560
case stringValue: {
561
if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
562
return (value_.string_ == other.value_.string_);
563
}
564
unsigned this_len;
565
unsigned other_len;
566
char const* this_str;
567
char const* other_str;
568
decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
569
&this_str);
570
decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
571
&other_str);
572
if (this_len != other_len)
573
return false;
574
JSON_ASSERT(this_str && other_str);
575
int comp = memcmp(this_str, other_str, this_len);
576
return comp == 0;
577
}
578
case arrayValue:
579
case objectValue:
580
return value_.map_->size() == other.value_.map_->size() &&
581
(*value_.map_) == (*other.value_.map_);
582
default:
583
JSON_ASSERT_UNREACHABLE;
584
}
585
return false; // unreachable
586
}
587
588
bool Value::operator!=(const Value& other) const { return !(*this == other); }
589
590
const char* Value::asCString() const {
591
JSON_ASSERT_MESSAGE(type() == stringValue,
592
"in Json::Value::asCString(): requires stringValue");
593
if (value_.string_ == nullptr)
594
return nullptr;
595
unsigned this_len;
596
char const* this_str;
597
decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
598
&this_str);
599
return this_str;
600
}
601
602
#if JSONCPP_USING_SECURE_MEMORY
603
unsigned Value::getCStringLength() const {
604
JSON_ASSERT_MESSAGE(type() == stringValue,
605
"in Json::Value::asCString(): requires stringValue");
606
if (value_.string_ == 0)
607
return 0;
608
unsigned this_len;
609
char const* this_str;
610
decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
611
&this_str);
612
return this_len;
613
}
614
#endif
615
616
bool Value::getString(char const** begin, char const** end) const {
617
if (type() != stringValue)
618
return false;
619
if (value_.string_ == nullptr)
620
return false;
621
unsigned length;
622
decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
623
begin);
624
*end = *begin + length;
625
return true;
626
}
627
628
String Value::asString() const {
629
switch (type()) {
630
case nullValue:
631
return "";
632
case stringValue: {
633
if (value_.string_ == nullptr)
634
return "";
635
unsigned this_len;
636
char const* this_str;
637
decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
638
&this_str);
639
return String(this_str, this_len);
640
}
641
case booleanValue:
642
return value_.bool_ ? "true" : "false";
643
case intValue:
644
return valueToString(value_.int_);
645
case uintValue:
646
return valueToString(value_.uint_);
647
case realValue:
648
return valueToString(value_.real_);
649
default:
650
JSON_FAIL_MESSAGE("Type is not convertible to string");
651
}
652
}
653
654
Value::Int Value::asInt() const {
655
switch (type()) {
656
case intValue:
657
JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
658
return Int(value_.int_);
659
case uintValue:
660
JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
661
return Int(value_.uint_);
662
case realValue:
663
JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
664
"double out of Int range");
665
return Int(value_.real_);
666
case nullValue:
667
return 0;
668
case booleanValue:
669
return value_.bool_ ? 1 : 0;
670
default:
671
break;
672
}
673
JSON_FAIL_MESSAGE("Value is not convertible to Int.");
674
}
675
676
Value::UInt Value::asUInt() const {
677
switch (type()) {
678
case intValue:
679
JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
680
return UInt(value_.int_);
681
case uintValue:
682
JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
683
return UInt(value_.uint_);
684
case realValue:
685
JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
686
"double out of UInt range");
687
return UInt(value_.real_);
688
case nullValue:
689
return 0;
690
case booleanValue:
691
return value_.bool_ ? 1 : 0;
692
default:
693
break;
694
}
695
JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
696
}
697
698
#if defined(JSON_HAS_INT64)
699
700
Value::Int64 Value::asInt64() const {
701
switch (type()) {
702
case intValue:
703
return Int64(value_.int_);
704
case uintValue:
705
JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
706
return Int64(value_.uint_);
707
case realValue:
708
JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
709
"double out of Int64 range");
710
return Int64(value_.real_);
711
case nullValue:
712
return 0;
713
case booleanValue:
714
return value_.bool_ ? 1 : 0;
715
default:
716
break;
717
}
718
JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
719
}
720
721
Value::UInt64 Value::asUInt64() const {
722
switch (type()) {
723
case intValue:
724
JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
725
return UInt64(value_.int_);
726
case uintValue:
727
return UInt64(value_.uint_);
728
case realValue:
729
JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
730
"double out of UInt64 range");
731
return UInt64(value_.real_);
732
case nullValue:
733
return 0;
734
case booleanValue:
735
return value_.bool_ ? 1 : 0;
736
default:
737
break;
738
}
739
JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
740
}
741
#endif // if defined(JSON_HAS_INT64)
742
743
LargestInt Value::asLargestInt() const {
744
#if defined(JSON_NO_INT64)
745
return asInt();
746
#else
747
return asInt64();
748
#endif
749
}
750
751
LargestUInt Value::asLargestUInt() const {
752
#if defined(JSON_NO_INT64)
753
return asUInt();
754
#else
755
return asUInt64();
756
#endif
757
}
758
759
double Value::asDouble() const {
760
switch (type()) {
761
case intValue:
762
return static_cast<double>(value_.int_);
763
case uintValue:
764
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
765
return static_cast<double>(value_.uint_);
766
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
767
return integerToDouble(value_.uint_);
768
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
769
case realValue:
770
return value_.real_;
771
case nullValue:
772
return 0.0;
773
case booleanValue:
774
return value_.bool_ ? 1.0 : 0.0;
775
default:
776
break;
777
}
778
JSON_FAIL_MESSAGE("Value is not convertible to double.");
779
}
780
781
float Value::asFloat() const {
782
switch (type()) {
783
case intValue:
784
return static_cast<float>(value_.int_);
785
case uintValue:
786
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
787
return static_cast<float>(value_.uint_);
788
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
789
// This can fail (silently?) if the value is bigger than MAX_FLOAT.
790
return static_cast<float>(integerToDouble(value_.uint_));
791
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
792
case realValue:
793
return static_cast<float>(value_.real_);
794
case nullValue:
795
return 0.0;
796
case booleanValue:
797
return value_.bool_ ? 1.0F : 0.0F;
798
default:
799
break;
800
}
801
JSON_FAIL_MESSAGE("Value is not convertible to float.");
802
}
803
804
bool Value::asBool() const {
805
switch (type()) {
806
case booleanValue:
807
return value_.bool_;
808
case nullValue:
809
return false;
810
case intValue:
811
return value_.int_ != 0;
812
case uintValue:
813
return value_.uint_ != 0;
814
case realValue: {
815
// According to JavaScript language zero or NaN is regarded as false
816
const auto value_classification = std::fpclassify(value_.real_);
817
return value_classification != FP_ZERO && value_classification != FP_NAN;
818
}
819
default:
820
break;
821
}
822
JSON_FAIL_MESSAGE("Value is not convertible to bool.");
823
}
824
825
bool Value::isConvertibleTo(ValueType other) const {
826
switch (other) {
827
case nullValue:
828
return (isNumeric() && asDouble() == 0.0) ||
829
(type() == booleanValue && !value_.bool_) ||
830
(type() == stringValue && asString().empty()) ||
831
(type() == arrayValue && value_.map_->empty()) ||
832
(type() == objectValue && value_.map_->empty()) ||
833
type() == nullValue;
834
case intValue:
835
return isInt() ||
836
(type() == realValue && InRange(value_.real_, minInt, maxInt)) ||
837
type() == booleanValue || type() == nullValue;
838
case uintValue:
839
return isUInt() ||
840
(type() == realValue && InRange(value_.real_, 0, maxUInt)) ||
841
type() == booleanValue || type() == nullValue;
842
case realValue:
843
return isNumeric() || type() == booleanValue || type() == nullValue;
844
case booleanValue:
845
return isNumeric() || type() == booleanValue || type() == nullValue;
846
case stringValue:
847
return isNumeric() || type() == booleanValue || type() == stringValue ||
848
type() == nullValue;
849
case arrayValue:
850
return type() == arrayValue || type() == nullValue;
851
case objectValue:
852
return type() == objectValue || type() == nullValue;
853
}
854
JSON_ASSERT_UNREACHABLE;
855
return false;
856
}
857
858
/// Number of values in array or object
859
ArrayIndex Value::size() const {
860
switch (type()) {
861
case nullValue:
862
case intValue:
863
case uintValue:
864
case realValue:
865
case booleanValue:
866
case stringValue:
867
return 0;
868
case arrayValue: // size of the array is highest index + 1
869
if (!value_.map_->empty()) {
870
ObjectValues::const_iterator itLast = value_.map_->end();
871
--itLast;
872
return (*itLast).first.index() + 1;
873
}
874
return 0;
875
case objectValue:
876
return ArrayIndex(value_.map_->size());
877
}
878
JSON_ASSERT_UNREACHABLE;
879
return 0; // unreachable;
880
}
881
882
bool Value::empty() const {
883
if (isNull() || isArray() || isObject())
884
return size() == 0U;
885
return false;
886
}
887
888
Value::operator bool() const { return !isNull(); }
889
890
void Value::clear() {
891
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue ||
892
type() == objectValue,
893
"in Json::Value::clear(): requires complex value");
894
start_ = 0;
895
limit_ = 0;
896
switch (type()) {
897
case arrayValue:
898
case objectValue:
899
value_.map_->clear();
900
break;
901
default:
902
break;
903
}
904
}
905
906
void Value::resize(ArrayIndex newSize) {
907
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
908
"in Json::Value::resize(): requires arrayValue");
909
if (type() == nullValue)
910
*this = Value(arrayValue);
911
ArrayIndex oldSize = size();
912
if (newSize == 0)
913
clear();
914
else if (newSize > oldSize)
915
for (ArrayIndex i = oldSize; i < newSize; ++i)
916
(*this)[i];
917
else {
918
for (ArrayIndex index = newSize; index < oldSize; ++index) {
919
value_.map_->erase(index);
920
}
921
JSON_ASSERT(size() == newSize);
922
}
923
}
924
925
Value& Value::operator[](ArrayIndex index) {
926
JSON_ASSERT_MESSAGE(
927
type() == nullValue || type() == arrayValue,
928
"in Json::Value::operator[](ArrayIndex): requires arrayValue");
929
if (type() == nullValue)
930
*this = Value(arrayValue);
931
CZString key(index);
932
auto it = value_.map_->lower_bound(key);
933
if (it != value_.map_->end() && (*it).first == key)
934
return (*it).second;
935
936
ObjectValues::value_type defaultValue(key, nullSingleton());
937
it = value_.map_->insert(it, defaultValue);
938
return (*it).second;
939
}
940
941
Value& Value::operator[](int index) {
942
JSON_ASSERT_MESSAGE(
943
index >= 0,
944
"in Json::Value::operator[](int index): index cannot be negative");
945
return (*this)[ArrayIndex(index)];
946
}
947
948
const Value& Value::operator[](ArrayIndex index) const {
949
JSON_ASSERT_MESSAGE(
950
type() == nullValue || type() == arrayValue,
951
"in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
952
if (type() == nullValue)
953
return nullSingleton();
954
CZString key(index);
955
ObjectValues::const_iterator it = value_.map_->find(key);
956
if (it == value_.map_->end())
957
return nullSingleton();
958
return (*it).second;
959
}
960
961
const Value& Value::operator[](int index) const {
962
JSON_ASSERT_MESSAGE(
963
index >= 0,
964
"in Json::Value::operator[](int index) const: index cannot be negative");
965
return (*this)[ArrayIndex(index)];
966
}
967
968
void Value::initBasic(ValueType type, bool allocated) {
969
setType(type);
970
setIsAllocated(allocated);
971
comments_ = Comments{};
972
start_ = 0;
973
limit_ = 0;
974
}
975
976
void Value::dupPayload(const Value& other) {
977
setType(other.type());
978
setIsAllocated(false);
979
switch (type()) {
980
case nullValue:
981
case intValue:
982
case uintValue:
983
case realValue:
984
case booleanValue:
985
value_ = other.value_;
986
break;
987
case stringValue:
988
if (other.value_.string_ && other.isAllocated()) {
989
unsigned len;
990
char const* str;
991
decodePrefixedString(other.isAllocated(), other.value_.string_, &len,
992
&str);
993
value_.string_ = duplicateAndPrefixStringValue(str, len);
994
setIsAllocated(true);
995
} else {
996
value_.string_ = other.value_.string_;
997
}
998
break;
999
case arrayValue:
1000
case objectValue:
1001
value_.map_ = new ObjectValues(*other.value_.map_);
1002
break;
1003
default:
1004
JSON_ASSERT_UNREACHABLE;
1005
}
1006
}
1007
1008
void Value::releasePayload() {
1009
switch (type()) {
1010
case nullValue:
1011
case intValue:
1012
case uintValue:
1013
case realValue:
1014
case booleanValue:
1015
break;
1016
case stringValue:
1017
if (isAllocated())
1018
releasePrefixedStringValue(value_.string_);
1019
break;
1020
case arrayValue:
1021
case objectValue:
1022
delete value_.map_;
1023
break;
1024
default:
1025
JSON_ASSERT_UNREACHABLE;
1026
}
1027
}
1028
1029
void Value::dupMeta(const Value& other) {
1030
comments_ = other.comments_;
1031
start_ = other.start_;
1032
limit_ = other.limit_;
1033
}
1034
1035
// Access an object value by name, create a null member if it does not exist.
1036
// @pre Type of '*this' is object or null.
1037
// @param key is null-terminated.
1038
Value& Value::resolveReference(const char* key) {
1039
JSON_ASSERT_MESSAGE(
1040
type() == nullValue || type() == objectValue,
1041
"in Json::Value::resolveReference(): requires objectValue");
1042
if (type() == nullValue)
1043
*this = Value(objectValue);
1044
CZString actualKey(key, static_cast<unsigned>(strlen(key)),
1045
CZString::noDuplication); // NOTE!
1046
auto it = value_.map_->lower_bound(actualKey);
1047
if (it != value_.map_->end() && (*it).first == actualKey)
1048
return (*it).second;
1049
1050
ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1051
it = value_.map_->insert(it, defaultValue);
1052
Value& value = (*it).second;
1053
return value;
1054
}
1055
1056
// @param key is not null-terminated.
1057
Value& Value::resolveReference(char const* key, char const* end) {
1058
JSON_ASSERT_MESSAGE(
1059
type() == nullValue || type() == objectValue,
1060
"in Json::Value::resolveReference(key, end): requires objectValue");
1061
if (type() == nullValue)
1062
*this = Value(objectValue);
1063
CZString actualKey(key, static_cast<unsigned>(end - key),
1064
CZString::duplicateOnCopy);
1065
auto it = value_.map_->lower_bound(actualKey);
1066
if (it != value_.map_->end() && (*it).first == actualKey)
1067
return (*it).second;
1068
1069
ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1070
it = value_.map_->insert(it, defaultValue);
1071
Value& value = (*it).second;
1072
return value;
1073
}
1074
1075
Value Value::get(ArrayIndex index, const Value& defaultValue) const {
1076
const Value* value = &((*this)[index]);
1077
return value == &nullSingleton() ? defaultValue : *value;
1078
}
1079
1080
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
1081
1082
Value const* Value::find(char const* begin, char const* end) const {
1083
JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1084
"in Json::Value::find(begin, end): requires "
1085
"objectValue or nullValue");
1086
if (type() == nullValue)
1087
return nullptr;
1088
CZString actualKey(begin, static_cast<unsigned>(end - begin),
1089
CZString::noDuplication);
1090
ObjectValues::const_iterator it = value_.map_->find(actualKey);
1091
if (it == value_.map_->end())
1092
return nullptr;
1093
return &(*it).second;
1094
}
1095
Value const* Value::find(const String& key) const {
1096
return find(key.data(), key.data() + key.length());
1097
}
1098
Value* Value::demand(char const* begin, char const* end) {
1099
JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1100
"in Json::Value::demand(begin, end): requires "
1101
"objectValue or nullValue");
1102
return &resolveReference(begin, end);
1103
}
1104
const Value& Value::operator[](const char* key) const {
1105
Value const* found = find(key, key + strlen(key));
1106
if (!found)
1107
return nullSingleton();
1108
return *found;
1109
}
1110
Value const& Value::operator[](const String& key) const {
1111
Value const* found = find(key);
1112
if (!found)
1113
return nullSingleton();
1114
return *found;
1115
}
1116
1117
Value& Value::operator[](const char* key) {
1118
return resolveReference(key, key + strlen(key));
1119
}
1120
1121
Value& Value::operator[](const String& key) {
1122
return resolveReference(key.data(), key.data() + key.length());
1123
}
1124
1125
Value& Value::operator[](const StaticString& key) {
1126
return resolveReference(key.c_str());
1127
}
1128
1129
Value& Value::append(const Value& value) { return append(Value(value)); }
1130
1131
Value& Value::append(Value&& value) {
1132
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
1133
"in Json::Value::append: requires arrayValue");
1134
if (type() == nullValue) {
1135
*this = Value(arrayValue);
1136
}
1137
return this->value_.map_->emplace(size(), std::move(value)).first->second;
1138
}
1139
1140
bool Value::insert(ArrayIndex index, const Value& newValue) {
1141
return insert(index, Value(newValue));
1142
}
1143
1144
bool Value::insert(ArrayIndex index, Value&& newValue) {
1145
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
1146
"in Json::Value::insert: requires arrayValue");
1147
ArrayIndex length = size();
1148
if (index > length) {
1149
return false;
1150
}
1151
for (ArrayIndex i = length; i > index; i--) {
1152
(*this)[i] = std::move((*this)[i - 1]);
1153
}
1154
(*this)[index] = std::move(newValue);
1155
return true;
1156
}
1157
1158
Value Value::get(char const* begin, char const* end,
1159
Value const& defaultValue) const {
1160
Value const* found = find(begin, end);
1161
return !found ? defaultValue : *found;
1162
}
1163
Value Value::get(char const* key, Value const& defaultValue) const {
1164
return get(key, key + strlen(key), defaultValue);
1165
}
1166
Value Value::get(String const& key, Value const& defaultValue) const {
1167
return get(key.data(), key.data() + key.length(), defaultValue);
1168
}
1169
1170
bool Value::removeMember(const char* begin, const char* end, Value* removed) {
1171
if (type() != objectValue) {
1172
return false;
1173
}
1174
CZString actualKey(begin, static_cast<unsigned>(end - begin),
1175
CZString::noDuplication);
1176
auto it = value_.map_->find(actualKey);
1177
if (it == value_.map_->end())
1178
return false;
1179
if (removed)
1180
*removed = std::move(it->second);
1181
value_.map_->erase(it);
1182
return true;
1183
}
1184
bool Value::removeMember(const char* key, Value* removed) {
1185
return removeMember(key, key + strlen(key), removed);
1186
}
1187
bool Value::removeMember(String const& key, Value* removed) {
1188
return removeMember(key.data(), key.data() + key.length(), removed);
1189
}
1190
void Value::removeMember(const char* key) {
1191
JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1192
"in Json::Value::removeMember(): requires objectValue");
1193
if (type() == nullValue)
1194
return;
1195
1196
CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
1197
value_.map_->erase(actualKey);
1198
}
1199
void Value::removeMember(const String& key) { removeMember(key.c_str()); }
1200
1201
bool Value::removeIndex(ArrayIndex index, Value* removed) {
1202
if (type() != arrayValue) {
1203
return false;
1204
}
1205
CZString key(index);
1206
auto it = value_.map_->find(key);
1207
if (it == value_.map_->end()) {
1208
return false;
1209
}
1210
if (removed)
1211
*removed = std::move(it->second);
1212
ArrayIndex oldSize = size();
1213
// shift left all items left, into the place of the "removed"
1214
for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
1215
CZString keey(i);
1216
(*value_.map_)[keey] = (*this)[i + 1];
1217
}
1218
// erase the last one ("leftover")
1219
CZString keyLast(oldSize - 1);
1220
auto itLast = value_.map_->find(keyLast);
1221
value_.map_->erase(itLast);
1222
return true;
1223
}
1224
1225
bool Value::isMember(char const* begin, char const* end) const {
1226
Value const* value = find(begin, end);
1227
return nullptr != value;
1228
}
1229
bool Value::isMember(char const* key) const {
1230
return isMember(key, key + strlen(key));
1231
}
1232
bool Value::isMember(String const& key) const {
1233
return isMember(key.data(), key.data() + key.length());
1234
}
1235
1236
Value::Members Value::getMemberNames() const {
1237
JSON_ASSERT_MESSAGE(
1238
type() == nullValue || type() == objectValue,
1239
"in Json::Value::getMemberNames(), value must be objectValue");
1240
if (type() == nullValue)
1241
return Value::Members();
1242
Members members;
1243
members.reserve(value_.map_->size());
1244
ObjectValues::const_iterator it = value_.map_->begin();
1245
ObjectValues::const_iterator itEnd = value_.map_->end();
1246
for (; it != itEnd; ++it) {
1247
members.push_back(String((*it).first.data(), (*it).first.length()));
1248
}
1249
return members;
1250
}
1251
1252
static bool IsIntegral(double d) {
1253
double integral_part;
1254
return modf(d, &integral_part) == 0.0;
1255
}
1256
1257
bool Value::isNull() const { return type() == nullValue; }
1258
1259
bool Value::isBool() const { return type() == booleanValue; }
1260
1261
bool Value::isInt() const {
1262
switch (type()) {
1263
case intValue:
1264
#if defined(JSON_HAS_INT64)
1265
return value_.int_ >= minInt && value_.int_ <= maxInt;
1266
#else
1267
return true;
1268
#endif
1269
case uintValue:
1270
return value_.uint_ <= UInt(maxInt);
1271
case realValue:
1272
return value_.real_ >= minInt && value_.real_ <= maxInt &&
1273
IsIntegral(value_.real_);
1274
default:
1275
break;
1276
}
1277
return false;
1278
}
1279
1280
bool Value::isUInt() const {
1281
switch (type()) {
1282
case intValue:
1283
#if defined(JSON_HAS_INT64)
1284
return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
1285
#else
1286
return value_.int_ >= 0;
1287
#endif
1288
case uintValue:
1289
#if defined(JSON_HAS_INT64)
1290
return value_.uint_ <= maxUInt;
1291
#else
1292
return true;
1293
#endif
1294
case realValue:
1295
return value_.real_ >= 0 && value_.real_ <= maxUInt &&
1296
IsIntegral(value_.real_);
1297
default:
1298
break;
1299
}
1300
return false;
1301
}
1302
1303
bool Value::isInt64() const {
1304
#if defined(JSON_HAS_INT64)
1305
switch (type()) {
1306
case intValue:
1307
return true;
1308
case uintValue:
1309
return value_.uint_ <= UInt64(maxInt64);
1310
case realValue:
1311
// Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
1312
// double, so double(maxInt64) will be rounded up to 2^63. Therefore we
1313
// require the value to be strictly less than the limit.
1314
return value_.real_ >= double(minInt64) &&
1315
value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
1316
default:
1317
break;
1318
}
1319
#endif // JSON_HAS_INT64
1320
return false;
1321
}
1322
1323
bool Value::isUInt64() const {
1324
#if defined(JSON_HAS_INT64)
1325
switch (type()) {
1326
case intValue:
1327
return value_.int_ >= 0;
1328
case uintValue:
1329
return true;
1330
case realValue:
1331
// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1332
// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1333
// require the value to be strictly less than the limit.
1334
return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
1335
IsIntegral(value_.real_);
1336
default:
1337
break;
1338
}
1339
#endif // JSON_HAS_INT64
1340
return false;
1341
}
1342
1343
bool Value::isIntegral() const {
1344
switch (type()) {
1345
case intValue:
1346
case uintValue:
1347
return true;
1348
case realValue:
1349
#if defined(JSON_HAS_INT64)
1350
// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1351
// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1352
// require the value to be strictly less than the limit.
1353
return value_.real_ >= double(minInt64) &&
1354
value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
1355
#else
1356
return value_.real_ >= minInt && value_.real_ <= maxUInt &&
1357
IsIntegral(value_.real_);
1358
#endif // JSON_HAS_INT64
1359
default:
1360
break;
1361
}
1362
return false;
1363
}
1364
1365
bool Value::isDouble() const {
1366
return type() == intValue || type() == uintValue || type() == realValue;
1367
}
1368
1369
bool Value::isNumeric() const { return isDouble(); }
1370
1371
bool Value::isString() const { return type() == stringValue; }
1372
1373
bool Value::isArray() const { return type() == arrayValue; }
1374
1375
bool Value::isObject() const { return type() == objectValue; }
1376
1377
Value::Comments::Comments(const Comments& that)
1378
: ptr_{cloneUnique(that.ptr_)} {}
1379
1380
Value::Comments::Comments(Comments&& that) noexcept
1381
: ptr_{std::move(that.ptr_)} {}
1382
1383
Value::Comments& Value::Comments::operator=(const Comments& that) {
1384
ptr_ = cloneUnique(that.ptr_);
1385
return *this;
1386
}
1387
1388
Value::Comments& Value::Comments::operator=(Comments&& that) noexcept {
1389
ptr_ = std::move(that.ptr_);
1390
return *this;
1391
}
1392
1393
bool Value::Comments::has(CommentPlacement slot) const {
1394
return ptr_ && !(*ptr_)[slot].empty();
1395
}
1396
1397
String Value::Comments::get(CommentPlacement slot) const {
1398
if (!ptr_)
1399
return {};
1400
return (*ptr_)[slot];
1401
}
1402
1403
void Value::Comments::set(CommentPlacement slot, String comment) {
1404
if (slot >= CommentPlacement::numberOfCommentPlacement)
1405
return;
1406
if (!ptr_)
1407
ptr_ = std::unique_ptr<Array>(new Array());
1408
(*ptr_)[slot] = std::move(comment);
1409
}
1410
1411
void Value::setComment(String comment, CommentPlacement placement) {
1412
if (!comment.empty() && (comment.back() == '\n')) {
1413
// Always discard trailing newline, to aid indentation.
1414
comment.pop_back();
1415
}
1416
JSON_ASSERT_MESSAGE(
1417
comment.empty() || comment[0] == '/',
1418
"in Json::Value::setComment(): Comments must start with /");
1419
comments_.set(placement, std::move(comment));
1420
}
1421
1422
bool Value::hasComment(CommentPlacement placement) const {
1423
return comments_.has(placement);
1424
}
1425
1426
String Value::getComment(CommentPlacement placement) const {
1427
return comments_.get(placement);
1428
}
1429
1430
void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
1431
1432
void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
1433
1434
ptrdiff_t Value::getOffsetStart() const { return start_; }
1435
1436
ptrdiff_t Value::getOffsetLimit() const { return limit_; }
1437
1438
String Value::toStyledString() const {
1439
StreamWriterBuilder builder;
1440
1441
String out = this->hasComment(commentBefore) ? "\n" : "";
1442
out += Json::writeString(builder, *this);
1443
out += '\n';
1444
1445
return out;
1446
}
1447
1448
Value::const_iterator Value::begin() const {
1449
switch (type()) {
1450
case arrayValue:
1451
case objectValue:
1452
if (value_.map_)
1453
return const_iterator(value_.map_->begin());
1454
break;
1455
default:
1456
break;
1457
}
1458
return {};
1459
}
1460
1461
Value::const_iterator Value::end() const {
1462
switch (type()) {
1463
case arrayValue:
1464
case objectValue:
1465
if (value_.map_)
1466
return const_iterator(value_.map_->end());
1467
break;
1468
default:
1469
break;
1470
}
1471
return {};
1472
}
1473
1474
Value::iterator Value::begin() {
1475
switch (type()) {
1476
case arrayValue:
1477
case objectValue:
1478
if (value_.map_)
1479
return iterator(value_.map_->begin());
1480
break;
1481
default:
1482
break;
1483
}
1484
return iterator();
1485
}
1486
1487
Value::iterator Value::end() {
1488
switch (type()) {
1489
case arrayValue:
1490
case objectValue:
1491
if (value_.map_)
1492
return iterator(value_.map_->end());
1493
break;
1494
default:
1495
break;
1496
}
1497
return iterator();
1498
}
1499
1500
// class PathArgument
1501
// //////////////////////////////////////////////////////////////////
1502
1503
PathArgument::PathArgument() = default;
1504
1505
PathArgument::PathArgument(ArrayIndex index)
1506
: index_(index), kind_(kindIndex) {}
1507
1508
PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {}
1509
1510
PathArgument::PathArgument(String key) : key_(std::move(key)), kind_(kindKey) {}
1511
1512
// class Path
1513
// //////////////////////////////////////////////////////////////////
1514
1515
Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2,
1516
const PathArgument& a3, const PathArgument& a4,
1517
const PathArgument& a5) {
1518
InArgs in;
1519
in.reserve(5);
1520
in.push_back(&a1);
1521
in.push_back(&a2);
1522
in.push_back(&a3);
1523
in.push_back(&a4);
1524
in.push_back(&a5);
1525
makePath(path, in);
1526
}
1527
1528
void Path::makePath(const String& path, const InArgs& in) {
1529
const char* current = path.c_str();
1530
const char* end = current + path.length();
1531
auto itInArg = in.begin();
1532
while (current != end) {
1533
if (*current == '[') {
1534
++current;
1535
if (*current == '%')
1536
addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1537
else {
1538
ArrayIndex index = 0;
1539
for (; current != end && *current >= '0' && *current <= '9'; ++current)
1540
index = index * 10 + ArrayIndex(*current - '0');
1541
args_.push_back(index);
1542
}
1543
if (current == end || *++current != ']')
1544
invalidPath(path, int(current - path.c_str()));
1545
} else if (*current == '%') {
1546
addPathInArg(path, in, itInArg, PathArgument::kindKey);
1547
++current;
1548
} else if (*current == '.' || *current == ']') {
1549
++current;
1550
} else {
1551
const char* beginName = current;
1552
while (current != end && !strchr("[.", *current))
1553
++current;
1554
args_.push_back(String(beginName, current));
1555
}
1556
}
1557
}
1558
1559
void Path::addPathInArg(const String& /*path*/, const InArgs& in,
1560
InArgs::const_iterator& itInArg,
1561
PathArgument::Kind kind) {
1562
if (itInArg == in.end()) {
1563
// Error: missing argument %d
1564
} else if ((*itInArg)->kind_ != kind) {
1565
// Error: bad argument type
1566
} else {
1567
args_.push_back(**itInArg++);
1568
}
1569
}
1570
1571
void Path::invalidPath(const String& /*path*/, int /*location*/) {
1572
// Error: invalid path.
1573
}
1574
1575
const Value& Path::resolve(const Value& root) const {
1576
const Value* node = &root;
1577
for (const auto& arg : args_) {
1578
if (arg.kind_ == PathArgument::kindIndex) {
1579
if (!node->isArray() || !node->isValidIndex(arg.index_)) {
1580
// Error: unable to resolve path (array value expected at position... )
1581
return Value::nullSingleton();
1582
}
1583
node = &((*node)[arg.index_]);
1584
} else if (arg.kind_ == PathArgument::kindKey) {
1585
if (!node->isObject()) {
1586
// Error: unable to resolve path (object value expected at position...)
1587
return Value::nullSingleton();
1588
}
1589
node = &((*node)[arg.key_]);
1590
if (node == &Value::nullSingleton()) {
1591
// Error: unable to resolve path (object has no member named '' at
1592
// position...)
1593
return Value::nullSingleton();
1594
}
1595
}
1596
}
1597
return *node;
1598
}
1599
1600
Value Path::resolve(const Value& root, const Value& defaultValue) const {
1601
const Value* node = &root;
1602
for (const auto& arg : args_) {
1603
if (arg.kind_ == PathArgument::kindIndex) {
1604
if (!node->isArray() || !node->isValidIndex(arg.index_))
1605
return defaultValue;
1606
node = &((*node)[arg.index_]);
1607
} else if (arg.kind_ == PathArgument::kindKey) {
1608
if (!node->isObject())
1609
return defaultValue;
1610
node = &((*node)[arg.key_]);
1611
if (node == &Value::nullSingleton())
1612
return defaultValue;
1613
}
1614
}
1615
return *node;
1616
}
1617
1618
Value& Path::make(Value& root) const {
1619
Value* node = &root;
1620
for (const auto& arg : args_) {
1621
if (arg.kind_ == PathArgument::kindIndex) {
1622
if (!node->isArray()) {
1623
// Error: node is not an array at position ...
1624
}
1625
node = &((*node)[arg.index_]);
1626
} else if (arg.kind_ == PathArgument::kindKey) {
1627
if (!node->isObject()) {
1628
// Error: node is not an object at position...
1629
}
1630
node = &((*node)[arg.key_]);
1631
}
1632
}
1633
return *node;
1634
}
1635
1636
} // namespace Json
1637
1638