• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

open-source-parsers / jsoncpp / 10784343976

10 Sep 2024 01:53AM CUT coverage: 95.536%. Remained the same
10784343976

push

github

web-flow
Merge 69d629daf into 62f7f3efe

5307 of 5555 relevant lines covered (95.54%)

11962.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.92
/src/lib_json/json_value.cpp
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) {
251,621✔
53
  std::unique_ptr<T> r;
251,621✔
54
  if (p) {
251,621✔
55
    r = std::unique_ptr<T>(new T(*p));
6✔
56
  }
57
  return r;
251,621✔
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() {
126,657✔
71
  static Value const nullStatic;
126,657✔
72
  return nullStatic;
126,657✔
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 +
21✔
95
         static_cast<double>(Int64(value & 1));
21✔
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);
47✔
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) {
28,639✔
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));
28,639✔
122
  if (newString == nullptr) {
28,639✔
123
    throwRuntimeError("in Json::Value::duplicateStringValue(): "
×
124
                      "Failed to allocate string value buffer");
125
  }
126
  memcpy(newString, value, length);
127
  newString[length] = 0;
28,639✔
128
  return newString;
28,639✔
129
}
130

131
/* Record the length as a prefix.
132
 */
133
static inline char* duplicateAndPrefixStringValue(const char* value,
2,417✔
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) -
2,417✔
138
                                    sizeof(unsigned) - 1U,
139
                      "in Json::Value::duplicateAndPrefixStringValue(): "
140
                      "length too big for prefixing");
141
  size_t actualLength = sizeof(length) + length + 1;
2,417✔
142
  auto newString = static_cast<char*>(malloc(actualLength));
2,417✔
143
  if (newString == nullptr) {
2,417✔
144
    throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): "
×
145
                      "Failed to allocate string value buffer");
146
  }
147
  *reinterpret_cast<unsigned*>(newString) = length;
2,417✔
148
  memcpy(newString + sizeof(unsigned), value, length);
2,417✔
149
  newString[actualLength - 1U] =
2,417✔
150
      0; // to avoid buffer over-run accidents by users later
151
  return newString;
2,417✔
152
}
153
inline static void decodePrefixedString(bool isPrefixed, char const* prefixed,
154
                                        unsigned* length, char const** value) {
155
  if (!isPrefixed) {
4,015✔
156
    *length = static_cast<unsigned>(strlen(prefixed));
3✔
157
    *value = prefixed;
×
158
  } else {
159
    *length = *reinterpret_cast<unsigned const*>(prefixed);
4,137✔
160
    *value = prefixed + sizeof(unsigned);
4,012✔
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); }
2,417✔
183
static inline void releaseStringValue(char* value, unsigned) { free(value); }
28,639✔
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)) {}
48✔
204
Exception::~Exception() noexcept = default;
192✔
205
char const* Exception::what() const noexcept { return msg_.c_str(); }
6✔
206
RuntimeError::RuntimeError(String const& msg) : Exception(msg) {}
16✔
207
LogicError::LogicError(String const& msg) : Exception(msg) {}
80✔
208
JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
8✔
209
  throw RuntimeError(msg);
8✔
210
}
211
JSONCPP_NORETURN void throwLogicError(String const& msg) {
40✔
212
  throw LogicError(msg);
40✔
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) {}
269,527✔
237

238
Value::CZString::CZString(char const* str, unsigned length,
35,566✔
239
                          DuplicationPolicy allocate)
35,566✔
240
    : cstr_(str) {
35,566✔
241
  // allocate != duplicate
242
  storage_.policy_ = allocate & 0x3;
35,566✔
243
  storage_.length_ = length & 0x3FFFFFFF;
35,566✔
244
}
35,566✔
245

246
Value::CZString::CZString(const CZString& other) {
251,338✔
247
  cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr
186,119✔
248
               ? duplicateStringValue(other.cstr_, other.storage_.length_)
437,457✔
249
               : other.cstr_);
250
  storage_.policy_ =
251,338✔
251
      static_cast<unsigned>(
252
          other.cstr_
251,338✔
253
              ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
28,642✔
254
                         noDuplication
255
                     ? noDuplication
28,642✔
256
                     : duplicate)
257
              : static_cast<DuplicationPolicy>(other.storage_.policy_)) &
251,338✔
258
      3U;
259
  storage_.length_ = other.storage_.length_;
251,338✔
260
}
251,338✔
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() {
556,431✔
268
  if (cstr_ && storage_.policy_ == duplicate) {
556,431✔
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
}
556,431✔
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 {
3,937,225✔
296
  if (!cstr_)
3,937,225✔
297
    return index_ < other.index_;
3,782,636✔
298
  // return strcmp(cstr_, other.cstr_) < 0;
299
  // Assume both are strings.
300
  unsigned this_len = this->storage_.length_;
154,589✔
301
  unsigned other_len = other.storage_.length_;
154,589✔
302
  unsigned min_len = std::min<unsigned>(this_len, other_len);
154,589✔
303
  JSON_ASSERT(this->cstr_ && other.cstr_);
154,589✔
304
  int comp = memcmp(this->cstr_, other.cstr_, min_len);
154,589✔
305
  if (comp < 0)
154,589✔
306
    return true;
307
  if (comp > 0)
79,097✔
308
    return false;
309
  return (this_len < other_len);
40,021✔
310
}
311

312
bool Value::CZString::operator==(const CZString& other) const {
119,629✔
313
  if (!cstr_)
119,629✔
314
    return index_ == other.index_;
104,928✔
315
  // return strcmp(cstr_, other.cstr_) == 0;
316
  // Assume both are strings.
317
  unsigned this_len = this->storage_.length_;
14,701✔
318
  unsigned other_len = other.storage_.length_;
14,701✔
319
  if (this_len != other_len)
14,701✔
320
    return false;
321
  JSON_ASSERT(this->cstr_ && other.cstr_);
5,278✔
322
  int comp = memcmp(this->cstr_, other.cstr_, this_len);
5,278✔
323
  return comp == 0;
5,278✔
324
}
325

326
ArrayIndex Value::CZString::index() const { return index_; }
717✔
327

328
// const char* Value::CZString::c_str() const { return cstr_; }
329
const char* Value::CZString::data() const { return cstr_; }
1,727✔
330
unsigned Value::CZString::length() const { return storage_.length_; }
1,711✔
331
bool Value::CZString::isStaticString() const {
3✔
332
  return storage_.policy_ == noDuplication;
3✔
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) {
118,372✔
348
  static char const emptyString[] = "";
349
  initBasic(type);
118,372✔
350
  switch (type) {
118,372✔
351
  case nullValue:
352
    break;
353
  case intValue:
2✔
354
  case uintValue:
355
    value_.int_ = 0;
2✔
356
    break;
2✔
357
  case realValue:
1✔
358
    value_.real_ = 0.0;
1✔
359
    break;
1✔
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:
8,913✔
365
  case objectValue:
366
    value_.map_ = new ObjectValues();
8,913✔
367
    break;
8,913✔
368
  case booleanValue:
×
369
    value_.bool_ = false;
×
370
    break;
×
371
  default:
×
372
    JSON_ASSERT_UNREACHABLE;
×
373
  }
374
}
118,372✔
375

376
Value::Value(Int value) {
1,381✔
377
  initBasic(intValue);
1,381✔
378
  value_.int_ = value;
1,381✔
379
}
1,381✔
380

381
Value::Value(UInt value) {
177✔
382
  initBasic(uintValue);
177✔
383
  value_.uint_ = value;
177✔
384
}
177✔
385
#if defined(JSON_HAS_INT64)
386
Value::Value(Int64 value) {
105,067✔
387
  initBasic(intValue);
105,067✔
388
  value_.int_ = value;
105,067✔
389
}
105,067✔
390
Value::Value(UInt64 value) {
89✔
391
  initBasic(uintValue);
89✔
392
  value_.uint_ = value;
89✔
393
}
89✔
394
#endif // defined(JSON_HAS_INT64)
395

396
Value::Value(double value) {
473✔
397
  initBasic(realValue);
473✔
398
  value_.real_ = value;
473✔
399
}
473✔
400

401
Value::Value(const char* value) {
1,029✔
402
  initBasic(stringValue, true);
1,029✔
403
  JSON_ASSERT_MESSAGE(value != nullptr,
1,029✔
404
                      "Null Value Passed to Value Constructor");
405
  value_.string_ = duplicateAndPrefixStringValue(
2,058✔
406
      value, static_cast<unsigned>(strlen(value)));
1,029✔
407
}
1,029✔
408

409
Value::Value(const char* begin, const char* end) {
2✔
410
  initBasic(stringValue, true);
2✔
411
  value_.string_ =
2✔
412
      duplicateAndPrefixStringValue(begin, static_cast<unsigned>(end - begin));
2✔
413
}
2✔
414

415
Value::Value(const String& value) {
1,258✔
416
  initBasic(stringValue, true);
1,258✔
417
  value_.string_ = duplicateAndPrefixStringValue(
1,258✔
418
      value.data(), static_cast<unsigned>(value.length()));
419
}
1,258✔
420

421
Value::Value(const StaticString& value) {
2✔
422
  initBasic(stringValue);
2✔
423
  value_.string_ = const_cast<char*>(value.c_str());
2✔
424
}
2✔
425

426
Value::Value(bool value) {
14,497✔
427
  initBasic(booleanValue);
14,497✔
428
  value_.bool_ = value;
14,497✔
429
}
14,497✔
430

431
Value::Value(const Value& other) {
251,613✔
432
  dupPayload(other);
251,613✔
433
  dupMeta(other);
251,613✔
434
}
251,613✔
435

436
Value::Value(Value&& other) noexcept {
50✔
437
  initBasic(nullValue);
50✔
438
  swap(other);
50✔
439
}
50✔
440

441
Value::~Value() {
494,010✔
442
  releasePayload();
494,010✔
443
  value_.uint_ = 0;
494,010✔
444
}
494,010✔
445

446
Value& Value::operator=(const Value& other) {
19✔
447
  Value(other).swap(*this);
19✔
448
  return *this;
19✔
449
}
450

451
Value& Value::operator=(Value&& other) noexcept {
124,074✔
452
  other.swap(*this);
124,074✔
453
  return *this;
124,074✔
454
}
455

456
void Value::swapPayload(Value& other) {
237,920✔
457
  std::swap(bits_, other.bits_);
458
  std::swap(value_, other.value_);
459
}
237,920✔
460

461
void Value::copyPayload(const Value& other) {
8✔
462
  releasePayload();
8✔
463
  dupPayload(other);
8✔
464
}
8✔
465

466
void Value::swap(Value& other) {
124,144✔
467
  swapPayload(other);
124,144✔
468
  std::swap(comments_, other.comments_);
124,144✔
469
  std::swap(start_, other.start_);
470
  std::swap(limit_, other.limit_);
471
}
124,144✔
472

473
void Value::copy(const Value& other) {
8✔
474
  copyPayload(other);
8✔
475
  dupMeta(other);
8✔
476
}
8✔
477

478
ValueType Value::type() const {
2,261,400✔
479
  return static_cast<ValueType>(bits_.value_type_);
2,261,400✔
480
}
481

482
int Value::compare(const Value& other) const {
120✔
483
  if (*this < other)
120✔
484
    return -1;
485
  if (*this > other)
89✔
486
    return 1;
31✔
487
  return 0;
488
}
489

490
bool Value::operator<(const Value& other) const {
1,279✔
491
  int typeDelta = type() - other.type();
1,279✔
492
  if (typeDelta)
1,279✔
493
    return typeDelta < 0;
77✔
494
  switch (type()) {
1,202✔
495
  case nullValue:
496
    return false;
497
  case intValue:
564✔
498
    return value_.int_ < other.value_.int_;
564✔
499
  case uintValue:
34✔
500
    return value_.uint_ < other.value_.uint_;
34✔
501
  case realValue:
46✔
502
    return value_.real_ < other.value_.real_;
46✔
503
  case booleanValue:
35✔
504
    return value_.bool_ < other.value_.bool_;
35✔
505
  case stringValue: {
175✔
506
    if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
175✔
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);
175✔
518
    JSON_ASSERT(this_str && other_str);
519
    int comp = memcmp(this_str, other_str, min_len);
175✔
520
    if (comp < 0)
175✔
521
      return true;
522
    if (comp > 0)
163✔
523
      return false;
524
    return (this_len < other_len);
153✔
525
  }
526
  case arrayValue:
312✔
527
  case objectValue: {
528
    auto thisSize = value_.map_->size();
312✔
529
    auto otherSize = other.value_.map_->size();
312✔
530
    if (thisSize != otherSize)
312✔
531
      return thisSize < otherSize;
66✔
532
    return (*value_.map_) < (*other.value_.map_);
246✔
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); }
120✔
541

542
bool Value::operator>=(const Value& other) const { return !(*this < other); }
120✔
543

544
bool Value::operator>(const Value& other) const { return other < *this; }
209✔
545

546
bool Value::operator==(const Value& other) const {
301✔
547
  if (type() != other.type())
301✔
548
    return false;
549
  switch (type()) {
286✔
550
  case nullValue:
551
    return true;
552
  case intValue:
75✔
553
    return value_.int_ == other.value_.int_;
75✔
554
  case uintValue:
8✔
555
    return value_.uint_ == other.value_.uint_;
8✔
556
  case realValue:
12✔
557
    return value_.real_ == other.value_.real_;
12✔
558
  case booleanValue:
14✔
559
    return value_.bool_ == other.value_.bool_;
14✔
560
  case stringValue: {
86✔
561
    if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
86✔
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)
86✔
573
      return false;
574
    JSON_ASSERT(this_str && other_str);
575
    int comp = memcmp(this_str, other_str, this_len);
79✔
576
    return comp == 0;
79✔
577
  }
578
  case arrayValue:
59✔
579
  case objectValue:
580
    return value_.map_->size() == other.value_.map_->size() &&
105✔
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); }
119✔
589

590
const char* Value::asCString() const {
4✔
591
  JSON_ASSERT_MESSAGE(type() == stringValue,
6✔
592
                      "in Json::Value::asCString(): requires stringValue");
593
  if (value_.string_ == nullptr)
3✔
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 {
782✔
617
  if (type() != stringValue)
782✔
618
    return false;
619
  if (value_.string_ == nullptr)
782✔
620
    return false;
621
  unsigned length;
622
  decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
623
                       begin);
624
  *end = *begin + length;
782✔
625
  return true;
782✔
626
}
627

628
String Value::asString() const {
2,750✔
629
  switch (type()) {
2,750✔
630
  case nullValue:
631
    return "";
2✔
632
  case stringValue: {
2,708✔
633
    if (value_.string_ == nullptr)
2,708✔
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);
2,708✔
640
  }
641
  case booleanValue:
642
    return value_.bool_ ? "true" : "false";
×
643
  case intValue:
13✔
644
    return valueToString(value_.int_);
13✔
645
  case uintValue:
7✔
646
    return valueToString(value_.uint_);
7✔
647
  case realValue:
18✔
648
    return valueToString(value_.real_);
18✔
649
  default:
2✔
650
    JSON_FAIL_MESSAGE("Type is not convertible to string");
6✔
651
  }
652
}
653

654
Value::Int Value::asInt() const {
28✔
655
  switch (type()) {
28✔
656
  case intValue:
9✔
657
    JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
9✔
658
    return Int(value_.int_);
9✔
659
  case uintValue:
8✔
660
    JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
8✔
661
    return Int(value_.uint_);
8✔
662
  case realValue:
5✔
663
    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
5✔
664
                        "double out of Int range");
665
    return Int(value_.real_);
5✔
666
  case nullValue:
667
    return 0;
668
  case booleanValue:
2✔
669
    return value_.bool_ ? 1 : 0;
2✔
670
  default:
671
    break;
672
  }
673
  JSON_FAIL_MESSAGE("Value is not convertible to Int.");
9✔
674
}
675

676
Value::UInt Value::asUInt() const {
1,575✔
677
  switch (type()) {
1,575✔
678
  case intValue:
1,558✔
679
    JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
1,558✔
680
    return UInt(value_.int_);
1,558✔
681
  case uintValue:
6✔
682
    JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
6✔
683
    return UInt(value_.uint_);
6✔
684
  case realValue:
5✔
685
    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
5✔
686
                        "double out of UInt range");
687
    return UInt(value_.real_);
5✔
688
  case nullValue:
689
    return 0;
690
  case booleanValue:
2✔
691
    return value_.bool_ ? 1 : 0;
2✔
692
  default:
693
    break;
694
  }
695
  JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
9✔
696
}
697

698
#if defined(JSON_HAS_INT64)
699

700
Value::Int64 Value::asInt64() const {
157,462✔
701
  switch (type()) {
157,462✔
702
  case intValue:
157,438✔
703
    return Int64(value_.int_);
157,438✔
704
  case uintValue:
6✔
705
    JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
6✔
706
    return Int64(value_.uint_);
6✔
707
  case realValue:
12✔
708
    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
12✔
709
                        "double out of Int64 range");
710
    return Int64(value_.real_);
12✔
711
  case nullValue:
712
    return 0;
713
  case booleanValue:
2✔
714
    return value_.bool_ ? 1 : 0;
2✔
715
  default:
716
    break;
717
  }
718
  JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
9✔
719
}
720

721
Value::UInt64 Value::asUInt64() const {
261✔
722
  switch (type()) {
261✔
723
  case intValue:
8✔
724
    JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
8✔
725
    return UInt64(value_.int_);
8✔
726
  case uintValue:
237✔
727
    return UInt64(value_.uint_);
237✔
728
  case realValue:
10✔
729
    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
10✔
730
                        "double out of UInt64 range");
731
    return UInt64(value_.real_);
10✔
732
  case nullValue:
733
    return 0;
734
  case booleanValue:
2✔
735
    return value_.bool_ ? 1 : 0;
2✔
736
  default:
737
    break;
738
  }
739
  JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
9✔
740
}
741
#endif // if defined(JSON_HAS_INT64)
742

743
LargestInt Value::asLargestInt() const {
157,449✔
744
#if defined(JSON_NO_INT64)
745
  return asInt();
746
#else
747
  return asInt64();
157,449✔
748
#endif
749
}
750

751
LargestUInt Value::asLargestUInt() const {
248✔
752
#if defined(JSON_NO_INT64)
753
  return asUInt();
754
#else
755
  return asUInt64();
248✔
756
#endif
757
}
758

759
double Value::asDouble() const {
528✔
760
  switch (type()) {
528✔
761
  case intValue:
20✔
762
    return static_cast<double>(value_.int_);
20✔
763
  case uintValue:
14✔
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_);
14✔
768
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
769
  case realValue:
488✔
770
    return value_.real_;
488✔
771
  case nullValue:
772
    return 0.0;
773
  case booleanValue:
2✔
774
    return value_.bool_ ? 1.0 : 0.0;
2✔
775
  default:
776
    break;
777
  }
778
  JSON_FAIL_MESSAGE("Value is not convertible to double.");
9✔
779
}
780

781
float Value::asFloat() const {
40✔
782
  switch (type()) {
40✔
783
  case intValue:
10✔
784
    return static_cast<float>(value_.int_);
10✔
785
  case uintValue:
7✔
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_));
7✔
791
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
792
  case realValue:
17✔
793
    return static_cast<float>(value_.real_);
17✔
794
  case nullValue:
795
    return 0.0;
796
  case booleanValue:
2✔
797
    return value_.bool_ ? 1.0F : 0.0F;
2✔
798
  default:
799
    break;
800
  }
801
  JSON_FAIL_MESSAGE("Value is not convertible to float.");
9✔
802
}
803

804
bool Value::asBool() const {
12,669✔
805
  switch (type()) {
12,669✔
806
  case booleanValue:
12,636✔
807
    return value_.bool_;
12,636✔
808
  case nullValue:
809
    return false;
810
  case intValue:
10✔
811
    return value_.int_ != 0;
10✔
812
  case uintValue:
7✔
813
    return value_.uint_ != 0;
7✔
814
  case realValue: {
13✔
815
    // According to JavaScript language zero or NaN is regarded as false
816
    const auto value_classification = std::fpclassify(value_.real_);
13✔
817
    return value_classification != FP_ZERO && value_classification != FP_NAN;
13✔
818
  }
819
  default:
820
    break;
821
  }
822
  JSON_FAIL_MESSAGE("Value is not convertible to bool.");
9✔
823
}
824

825
bool Value::isConvertibleTo(ValueType other) const {
173✔
826
  switch (other) {
173✔
827
  case nullValue:
39✔
828
    return (isNumeric() && asDouble() == 0.0) ||
102✔
829
           (type() == booleanValue && !value_.bool_) ||
67✔
830
           (type() == stringValue && asString().empty()) ||
105✔
831
           (type() == arrayValue && value_.map_->empty()) ||
63✔
832
           (type() == objectValue && value_.map_->empty()) ||
100✔
833
           type() == nullValue;
29✔
834
  case intValue:
35✔
835
    return isInt() ||
58✔
836
           (type() == realValue && InRange(value_.real_, minInt, maxInt)) ||
54✔
837
           type() == booleanValue || type() == nullValue;
76✔
838
  case uintValue:
35✔
839
    return isUInt() ||
59✔
840
           (type() == realValue && InRange(value_.real_, 0, maxUInt)) ||
56✔
841
           type() == booleanValue || type() == nullValue;
78✔
842
  case realValue:
13✔
843
    return isNumeric() || type() == booleanValue || type() == nullValue;
13✔
844
  case booleanValue:
12✔
845
    return isNumeric() || type() == booleanValue || type() == nullValue;
12✔
846
  case stringValue:
13✔
847
    return isNumeric() || type() == booleanValue || type() == stringValue ||
16✔
848
           type() == nullValue;
3✔
849
  case arrayValue:
13✔
850
    return type() == arrayValue || type() == nullValue;
13✔
851
  case objectValue:
13✔
852
    return type() == objectValue || type() == nullValue;
13✔
853
  }
854
  JSON_ASSERT_UNREACHABLE;
×
855
  return false;
856
}
857

858
/// Number of values in array or object
859
ArrayIndex Value::size() const {
838✔
860
  switch (type()) {
838✔
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
797✔
869
    if (!value_.map_->empty()) {
797✔
870
      ObjectValues::const_iterator itLast = value_.map_->end();
871
      --itLast;
872
      return (*itLast).first.index() + 1;
713✔
873
    }
874
    return 0;
875
  case objectValue:
28✔
876
    return ArrayIndex(value_.map_->size());
28✔
877
  }
878
  JSON_ASSERT_UNREACHABLE;
×
879
  return 0; // unreachable;
880
}
881

882
bool Value::empty() const {
36✔
883
  if (isNull() || isArray() || isObject())
36✔
884
    return size() == 0U;
36✔
885
  return false;
886
}
887

888
Value::operator bool() const { return !isNull(); }
4✔
889

890
void Value::clear() {
3✔
891
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue ||
5✔
892
                          type() == objectValue,
893
                      "in Json::Value::clear(): requires complex value");
894
  start_ = 0;
2✔
895
  limit_ = 0;
2✔
896
  switch (type()) {
2✔
897
  case arrayValue:
2✔
898
  case objectValue:
899
    value_.map_->clear();
2✔
900
    break;
901
  default:
902
    break;
903
  }
904
}
2✔
905

906
void Value::resize(ArrayIndex newSize) {
7✔
907
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
13✔
908
                      "in Json::Value::resize(): requires arrayValue");
909
  if (type() == nullValue)
4✔
910
    *this = Value(arrayValue);
1✔
911
  ArrayIndex oldSize = size();
4✔
912
  if (newSize == 0)
4✔
913
    clear();
1✔
914
  else if (newSize > oldSize)
3✔
915
    for (ArrayIndex i = oldSize; i < newSize; ++i)
17✔
916
      (*this)[i];
15✔
917
  else {
918
    for (ArrayIndex index = newSize; index < oldSize; ++index) {
11✔
919
      value_.map_->erase(index);
20✔
920
    }
921
    JSON_ASSERT(size() == newSize);
1✔
922
  }
923
}
4✔
924

925
Value& Value::operator[](ArrayIndex index) {
216,243✔
926
  JSON_ASSERT_MESSAGE(
216,249✔
927
      type() == nullValue || type() == arrayValue,
928
      "in Json::Value::operator[](ArrayIndex): requires arrayValue");
929
  if (type() == nullValue)
216,240✔
930
    *this = Value(arrayValue);
16✔
931
  CZString key(index);
216,240✔
932
  auto it = value_.map_->lower_bound(key);
216,240✔
933
  if (it != value_.map_->end() && (*it).first == key)
216,240✔
934
    return (*it).second;
104,903✔
935

936
  ObjectValues::value_type defaultValue(key, nullSingleton());
111,337✔
937
  it = value_.map_->insert(it, defaultValue);
111,337✔
938
  return (*it).second;
111,337✔
939
}
216,240✔
940

941
Value& Value::operator[](int index) {
111,235✔
942
  JSON_ASSERT_MESSAGE(
111,235✔
943
      index >= 0,
944
      "in Json::Value::operator[](int index): index cannot be negative");
945
  return (*this)[ArrayIndex(index)];
111,235✔
946
}
947

948
const Value& Value::operator[](ArrayIndex index) const {
53,225✔
949
  JSON_ASSERT_MESSAGE(
53,225✔
950
      type() == nullValue || type() == arrayValue,
951
      "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
952
  if (type() == nullValue)
53,225✔
953
    return nullSingleton();
×
954
  CZString key(index);
53,225✔
955
  ObjectValues::const_iterator it = value_.map_->find(key);
53,225✔
956
  if (it == value_.map_->end())
53,225✔
957
    return nullSingleton();
1✔
958
  return (*it).second;
53,224✔
959
}
53,225✔
960

961
const Value& Value::operator[](int index) const {
4✔
962
  JSON_ASSERT_MESSAGE(
4✔
963
      index >= 0,
964
      "in Json::Value::operator[](int index) const: index cannot be negative");
965
  return (*this)[ArrayIndex(index)];
4✔
966
}
967

968
void Value::initBasic(ValueType type, bool allocated) {
242,397✔
969
  setType(type);
970
  setIsAllocated(allocated);
971
  comments_ = Comments{};
242,397✔
972
  start_ = 0;
242,397✔
973
  limit_ = 0;
242,397✔
974
}
242,397✔
975

976
void Value::dupPayload(const Value& other) {
251,621✔
977
  setType(other.type());
251,621✔
978
  setIsAllocated(false);
979
  switch (type()) {
251,621✔
980
  case nullValue:
251,440✔
981
  case intValue:
982
  case uintValue:
983
  case realValue:
984
  case booleanValue:
985
    value_ = other.value_;
251,440✔
986
    break;
251,440✔
987
  case stringValue:
128✔
988
    if (other.value_.string_ && other.isAllocated()) {
128✔
989
      unsigned len;
990
      char const* str;
991
      decodePrefixedString(other.isAllocated(), other.value_.string_, &len,
992
                           &str);
993
      value_.string_ = duplicateAndPrefixStringValue(str, len);
128✔
994
      setIsAllocated(true);
995
    } else {
996
      value_.string_ = other.value_.string_;
×
997
    }
998
    break;
999
  case arrayValue:
53✔
1000
  case objectValue:
1001
    value_.map_ = new ObjectValues(*other.value_.map_);
53✔
1002
    break;
53✔
1003
  default:
×
1004
    JSON_ASSERT_UNREACHABLE;
×
1005
  }
1006
}
251,621✔
1007

1008
void Value::releasePayload() {
494,018✔
1009
  switch (type()) {
494,018✔
1010
  case nullValue:
1011
  case intValue:
1012
  case uintValue:
1013
  case realValue:
1014
  case booleanValue:
1015
    break;
1016
  case stringValue:
1017
    if (isAllocated())
2,419✔
1018
      releasePrefixedStringValue(value_.string_);
2,417✔
1019
    break;
1020
  case arrayValue:
8,966✔
1021
  case objectValue:
1022
    delete value_.map_;
17,932✔
1023
    break;
1024
  default:
×
1025
    JSON_ASSERT_UNREACHABLE;
×
1026
  }
1027
}
494,018✔
1028

1029
void Value::dupMeta(const Value& other) {
251,621✔
1030
  comments_ = other.comments_;
251,621✔
1031
  start_ = other.start_;
251,621✔
1032
  limit_ = other.limit_;
251,621✔
1033
}
251,621✔
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) {
1✔
1039
  JSON_ASSERT_MESSAGE(
1✔
1040
      type() == nullValue || type() == objectValue,
1041
      "in Json::Value::resolveReference(): requires objectValue");
1042
  if (type() == nullValue)
1✔
1043
    *this = Value(objectValue);
1✔
1044
  CZString actualKey(key, static_cast<unsigned>(strlen(key)),
1✔
1045
                     CZString::noDuplication); // NOTE!
1✔
1046
  auto it = value_.map_->lower_bound(actualKey);
1✔
1047
  if (it != value_.map_->end() && (*it).first == actualKey)
1✔
1048
    return (*it).second;
×
1049

1050
  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1✔
1051
  it = value_.map_->insert(it, defaultValue);
1✔
1052
  Value& value = (*it).second;
1✔
1053
  return value;
1054
}
1✔
1055

1056
// @param key is not null-terminated.
1057
Value& Value::resolveReference(char const* key, char const* end) {
18,648✔
1058
  JSON_ASSERT_MESSAGE(
18,654✔
1059
      type() == nullValue || type() == objectValue,
1060
      "in Json::Value::resolveReference(key, end): requires objectValue");
1061
  if (type() == nullValue)
18,645✔
1062
    *this = Value(objectValue);
1,612✔
1063
  CZString actualKey(key, static_cast<unsigned>(end - key),
18,645✔
1064
                     CZString::duplicateOnCopy);
18,645✔
1065
  auto it = value_.map_->lower_bound(actualKey);
18,645✔
1066
  if (it != value_.map_->end() && (*it).first == actualKey)
18,645✔
1067
    return (*it).second;
4,345✔
1068

1069
  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
14,300✔
1070
  it = value_.map_->insert(it, defaultValue);
14,300✔
1071
  Value& value = (*it).second;
14,300✔
1072
  return value;
1073
}
18,645✔
1074

1075
Value Value::get(ArrayIndex index, const Value& defaultValue) const {
6✔
1076
  const Value* value = &((*this)[index]);
6✔
1077
  return value == &nullSingleton() ? defaultValue : *value;
11✔
1078
}
1079

1080
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
7✔
1081

1082
Value const* Value::find(char const* begin, char const* end) const {
16,910✔
1083
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
16,910✔
1084
                      "in Json::Value::find(begin, end): requires "
1085
                      "objectValue or nullValue");
1086
  if (type() == nullValue)
16,910✔
1087
    return nullptr;
1088
  CZString actualKey(begin, static_cast<unsigned>(end - begin),
16,910✔
1089
                     CZString::noDuplication);
16,910✔
1090
  ObjectValues::const_iterator it = value_.map_->find(actualKey);
16,910✔
1091
  if (it == value_.map_->end())
16,910✔
1092
    return nullptr;
1093
  return &(*it).second;
16,897✔
1094
}
16,910✔
1095
Value* Value::demand(char const* begin, char const* end) {
1✔
1096
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1✔
1097
                      "in Json::Value::demand(begin, end): requires "
1098
                      "objectValue or nullValue");
1099
  return &resolveReference(begin, end);
1✔
1100
}
1101
const Value& Value::operator[](const char* key) const {
16,010✔
1102
  Value const* found = find(key, key + strlen(key));
16,010✔
1103
  if (!found)
16,010✔
1104
    return nullSingleton();
1✔
1105
  return *found;
1106
}
1107
Value const& Value::operator[](const String& key) const {
872✔
1108
  Value const* found = find(key.data(), key.data() + key.length());
872✔
1109
  if (!found)
872✔
1110
    return nullSingleton();
3✔
1111
  return *found;
1112
}
1113

1114
Value& Value::operator[](const char* key) {
16,783✔
1115
  return resolveReference(key, key + strlen(key));
16,783✔
1116
}
1117

1118
Value& Value::operator[](const String& key) {
1,864✔
1119
  return resolveReference(key.data(), key.data() + key.length());
1,864✔
1120
}
1121

1122
Value& Value::operator[](const StaticString& key) {
1✔
1123
  return resolveReference(key.c_str());
1✔
1124
}
1125

1126
Value& Value::append(const Value& value) { return append(Value(value)); }
1✔
1127

1128
Value& Value::append(Value&& value) {
49✔
1129
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
49✔
1130
                      "in Json::Value::append: requires arrayValue");
1131
  if (type() == nullValue) {
49✔
1132
    *this = Value(arrayValue);
40✔
1133
  }
1134
  return this->value_.map_->emplace(size(), std::move(value)).first->second;
49✔
1135
}
1136

1137
bool Value::insert(ArrayIndex index, const Value& newValue) {
1✔
1138
  return insert(index, Value(newValue));
1✔
1139
}
1140

1141
bool Value::insert(ArrayIndex index, Value&& newValue) {
4✔
1142
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
4✔
1143
                      "in Json::Value::insert: requires arrayValue");
1144
  ArrayIndex length = size();
4✔
1145
  if (index > length) {
4✔
1146
    return false;
1147
  }
1148
  for (ArrayIndex i = length; i > index; i--) {
8✔
1149
    (*this)[i] = std::move((*this)[i - 1]);
5✔
1150
  }
1151
  (*this)[index] = std::move(newValue);
3✔
1152
  return true;
3✔
1153
}
1154

1155
Value Value::get(char const* begin, char const* end,
15✔
1156
                 Value const& defaultValue) const {
1157
  Value const* found = find(begin, end);
15✔
1158
  return !found ? defaultValue : *found;
29✔
1159
}
1160
Value Value::get(char const* key, Value const& defaultValue) const {
10✔
1161
  return get(key, key + strlen(key), defaultValue);
10✔
1162
}
1163
Value Value::get(String const& key, Value const& defaultValue) const {
5✔
1164
  return get(key.data(), key.data() + key.length(), defaultValue);
5✔
1165
}
1166

1167
bool Value::removeMember(const char* begin, const char* end, Value* removed) {
9✔
1168
  if (type() != objectValue) {
9✔
1169
    return false;
1170
  }
1171
  CZString actualKey(begin, static_cast<unsigned>(end - begin),
9✔
1172
                     CZString::noDuplication);
9✔
1173
  auto it = value_.map_->find(actualKey);
9✔
1174
  if (it == value_.map_->end())
9✔
1175
    return false;
1176
  if (removed)
5✔
1177
    *removed = std::move(it->second);
4✔
1178
  value_.map_->erase(it);
5✔
1179
  return true;
5✔
1180
}
9✔
1181
bool Value::removeMember(const char* key, Value* removed) {
3✔
1182
  return removeMember(key, key + strlen(key), removed);
3✔
1183
}
1184
bool Value::removeMember(String const& key, Value* removed) {
2✔
1185
  return removeMember(key.data(), key.data() + key.length(), removed);
2✔
1186
}
1187
void Value::removeMember(const char* key) {
4✔
1188
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
10✔
1189
                      "in Json::Value::removeMember(): requires objectValue");
1190
  if (type() == nullValue)
1✔
1191
    return;
×
1192

1193
  CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
1✔
1194
  value_.map_->erase(actualKey);
1✔
1195
}
1✔
1196
void Value::removeMember(const String& key) { removeMember(key.c_str()); }
1✔
1197

1198
bool Value::removeIndex(ArrayIndex index, Value* removed) {
2✔
1199
  if (type() != arrayValue) {
2✔
1200
    return false;
1201
  }
1202
  CZString key(index);
2✔
1203
  auto it = value_.map_->find(key);
2✔
1204
  if (it == value_.map_->end()) {
2✔
1205
    return false;
1206
  }
1207
  if (removed)
1✔
1208
    *removed = it->second;
1✔
1209
  ArrayIndex oldSize = size();
1✔
1210
  // shift left all items left, into the place of the "removed"
1211
  for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
1✔
1212
    CZString keey(i);
×
1213
    (*value_.map_)[keey] = (*this)[i + 1];
×
1214
  }
×
1215
  // erase the last one ("leftover")
1216
  CZString keyLast(oldSize - 1);
1✔
1217
  auto itLast = value_.map_->find(keyLast);
1✔
1218
  value_.map_->erase(itLast);
1✔
1219
  return true;
1220
}
2✔
1221

1222
bool Value::isMember(char const* begin, char const* end) const {
10✔
1223
  Value const* value = find(begin, end);
10✔
1224
  return nullptr != value;
10✔
1225
}
1226
bool Value::isMember(char const* key) const {
5✔
1227
  return isMember(key, key + strlen(key));
5✔
1228
}
1229
bool Value::isMember(String const& key) const {
5✔
1230
  return isMember(key.data(), key.data() + key.length());
5✔
1231
}
1232

1233
Value::Members Value::getMemberNames() const {
1,130✔
1234
  JSON_ASSERT_MESSAGE(
1,136✔
1235
      type() == nullValue || type() == objectValue,
1236
      "in Json::Value::getMemberNames(), value must be objectValue");
1237
  if (type() == nullValue)
1,127✔
1238
    return Value::Members();
×
1239
  Members members;
1240
  members.reserve(value_.map_->size());
1,127✔
1241
  ObjectValues::const_iterator it = value_.map_->begin();
1,127✔
1242
  ObjectValues::const_iterator itEnd = value_.map_->end();
1243
  for (; it != itEnd; ++it) {
2,792✔
1244
    members.push_back(String((*it).first.data(), (*it).first.length()));
3,330✔
1245
  }
1246
  return members;
1247
}
1,127✔
1248

1249
static bool IsIntegral(double d) {
1250
  double integral_part;
1251
  return modf(d, &integral_part) == 0.0;
59✔
1252
}
1253

1254
bool Value::isNull() const { return type() == nullValue; }
80✔
1255

1256
bool Value::isBool() const { return type() == booleanValue; }
48✔
1257

1258
bool Value::isInt() const {
100✔
1259
  switch (type()) {
100✔
1260
  case intValue:
31✔
1261
#if defined(JSON_HAS_INT64)
1262
    return value_.int_ >= minInt && value_.int_ <= maxInt;
31✔
1263
#else
1264
    return true;
1265
#endif
1266
  case uintValue:
22✔
1267
    return value_.uint_ <= UInt(maxInt);
22✔
1268
  case realValue:
28✔
1269
    return value_.real_ >= minInt && value_.real_ <= maxInt &&
28✔
1270
           IsIntegral(value_.real_);
1271
  default:
1272
    break;
1273
  }
1274
  return false;
1275
}
1276

1277
bool Value::isUInt() const {
1,647✔
1278
  switch (type()) {
1,647✔
1279
  case intValue:
1,580✔
1280
#if defined(JSON_HAS_INT64)
1281
    return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
1,580✔
1282
#else
1283
    return value_.int_ >= 0;
1284
#endif
1285
  case uintValue:
20✔
1286
#if defined(JSON_HAS_INT64)
1287
    return value_.uint_ <= maxUInt;
20✔
1288
#else
1289
    return true;
1290
#endif
1291
  case realValue:
28✔
1292
    return value_.real_ >= 0 && value_.real_ <= maxUInt &&
28✔
1293
           IsIntegral(value_.real_);
1294
  default:
1295
    break;
1296
  }
1297
  return false;
1298
}
1299

1300
bool Value::isInt64() const {
54✔
1301
#if defined(JSON_HAS_INT64)
1302
  switch (type()) {
54✔
1303
  case intValue:
1304
    return true;
1305
  case uintValue:
13✔
1306
    return value_.uint_ <= UInt64(maxInt64);
13✔
1307
  case realValue:
15✔
1308
    // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
1309
    // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
1310
    // require the value to be strictly less than the limit.
1311
    return value_.real_ >= double(minInt64) &&
15✔
1312
           value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
27✔
1313
  default:
1314
    break;
1315
  }
1316
#endif // JSON_HAS_INT64
1317
  return false;
14✔
1318
}
1319

1320
bool Value::isUInt64() const {
56✔
1321
#if defined(JSON_HAS_INT64)
1322
  switch (type()) {
56✔
1323
  case intValue:
20✔
1324
    return value_.int_ >= 0;
20✔
1325
  case uintValue:
1326
    return true;
1327
  case realValue:
15✔
1328
    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1329
    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1330
    // require the value to be strictly less than the limit.
1331
    return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
15✔
1332
           IsIntegral(value_.real_);
1333
  default:
1334
    break;
1335
  }
1336
#endif // JSON_HAS_INT64
1337
  return false;
14✔
1338
}
1339

1340
bool Value::isIntegral() const {
40✔
1341
  switch (type()) {
40✔
1342
  case intValue:
1343
  case uintValue:
1344
    return true;
1345
  case realValue:
13✔
1346
#if defined(JSON_HAS_INT64)
1347
    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1348
    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1349
    // require the value to be strictly less than the limit.
1350
    return value_.real_ >= double(minInt64) &&
13✔
1351
           value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
25✔
1352
#else
1353
    return value_.real_ >= minInt && value_.real_ <= maxUInt &&
1354
           IsIntegral(value_.real_);
1355
#endif // JSON_HAS_INT64
1356
  default:
1357
    break;
1358
  }
1359
  return false;
10✔
1360
}
1361

1362
bool Value::isDouble() const {
165✔
1363
  return type() == intValue || type() == uintValue || type() == realValue;
165✔
1364
}
1365

1366
bool Value::isNumeric() const { return isDouble(); }
117✔
1367

1368
bool Value::isString() const { return type() == stringValue; }
50✔
1369

1370
bool Value::isArray() const { return type() == arrayValue; }
499✔
1371

1372
bool Value::isObject() const { return type() == objectValue; }
432✔
1373

1374
Value::Comments::Comments(const Comments& that)
×
1375
    : ptr_{cloneUnique(that.ptr_)} {}
×
1376

1377
Value::Comments::Comments(Comments&& that) noexcept
124,144✔
1378
    : ptr_{std::move(that.ptr_)} {}
124,144✔
1379

1380
Value::Comments& Value::Comments::operator=(const Comments& that) {
251,621✔
1381
  ptr_ = cloneUnique(that.ptr_);
251,621✔
1382
  return *this;
251,621✔
1383
}
1384

1385
Value::Comments& Value::Comments::operator=(Comments&& that) noexcept {
490,685✔
1386
  ptr_ = std::move(that.ptr_);
1387
  return *this;
490,685✔
1388
}
1389

1390
bool Value::Comments::has(CommentPlacement slot) const {
377,785✔
1391
  return ptr_ && !(*ptr_)[slot].empty();
377,785✔
1392
}
1393

1394
String Value::Comments::get(CommentPlacement slot) const {
1,282✔
1395
  if (!ptr_)
1,282✔
1396
    return {};
1397
  return (*ptr_)[slot];
1,282✔
1398
}
1399

1400
void Value::Comments::set(CommentPlacement slot, String comment) {
955✔
1401
  if (slot >= CommentPlacement::numberOfCommentPlacement)
955✔
1402
    return;
1403
  if (!ptr_)
955✔
1404
    ptr_ = std::unique_ptr<Array>(new Array());
1,786✔
1405
  (*ptr_)[slot] = std::move(comment);
1,910✔
1406
}
1407

1408
void Value::setComment(String comment, CommentPlacement placement) {
955✔
1409
  if (!comment.empty() && (comment.back() == '\n')) {
955✔
1410
    // Always discard trailing newline, to aid indentation.
1411
    comment.pop_back();
790✔
1412
  }
1413
  JSON_ASSERT_MESSAGE(
955✔
1414
      comment.empty() || comment[0] == '/',
1415
      "in Json::Value::setComment(): Comments must start with /");
1416
  comments_.set(placement, std::move(comment));
1,910✔
1417
}
955✔
1418

1419
bool Value::hasComment(CommentPlacement placement) const {
377,785✔
1420
  return comments_.has(placement);
377,785✔
1421
}
1422

1423
String Value::getComment(CommentPlacement placement) const {
1,282✔
1424
  return comments_.get(placement);
1,282✔
1425
}
1426

1427
void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
113,818✔
1428

1429
void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
107,817✔
1430

1431
ptrdiff_t Value::getOffsetStart() const { return start_; }
19✔
1432

1433
ptrdiff_t Value::getOffsetLimit() const { return limit_; }
19✔
1434

1435
String Value::toStyledString() const {
5✔
1436
  StreamWriterBuilder builder;
5✔
1437

1438
  String out = this->hasComment(commentBefore) ? "\n" : "";
8✔
1439
  out += Json::writeString(builder, *this);
10✔
1440
  out += '\n';
1441

1442
  return out;
5✔
1443
}
5✔
1444

1445
Value::const_iterator Value::begin() const {
22✔
1446
  switch (type()) {
22✔
1447
  case arrayValue:
9✔
1448
  case objectValue:
1449
    if (value_.map_)
9✔
1450
      return const_iterator(value_.map_->begin());
9✔
1451
    break;
1452
  default:
1453
    break;
1454
  }
1455
  return {};
13✔
1456
}
1457

1458
Value::const_iterator Value::end() const {
63✔
1459
  switch (type()) {
63✔
1460
  case arrayValue:
51✔
1461
  case objectValue:
1462
    if (value_.map_)
51✔
1463
      return const_iterator(value_.map_->end());
51✔
1464
    break;
1465
  default:
1466
    break;
1467
  }
1468
  return {};
12✔
1469
}
1470

1471
Value::iterator Value::begin() {
37✔
1472
  switch (type()) {
37✔
1473
  case arrayValue:
24✔
1474
  case objectValue:
1475
    if (value_.map_)
24✔
1476
      return iterator(value_.map_->begin());
24✔
1477
    break;
1478
  default:
1479
    break;
1480
  }
1481
  return iterator();
13✔
1482
}
1483

1484
Value::iterator Value::end() {
42✔
1485
  switch (type()) {
42✔
1486
  case arrayValue:
27✔
1487
  case objectValue:
1488
    if (value_.map_)
27✔
1489
      return iterator(value_.map_->end());
27✔
1490
    break;
1491
  default:
1492
    break;
1493
  }
1494
  return iterator();
15✔
1495
}
1496

1497
// class PathArgument
1498
// //////////////////////////////////////////////////////////////////
1499

1500
PathArgument::PathArgument() = default;
36✔
1501

1502
PathArgument::PathArgument(ArrayIndex index)
4✔
1503
    : index_(index), kind_(kindIndex) {}
4✔
1504

1505
PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {}
2✔
1506

1507
PathArgument::PathArgument(String key) : key_(std::move(key)), kind_(kindKey) {}
10✔
1508

1509
// class Path
1510
// //////////////////////////////////////////////////////////////////
1511

1512
Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2,
8✔
1513
           const PathArgument& a3, const PathArgument& a4,
1514
           const PathArgument& a5) {
8✔
1515
  InArgs in;
1516
  in.reserve(5);
8✔
1517
  in.push_back(&a1);
8✔
1518
  in.push_back(&a2);
8✔
1519
  in.push_back(&a3);
8✔
1520
  in.push_back(&a4);
8✔
1521
  in.push_back(&a5);
8✔
1522
  makePath(path, in);
8✔
1523
}
8✔
1524

1525
void Path::makePath(const String& path, const InArgs& in) {
8✔
1526
  const char* current = path.c_str();
1527
  const char* end = current + path.length();
8✔
1528
  auto itInArg = in.begin();
8✔
1529
  while (current != end) {
42✔
1530
    if (*current == '[') {
34✔
1531
      ++current;
4✔
1532
      if (*current == '%')
4✔
1533
        addPathInArg(path, in, itInArg, PathArgument::kindIndex);
2✔
1534
      else {
1535
        ArrayIndex index = 0;
1536
        for (; current != end && *current >= '0' && *current <= '9'; ++current)
4✔
1537
          index = index * 10 + ArrayIndex(*current - '0');
2✔
1538
        args_.push_back(index);
4✔
1539
      }
1540
      if (current == end || *++current != ']')
4✔
1541
        invalidPath(path, int(current - path.c_str()));
2✔
1542
    } else if (*current == '%') {
30✔
1543
      addPathInArg(path, in, itInArg, PathArgument::kindKey);
2✔
1544
      ++current;
2✔
1545
    } else if (*current == '.' || *current == ']') {
28✔
1546
      ++current;
18✔
1547
    } else {
1548
      const char* beginName = current;
1549
      while (current != end && !strchr("[.", *current))
88✔
1550
        ++current;
78✔
1551
      args_.push_back(String(beginName, current));
20✔
1552
    }
1553
  }
1554
}
8✔
1555

1556
void Path::addPathInArg(const String& /*path*/, const InArgs& in,
4✔
1557
                        InArgs::const_iterator& itInArg,
1558
                        PathArgument::Kind kind) {
1559
  if (itInArg == in.end()) {
4✔
1560
    // Error: missing argument %d
1561
  } else if ((*itInArg)->kind_ != kind) {
4✔
1562
    // Error: bad argument type
1563
  } else {
1564
    args_.push_back(**itInArg++);
4✔
1565
  }
1566
}
4✔
1567

1568
void Path::invalidPath(const String& /*path*/, int /*location*/) {
2✔
1569
  // Error: invalid path.
1570
}
2✔
1571

1572
const Value& Path::resolve(const Value& root) const {
6✔
1573
  const Value* node = &root;
1574
  for (const auto& arg : args_) {
14✔
1575
    if (arg.kind_ == PathArgument::kindIndex) {
12✔
1576
      if (!node->isArray() || !node->isValidIndex(arg.index_)) {
2✔
1577
        // Error: unable to resolve path (array value expected at position... )
1578
        return Value::nullSingleton();
1✔
1579
      }
1580
      node = &((*node)[arg.index_]);
1✔
1581
    } else if (arg.kind_ == PathArgument::kindKey) {
10✔
1582
      if (!node->isObject()) {
10✔
1583
        // Error: unable to resolve path (object value expected at position...)
1584
        return Value::nullSingleton();
1✔
1585
      }
1586
      node = &((*node)[arg.key_]);
9✔
1587
      if (node == &Value::nullSingleton()) {
9✔
1588
        // Error: unable to resolve path (object has no member named '' at
1589
        // position...)
1590
        return Value::nullSingleton();
2✔
1591
      }
1592
    }
1593
  }
1594
  return *node;
1595
}
1596

1597
Value Path::resolve(const Value& root, const Value& defaultValue) const {
6✔
1598
  const Value* node = &root;
1599
  for (const auto& arg : args_) {
14✔
1600
    if (arg.kind_ == PathArgument::kindIndex) {
12✔
1601
      if (!node->isArray() || !node->isValidIndex(arg.index_))
3✔
1602
        return defaultValue;
2✔
1603
      node = &((*node)[arg.index_]);
1✔
1604
    } else if (arg.kind_ == PathArgument::kindKey) {
9✔
1605
      if (!node->isObject())
9✔
1606
        return defaultValue;
1✔
1607
      node = &((*node)[arg.key_]);
8✔
1608
      if (node == &Value::nullSingleton())
8✔
1609
        return defaultValue;
1✔
1610
    }
1611
  }
1612
  return *node;
2✔
1613
}
1614

1615
Value& Path::make(Value& root) const {
2✔
1616
  Value* node = &root;
1617
  for (const auto& arg : args_) {
6✔
1618
    if (arg.kind_ == PathArgument::kindIndex) {
4✔
1619
      if (!node->isArray()) {
1✔
1620
        // Error: node is not an array at position ...
1621
      }
1622
      node = &((*node)[arg.index_]);
1✔
1623
    } else if (arg.kind_ == PathArgument::kindKey) {
3✔
1624
      if (!node->isObject()) {
3✔
1625
        // Error: node is not an object at position...
1626
      }
1627
      node = &((*node)[arg.key_]);
3✔
1628
    }
1629
  }
1630
  return *node;
2✔
1631
}
1632

1633
} // namespace Json
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc