| // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors | 
 | // Distributed under MIT license, or public domain if desired and | 
 | // recognized in your jurisdiction. | 
 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE | 
 |  | 
 | #if defined(__GNUC__) | 
 | #pragma GCC diagnostic push | 
 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | 
 | #elif defined(_MSC_VER) | 
 | #pragma warning(disable : 4996) | 
 | #endif | 
 |  | 
 | #include "fuzz.h" | 
 | #include "jsontest.h" | 
 | #include <algorithm> | 
 | #include <cmath> | 
 | #include <cstring> | 
 | #include <functional> | 
 | #include <iomanip> | 
 | #include <iostream> | 
 | #include <iterator> | 
 | #include <json/config.h> | 
 | #include <json/json.h> | 
 | #include <limits> | 
 | #include <memory> | 
 | #include <sstream> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | using CharReaderPtr = std::unique_ptr<Json::CharReader>; | 
 |  | 
 | // Make numeric limits more convenient to talk about. | 
 | // Assumes int type in 32 bits. | 
 | #define kint32max Json::Value::maxInt | 
 | #define kint32min Json::Value::minInt | 
 | #define kuint32max Json::Value::maxUInt | 
 | #define kint64max Json::Value::maxInt64 | 
 | #define kint64min Json::Value::minInt64 | 
 | #define kuint64max Json::Value::maxUInt64 | 
 |  | 
 | // static const double kdint64max = double(kint64max); | 
 | // static const float kfint64max = float(kint64max); | 
 | static const float kfint32max = float(kint32max); | 
 | static const float kfuint32max = float(kuint32max); | 
 |  | 
 | // ////////////////////////////////////////////////////////////////// | 
 | // ////////////////////////////////////////////////////////////////// | 
 | // Json Library test cases | 
 | // ////////////////////////////////////////////////////////////////// | 
 | // ////////////////////////////////////////////////////////////////// | 
 |  | 
 | #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) | 
 | static inline double uint64ToDouble(Json::UInt64 value) { | 
 |   return static_cast<double>(value); | 
 | } | 
 | #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) | 
 | static inline double uint64ToDouble(Json::UInt64 value) { | 
 |   return static_cast<double>(Json::Int64(value / 2)) * 2.0 + | 
 |          static_cast<double>(Json::Int64(value & 1)); | 
 | } | 
 | #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) | 
 |  | 
 | // local_ is the collection for the testcases in this code file. | 
 | static std::deque<JsonTest::TestCaseFactory> local_; | 
 | #define JSONTEST_FIXTURE_LOCAL(FixtureType, name)                              \ | 
 |   JSONTEST_FIXTURE_V2(FixtureType, name, local_) | 
 |  | 
 | struct ValueTest : JsonTest::TestCase { | 
 |   Json::Value null_; | 
 |   Json::Value emptyArray_{Json::arrayValue}; | 
 |   Json::Value emptyObject_{Json::objectValue}; | 
 |   Json::Value integer_{123456789}; | 
 |   Json::Value unsignedInteger_{34567890}; | 
 |   Json::Value smallUnsignedInteger_{Json::Value::UInt(Json::Value::maxInt)}; | 
 |   Json::Value real_{1234.56789}; | 
 |   Json::Value float_{0.00390625f}; | 
 |   Json::Value array1_; | 
 |   Json::Value object1_; | 
 |   Json::Value object2_; | 
 |   Json::Value object3_; | 
 |   Json::Value emptyString_{""}; | 
 |   Json::Value string1_{"a"}; | 
 |   Json::Value string_{"sometext with space"}; | 
 |   Json::Value true_{true}; | 
 |   Json::Value false_{false}; | 
 |  | 
 |   ValueTest() { | 
 |     array1_.append(1234); | 
 |     object1_["id"] = 1234; | 
 |  | 
 |     // object2 with matching values | 
 |     object2_["null"] = Json::nullValue; | 
 |     object2_["bool"] = true; | 
 |     object2_["int"] = Json::Int{Json::Value::maxInt}; | 
 |     object2_["int64"] = Json::Int64{Json::Value::maxInt64}; | 
 |     object2_["uint"] = Json::UInt{Json::Value::maxUInt}; | 
 |     object2_["uint64"] = Json::UInt64{Json::Value::maxUInt64}; | 
 |     object2_["integral"] = 1234; | 
 |     object2_["double"] = 1234.56789; | 
 |     object2_["numeric"] = 0.12345f; | 
 |     object2_["string"] = "string"; | 
 |     object2_["array"] = Json::arrayValue; | 
 |     object2_["object"] = Json::objectValue; | 
 |  | 
 |     // object3 with not matching values | 
 |     object3_["object"] = Json::nullValue; | 
 |     object3_["null"] = true; | 
 |     object3_["bool"] = Json::Int{Json::Value::maxInt}; | 
 |     object3_["int"] = "not_an_int"; | 
 |     object3_["int64"] = "not_an_int64"; | 
 |     object3_["uint"] = "not_an_uint"; | 
 |     object3_["uin64"] = "not_an_uint64"; | 
 |     object3_["integral"] = 1234.56789; | 
 |     object3_["double"] = false; | 
 |     object3_["numeric"] = "string"; | 
 |     object3_["string"] = Json::arrayValue; | 
 |     object3_["array"] = Json::objectValue; | 
 |   } | 
 |  | 
 |   struct IsCheck { | 
 |     /// Initialize all checks to \c false by default. | 
 |     IsCheck(); | 
 |  | 
 |     bool isObject_{false}; | 
 |     bool isArray_{false}; | 
 |     bool isBool_{false}; | 
 |     bool isString_{false}; | 
 |     bool isNull_{false}; | 
 |  | 
 |     bool isInt_{false}; | 
 |     bool isInt64_{false}; | 
 |     bool isUInt_{false}; | 
 |     bool isUInt64_{false}; | 
 |     bool isIntegral_{false}; | 
 |     bool isDouble_{false}; | 
 |     bool isNumeric_{false}; | 
 |   }; | 
 |  | 
 |   void checkConstMemberCount(const Json::Value& value, | 
 |                              unsigned int expectedCount); | 
 |  | 
 |   void checkMemberCount(Json::Value& value, unsigned int expectedCount); | 
 |  | 
 |   void checkIs(const Json::Value& value, const IsCheck& check); | 
 |  | 
 |   void checkIsLess(const Json::Value& x, const Json::Value& y); | 
 |  | 
 |   void checkIsEqual(const Json::Value& x, const Json::Value& y); | 
 |  | 
 |   /// Normalize the representation of floating-point number by stripped leading | 
 |   /// 0 in exponent. | 
 |   static Json::String normalizeFloatingPointStr(const Json::String& s); | 
 | }; | 
 |  | 
 | Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { | 
 |   auto index = s.find_last_of("eE"); | 
 |   if (index == s.npos) | 
 |     return s; | 
 |   std::size_t signWidth = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; | 
 |   auto exponentStartIndex = index + 1 + signWidth; | 
 |   Json::String normalized = s.substr(0, exponentStartIndex); | 
 |   auto indexDigit = s.find_first_not_of('0', exponentStartIndex); | 
 |   Json::String exponent = "0"; | 
 |   if (indexDigit != s.npos) { // nonzero exponent | 
 |     exponent = s.substr(indexDigit); | 
 |   } | 
 |   return normalized + exponent; | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, checkNormalizeFloatingPointStr) { | 
 |   struct TestData { | 
 |     std::string in; | 
 |     std::string out; | 
 |   } const testData[] = { | 
 |       {"0.0", "0.0"}, | 
 |       {"0e0", "0e0"}, | 
 |       {"1234.0", "1234.0"}, | 
 |       {"1234.0e0", "1234.0e0"}, | 
 |       {"1234.0e-1", "1234.0e-1"}, | 
 |       {"1234.0e+0", "1234.0e+0"}, | 
 |       {"1234.0e+001", "1234.0e+1"}, | 
 |       {"1234e-1", "1234e-1"}, | 
 |       {"1234e+000", "1234e+0"}, | 
 |       {"1234e+001", "1234e+1"}, | 
 |       {"1234e10", "1234e10"}, | 
 |       {"1234e010", "1234e10"}, | 
 |       {"1234e+010", "1234e+10"}, | 
 |       {"1234e-010", "1234e-10"}, | 
 |       {"1234e+100", "1234e+100"}, | 
 |       {"1234e-100", "1234e-100"}, | 
 |   }; | 
 |   for (const auto& td : testData) { | 
 |     JSONTEST_ASSERT_STRING_EQUAL(normalizeFloatingPointStr(td.in), td.out); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, memberCount) { | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(emptyArray_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(emptyObject_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(array1_, 1)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(object1_, 1)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(null_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(integer_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(unsignedInteger_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(smallUnsignedInteger_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(real_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(emptyString_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(string_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(true_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(false_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(string1_, 0)); | 
 |   JSONTEST_ASSERT_PRED(checkMemberCount(float_, 0)); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { | 
 |   // Types | 
 |   IsCheck checks; | 
 |   checks.isObject_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(emptyObject_, checks)); | 
 |   JSONTEST_ASSERT_PRED(checkIs(object1_, checks)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::objectValue, emptyObject_.type()); | 
 |  | 
 |   // Empty object okay | 
 |   JSONTEST_ASSERT(emptyObject_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Non-empty object not okay | 
 |   JSONTEST_ASSERT(!object1_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Always okay | 
 |   JSONTEST_ASSERT(emptyObject_.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   // Never okay | 
 |   JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::stringValue)); | 
 |  | 
 |   // Access through const reference | 
 |   const Json::Value& constObject = object1_; | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), constObject["id"]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(), constObject["unknown id"]); | 
 |  | 
 |   // Access through find() | 
 |   const char idKey[] = "id"; | 
 |   const Json::Value* foundId = object1_.find(idKey, idKey + strlen(idKey)); | 
 |   JSONTEST_ASSERT(foundId != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), *foundId); | 
 |  | 
 |   const std::string stringIdKey = "id"; | 
 |   const Json::Value* stringFoundId = object1_.find(stringIdKey); | 
 |   JSONTEST_ASSERT(stringFoundId != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), *stringFoundId); | 
 |  | 
 |   const char unknownIdKey[] = "unknown id"; | 
 |   const Json::Value* foundUnknownId = | 
 |       object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); | 
 |   JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); | 
 |  | 
 |   const std::string stringUnknownIdKey = "unknown id"; | 
 |   const Json::Value* stringFoundUnknownId = object1_.find(stringUnknownIdKey); | 
 |   JSONTEST_ASSERT_EQUAL(nullptr, stringFoundUnknownId); | 
 |  | 
 |   // Access through find<Type>() | 
 |   const Json::Value* nullFound = object2_.findNull("null"); | 
 |   JSONTEST_ASSERT(nullFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::nullValue, *nullFound); | 
 |   JSONTEST_ASSERT(object3_.findNull("null") == nullptr); | 
 |  | 
 |   const Json::Value* boolFound = object2_.findBool("bool"); | 
 |   JSONTEST_ASSERT(boolFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(true, *boolFound); | 
 |   JSONTEST_ASSERT(object3_.findBool("bool") == nullptr); | 
 |  | 
 |   const Json::Value* intFound = object2_.findInt("int"); | 
 |   JSONTEST_ASSERT(intFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Int{Json::Value::maxInt}, *intFound); | 
 |   JSONTEST_ASSERT(object3_.findInt("int") == nullptr); | 
 |  | 
 |   const Json::Value* int64Found = object2_.findInt64("int64"); | 
 |   JSONTEST_ASSERT(int64Found != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Int64{Json::Value::maxInt64}, *int64Found); | 
 |   JSONTEST_ASSERT(object3_.findInt64("int64") == nullptr); | 
 |  | 
 |   const Json::Value* uintFound = object2_.findUInt("uint"); | 
 |   JSONTEST_ASSERT(uintFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::UInt{Json::Value::maxUInt}, *uintFound); | 
 |   JSONTEST_ASSERT(object3_.findUInt("uint") == nullptr); | 
 |  | 
 |   const Json::Value* uint64Found = object2_.findUInt64("uint64"); | 
 |   JSONTEST_ASSERT(uint64Found != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::UInt64{Json::Value::maxUInt64}, *uint64Found); | 
 |   JSONTEST_ASSERT(object3_.findUInt64("uint64") == nullptr); | 
 |  | 
 |   const Json::Value* integralFound = object2_.findIntegral("integral"); | 
 |   JSONTEST_ASSERT(integralFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(1234, *integralFound); | 
 |   JSONTEST_ASSERT(object3_.findIntegral("integral") == nullptr); | 
 |  | 
 |   const Json::Value* doubleFound = object2_.findDouble("double"); | 
 |   JSONTEST_ASSERT(doubleFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(1234.56789, *doubleFound); | 
 |   JSONTEST_ASSERT(object3_.findDouble("double") == nullptr); | 
 |  | 
 |   const Json::Value* numericFound = object2_.findNumeric("numeric"); | 
 |   JSONTEST_ASSERT(numericFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(0.12345f, *numericFound); | 
 |   JSONTEST_ASSERT(object3_.findNumeric("numeric") == nullptr); | 
 |  | 
 |   const Json::Value* stringFound = object2_.findString("string"); | 
 |   JSONTEST_ASSERT(stringFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(std::string{"string"}, *stringFound); | 
 |   JSONTEST_ASSERT(object3_.findString("string") == nullptr); | 
 |  | 
 |   const Json::Value* arrayFound = object2_.findArray("array"); | 
 |   JSONTEST_ASSERT(arrayFound != nullptr); | 
 |   JSONTEST_ASSERT_EQUAL(Json::arrayValue, *arrayFound); | 
 |   JSONTEST_ASSERT(object3_.findArray("array") == nullptr); | 
 |  | 
 |   // Access through demand() | 
 |   const char yetAnotherIdKey[] = "yet another id"; | 
 |   const Json::Value* foundYetAnotherId = | 
 |       object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); | 
 |   JSONTEST_ASSERT_EQUAL(nullptr, foundYetAnotherId); | 
 |   Json::Value* demandedYetAnotherId = object1_.demand( | 
 |       yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); | 
 |   JSONTEST_ASSERT(demandedYetAnotherId != nullptr); | 
 |   *demandedYetAnotherId = "baz"; | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("baz"), object1_["yet another id"]); | 
 |  | 
 |   // Access through non-const reference | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), object1_["id"]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(), object1_["unknown id"]); | 
 |  | 
 |   object1_["some other id"] = "foo"; | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("foo"), object1_["some other id"]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("foo"), object1_["some other id"]); | 
 |  | 
 |   // Remove. | 
 |   Json::Value got; | 
 |   bool did; | 
 |   did = object1_.removeMember("some other id", &got); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("foo"), got); | 
 |   JSONTEST_ASSERT_EQUAL(true, did); | 
 |   got = Json::Value("bar"); | 
 |   did = object1_.removeMember("some other id", &got); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("bar"), got); | 
 |   JSONTEST_ASSERT_EQUAL(false, did); | 
 |  | 
 |   object1_["some other id"] = "foo"; | 
 |   Json::Value* gotPtr = nullptr; | 
 |   did = object1_.removeMember("some other id", gotPtr); | 
 |   JSONTEST_ASSERT_EQUAL(nullptr, gotPtr); | 
 |   JSONTEST_ASSERT_EQUAL(true, did); | 
 |  | 
 |   // Using other removeMember interfaces, the test idea is the same as above. | 
 |   object1_["some other id"] = "foo"; | 
 |   const Json::String key("some other id"); | 
 |   did = object1_.removeMember(key, &got); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("foo"), got); | 
 |   JSONTEST_ASSERT_EQUAL(true, did); | 
 |   got = Json::Value("bar"); | 
 |   did = object1_.removeMember(key, &got); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("bar"), got); | 
 |   JSONTEST_ASSERT_EQUAL(false, did); | 
 |  | 
 |   object1_["some other id"] = "foo"; | 
 |   object1_.removeMember(key); | 
 |   JSONTEST_ASSERT_EQUAL(Json::nullValue, object1_[key]); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { | 
 |   const unsigned int index0 = 0; | 
 |  | 
 |   // Types | 
 |   IsCheck checks; | 
 |   checks.isArray_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(emptyArray_, checks)); | 
 |   JSONTEST_ASSERT_PRED(checkIs(array1_, checks)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::arrayValue, array1_.type()); | 
 |  | 
 |   // Empty array okay | 
 |   JSONTEST_ASSERT(emptyArray_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Non-empty array not okay | 
 |   JSONTEST_ASSERT(!array1_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Always okay | 
 |   JSONTEST_ASSERT(emptyArray_.isConvertibleTo(Json::arrayValue)); | 
 |  | 
 |   // Never okay | 
 |   JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::objectValue)); | 
 |   JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::stringValue)); | 
 |  | 
 |   // Access through const reference | 
 |   const Json::Value& constArray = array1_; | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray[index0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray[0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray.front()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray.back()); | 
 |  | 
 |   // Access through non-const reference | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_[index0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_[0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_.front()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_.back()); | 
 |  | 
 |   array1_[2] = Json::Value(17); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(), array1_[1]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(17), array1_[2]); | 
 |   Json::Value got; | 
 |   JSONTEST_ASSERT_EQUAL(true, array1_.removeIndex(2, &got)); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(17), got); | 
 |   JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { | 
 |   Json::Value array; | 
 |   { | 
 |     for (Json::ArrayIndex i = 0; i < 10; i++) | 
 |       array[i] = i; | 
 |     JSONTEST_ASSERT_EQUAL(array.size(), 10); | 
 |     // The length set is greater than the length of the array. | 
 |     array.resize(15); | 
 |     JSONTEST_ASSERT_EQUAL(array.size(), 15); | 
 |  | 
 |     // The length set is less than the length of the array. | 
 |     array.resize(5); | 
 |     JSONTEST_ASSERT_EQUAL(array.size(), 5); | 
 |  | 
 |     // The length of the array is set to 0. | 
 |     array.resize(0); | 
 |     JSONTEST_ASSERT_EQUAL(array.size(), 0); | 
 |   } | 
 |   { | 
 |     for (Json::ArrayIndex i = 0; i < 10; i++) | 
 |       array[i] = i; | 
 |     JSONTEST_ASSERT_EQUAL(array.size(), 10); | 
 |     array.clear(); | 
 |     JSONTEST_ASSERT_EQUAL(array.size(), 0); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, resizePopulatesAllMissingElements) { | 
 |   Json::ArrayIndex n = 10; | 
 |   Json::Value v; | 
 |   v.resize(n); | 
 |   JSONTEST_ASSERT_EQUAL(n, v.size()); | 
 |   JSONTEST_ASSERT_EQUAL(n, std::distance(v.begin(), v.end())); | 
 |   JSONTEST_ASSERT_EQUAL(v.front(), Json::Value{}); | 
 |   JSONTEST_ASSERT_EQUAL(v.back(), Json::Value{}); | 
 |   for (const Json::Value& e : v) | 
 |     JSONTEST_ASSERT_EQUAL(e, Json::Value{}); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, getArrayValue) { | 
 |   Json::Value array; | 
 |   for (Json::ArrayIndex i = 0; i < 5; i++) | 
 |     array[i] = i; | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(array.size(), 5); | 
 |   const Json::Value defaultValue(10); | 
 |   Json::ArrayIndex index = 0; | 
 |   for (; index <= 4; index++) | 
 |     JSONTEST_ASSERT_EQUAL(index, array.get(index, defaultValue).asInt()); | 
 |  | 
 |   index = 4; | 
 |   JSONTEST_ASSERT_EQUAL(array.isValidIndex(index), true); | 
 |   index = 5; | 
 |   JSONTEST_ASSERT_EQUAL(array.isValidIndex(index), false); | 
 |   JSONTEST_ASSERT_EQUAL(defaultValue, array.get(index, defaultValue)); | 
 |   JSONTEST_ASSERT_EQUAL(array.isValidIndex(index), false); | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, arrayIssue252) { | 
 |   int count = 5; | 
 |   Json::Value root; | 
 |   Json::Value item; | 
 |   root["array"] = Json::Value::nullSingleton(); | 
 |   for (int i = 0; i < count; i++) { | 
 |     item["a"] = i; | 
 |     item["b"] = i; | 
 |     root["array"][i] = item; | 
 |   } | 
 |   // JSONTEST_ASSERT_EQUAL(5, root["array"].size()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { | 
 |   Json::Value array; | 
 |   const Json::Value str0("index2"); | 
 |   const Json::Value str1("index3"); | 
 |   array.append("index0"); // append rvalue | 
 |   array.append("index1"); | 
 |   array.append(str0); // append lvalue | 
 |  | 
 |   std::vector<Json::Value*> vec; // storage value address for checking | 
 |   for (Json::ArrayIndex i = 0; i < 3; i++) { | 
 |     vec.push_back(&array[i]); | 
 |   } | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]); // check append | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array.front()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array.back()); | 
 |  | 
 |   // insert lvalue at the head | 
 |   JSONTEST_ASSERT(array.insert(0, str1)); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[2]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[3]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array.front()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array.back()); | 
 |   // checking address | 
 |   for (Json::ArrayIndex i = 0; i < 3; i++) { | 
 |     JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); | 
 |   } | 
 |   vec.push_back(&array[3]); | 
 |   // insert rvalue at middle | 
 |   JSONTEST_ASSERT(array.insert(2, "index4")); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array.front()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array.back()); | 
 |   // checking address | 
 |   for (Json::ArrayIndex i = 0; i < 4; i++) { | 
 |     JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); | 
 |   } | 
 |   vec.push_back(&array[4]); | 
 |   // insert rvalue at the tail | 
 |   JSONTEST_ASSERT(array.insert(5, "index5")); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array[5]); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array.front()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array.back()); | 
 |   // checking address | 
 |   for (Json::ArrayIndex i = 0; i < 5; i++) { | 
 |     JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); | 
 |   } | 
 |   vec.push_back(&array[5]); | 
 |   // beyond max array size, it should not be allowed to insert into its tail | 
 |   JSONTEST_ASSERT(!array.insert(10, "index10")); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, null) { | 
 |   JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type()); | 
 |  | 
 |   IsCheck checks; | 
 |   checks.isNull_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(null_, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(null_.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::Int(0), null_.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::LargestInt(0), null_.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::UInt(0), null_.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::LargestUInt(0), null_.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, null_.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, null_.asFloat()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("", null_.asString()); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value::nullSingleton(), null_); | 
 |  | 
 |   // Test using a Value in a boolean context (false iff null) | 
 |   JSONTEST_ASSERT_EQUAL(null_, false); | 
 |   JSONTEST_ASSERT_EQUAL(object1_, true); | 
 |   JSONTEST_ASSERT_EQUAL(!null_, true); | 
 |   JSONTEST_ASSERT_EQUAL(!object1_, false); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, strings) { | 
 |   JSONTEST_ASSERT_EQUAL(Json::stringValue, string1_.type()); | 
 |  | 
 |   IsCheck checks; | 
 |   checks.isString_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(emptyString_, checks)); | 
 |   JSONTEST_ASSERT_PRED(checkIs(string_, checks)); | 
 |   JSONTEST_ASSERT_PRED(checkIs(string1_, checks)); | 
 |  | 
 |   // Empty string okay | 
 |   JSONTEST_ASSERT(emptyString_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Non-empty string not okay | 
 |   JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Always okay | 
 |   JSONTEST_ASSERT(string1_.isConvertibleTo(Json::stringValue)); | 
 |  | 
 |   // Never okay | 
 |   JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::objectValue)); | 
 |   JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::realValue)); | 
 |  | 
 |   JSONTEST_ASSERT_STRING_EQUAL("a", string1_.asString()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("a", string1_.asCString()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, bools) { | 
 |   JSONTEST_ASSERT_EQUAL(Json::booleanValue, false_.type()); | 
 |  | 
 |   IsCheck checks; | 
 |   checks.isBool_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(false_, checks)); | 
 |   JSONTEST_ASSERT_PRED(checkIs(true_, checks)); | 
 |  | 
 |   // False okay | 
 |   JSONTEST_ASSERT(false_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // True not okay | 
 |   JSONTEST_ASSERT(!true_.isConvertibleTo(Json::nullValue)); | 
 |  | 
 |   // Always okay | 
 |   JSONTEST_ASSERT(true_.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(true_.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(true_.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(true_.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(true_.isConvertibleTo(Json::stringValue)); | 
 |  | 
 |   // Never okay | 
 |   JSONTEST_ASSERT(!true_.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!true_.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(true, true_.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL(1, true_.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1, true_.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1, true_.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1, true_.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1.0, true_.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(1.0, true_.asFloat()); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(false, false_.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL(0, false_.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, false_.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, false_.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, false_.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, false_.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, false_.asFloat()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, integers) { | 
 |   IsCheck checks; | 
 |   Json::Value val; | 
 |  | 
 |   // Conversions that don't depend on the value. | 
 |   JSONTEST_ASSERT(Json::Value(17).isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(Json::Value(17).isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(Json::Value(17).isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(!Json::Value(17).isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!Json::Value(17).isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT(Json::Value(17U).isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(Json::Value(17U).isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(Json::Value(17U).isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(!Json::Value(17U).isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!Json::Value(17U).isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT(Json::Value(17.0).isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(Json::Value(17.0).isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(Json::Value(17.0).isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(!Json::Value(17.0).isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!Json::Value(17.0).isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   // Default int | 
 |   val = Json::Value(Json::intValue); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(false, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("0", val.asString()); | 
 |  | 
 |   // Default uint | 
 |   val = Json::Value(Json::uintValue); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(false, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("0", val.asString()); | 
 |  | 
 |   // Default real | 
 |   val = Json::Value(Json::realValue); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(false, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("0.0", val.asString()); | 
 |  | 
 |   // Zero (signed constructor arg) | 
 |   val = Json::Value(0); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(false, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("0", val.asString()); | 
 |  | 
 |   // Zero (unsigned constructor arg) | 
 |   val = Json::Value(0u); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(false, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("0", val.asString()); | 
 |  | 
 |   // Zero (floating-point constructor arg) | 
 |   val = Json::Value(0.0); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(0.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(false, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("0.0", val.asString()); | 
 |  | 
 |   // 2^20 (signed constructor arg) | 
 |   val = Json::Value(1 << 20); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("1048576", val.asString()); | 
 |  | 
 |   // 2^20 (unsigned constructor arg) | 
 |   val = Json::Value(Json::UInt(1 << 20)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("1048576", val.asString()); | 
 |  | 
 |   // 2^20 (floating-point constructor arg) | 
 |   val = Json::Value((1 << 20) / 1.0); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "1048576.0", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // -2^20 | 
 |   val = Json::Value(-(1 << 20)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("-1048576", val.asString()); | 
 |  | 
 |   // int32 max | 
 |   val = Json::Value(kint32max); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(kint32max, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32max, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32max, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32max, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32max, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(kfint32max, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("2147483647", val.asString()); | 
 |  | 
 |   // int32 min | 
 |   val = Json::Value(kint32min); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt_ = true; | 
 |   checks.isInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(kint32min, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32min, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32min, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(kint32min, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("-2147483648", val.asString()); | 
 |  | 
 |   // uint32 max | 
 |   val = Json::Value(kuint32max); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 | #ifndef JSON_NO_INT64 | 
 |   JSONTEST_ASSERT_EQUAL(kuint32max, val.asLargestInt()); | 
 | #endif | 
 |   JSONTEST_ASSERT_EQUAL(kuint32max, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kuint32max, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kuint32max, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(kfuint32max, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("4294967295", val.asString()); | 
 |  | 
 | #ifdef JSON_NO_INT64 | 
 |   // int64 max | 
 |   val = Json::Value(double(kint64max)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(double(kint64max), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(kint64max), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("9.22337e+18", val.asString()); | 
 |  | 
 |   // int64 min | 
 |   val = Json::Value(double(kint64min)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(double(kint64min), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(kint64min), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("-9.22337e+18", val.asString()); | 
 |  | 
 |   // uint64 max | 
 |   val = Json::Value(double(kuint64max)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(double(kuint64max), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(kuint64max), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("1.84467e+19", val.asString()); | 
 | #else // ifdef JSON_NO_INT64 | 
 |   // 2^40 (signed constructor arg) | 
 |   val = Json::Value(Json::Int64(1) << 40); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asInt64()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("1099511627776", val.asString()); | 
 |  | 
 |   // 2^40 (unsigned constructor arg) | 
 |   val = Json::Value(Json::UInt64(1) << 40); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asInt64()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("1099511627776", val.asString()); | 
 |  | 
 |   // 2^40 (floating-point constructor arg) | 
 |   val = Json::Value((Json::Int64(1) << 40) / 1.0); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asInt64()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "1099511627776.0", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // -2^40 | 
 |   val = Json::Value(-(Json::Int64(1) << 40)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 40), val.asInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 40), val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 40), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 40), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("-1099511627776", val.asString()); | 
 |  | 
 |   // int64 max | 
 |   val = Json::Value(Json::Int64(kint64max)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(kint64max, val.asInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(kint64max, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(kint64max, val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(kint64max, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(double(kint64max), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(kint64max), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("9223372036854775807", val.asString()); | 
 |  | 
 |   // int64 max (floating point constructor). Note that kint64max is not exactly | 
 |   // representable as a double, and will be rounded up to be higher. | 
 |   val = Json::Value(double(kint64max)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::UInt64(1) << 63, val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::UInt64(1) << 63, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(uint64ToDouble(Json::UInt64(1) << 63), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(Json::UInt64(1) << 63), val.asFloat()); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "9.2233720368547758e+18", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // int64 min | 
 |   val = Json::Value(Json::Int64(kint64min)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::intValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(kint64min, val.asInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(kint64min, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(double(kint64min), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(kint64min), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("-9223372036854775808", val.asString()); | 
 |  | 
 |   // int64 min (floating point constructor). Since double values in proximity of | 
 |   // kint64min are rounded to kint64min, we don't check for conversion to int64. | 
 |   val = Json::Value(double(kint64min)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "-9.2233720368547758e+18", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // 10^19 | 
 |   const auto ten_to_19 = static_cast<Json::UInt64>(1e19); | 
 |   val = Json::Value(Json::UInt64(ten_to_19)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(ten_to_19, val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(ten_to_19, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(uint64ToDouble(ten_to_19), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(uint64ToDouble(ten_to_19)), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("10000000000000000000", val.asString()); | 
 |  | 
 |   // 10^19 (double constructor). Note that 10^19 is not exactly representable | 
 |   // as a double. | 
 |   val = Json::Value(uint64ToDouble(ten_to_19)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(1e19, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(1e19, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "1e+19", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // uint64 max | 
 |   val = Json::Value(Json::UInt64(kuint64max)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isUInt64_ = true; | 
 |   checks.isIntegral_ = true; | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(kuint64max, val.asUInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(kuint64max, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(uint64ToDouble(kuint64max), val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(uint64ToDouble(kuint64max)), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("18446744073709551615", val.asString()); | 
 |  | 
 |   // uint64 max (floating point constructor). Note that kuint64max is not | 
 |   // exactly representable as a double, and will be rounded up to be higher. | 
 |   val = Json::Value(uint64ToDouble(kuint64max)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "1.8446744073709552e+19", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 | #endif | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, nonIntegers) { | 
 |   IsCheck checks; | 
 |   Json::Value val; | 
 |  | 
 |   // Small positive number | 
 |   val = Json::Value(1.5); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(1.5, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(1.5, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(1, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1, val.asUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(1, val.asLargestUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL("1.5", val.asString()); | 
 |  | 
 |   // Small negative number | 
 |   val = Json::Value(-1.5); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(-1.5, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(-1.5, val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(-1, val.asInt()); | 
 |   JSONTEST_ASSERT_EQUAL(-1, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL("-1.5", val.asString()); | 
 |  | 
 |   // A bit over int32 max | 
 |   val = Json::Value(kint32max + 0.5); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(2147483647.5, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(2147483647.5), val.asFloat()); | 
 |   JSONTEST_ASSERT_EQUAL(2147483647U, val.asUInt()); | 
 | #ifdef JSON_HAS_INT64 | 
 |   JSONTEST_ASSERT_EQUAL(2147483647L, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL(2147483647U, val.asLargestUInt()); | 
 | #endif | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL( | 
 |       "2147483647.5", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // A bit under int32 min | 
 |   val = Json::Value(kint32min - 0.5); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(-2147483648.5, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(-2147483648.5), val.asFloat()); | 
 | #ifdef JSON_HAS_INT64 | 
 |   JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 31), val.asLargestInt()); | 
 | #endif | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL( | 
 |       "-2147483648.5", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // A bit over uint32 max | 
 |   val = Json::Value(kuint32max + 0.5); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); | 
 |  | 
 |   checks = IsCheck(); | 
 |   checks.isDouble_ = true; | 
 |   checks.isNumeric_ = true; | 
 |   JSONTEST_ASSERT_PRED(checkIs(val, checks)); | 
 |  | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue)); | 
 |   JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue)); | 
 |   JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue)); | 
 |  | 
 |   JSONTEST_ASSERT_EQUAL(4294967295.5, val.asDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(float(4294967295.5), val.asFloat()); | 
 | #ifdef JSON_HAS_INT64 | 
 |   JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 32) - 1, val.asLargestInt()); | 
 |   JSONTEST_ASSERT_EQUAL((Json::UInt64(1) << 32) - Json::UInt64(1), | 
 |                         val.asLargestUInt()); | 
 | #endif | 
 |   JSONTEST_ASSERT_EQUAL(true, val.asBool()); | 
 |   JSONTEST_ASSERT_EQUAL( | 
 |       "4294967295.5", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   val = Json::Value(1.2345678901234); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "1.2345678901234001", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // A 16-digit floating point number. | 
 |   val = Json::Value(2199023255552000.0f); | 
 |   JSONTEST_ASSERT_EQUAL(float(2199023255552000.0f), val.asFloat()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "2199023255552000.0", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // A very large floating point number. | 
 |   val = Json::Value(3.402823466385289e38); | 
 |   JSONTEST_ASSERT_EQUAL(float(3.402823466385289e38), val.asFloat()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "3.402823466385289e+38", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 |  | 
 |   // An even larger floating point number. | 
 |   val = Json::Value(1.2345678e300); | 
 |   JSONTEST_ASSERT_EQUAL(double(1.2345678e300), val.asDouble()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL( | 
 |       "1.2345678e+300", | 
 |       normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); | 
 | } | 
 |  | 
 | void ValueTest::checkConstMemberCount(const Json::Value& value, | 
 |                                       unsigned int expectedCount) { | 
 |   unsigned int count = 0; | 
 |   Json::Value::const_iterator itEnd = value.end(); | 
 |   for (Json::Value::const_iterator it = value.begin(); it != itEnd; ++it) { | 
 |     ++count; | 
 |   } | 
 |   JSONTEST_ASSERT_EQUAL(expectedCount, count) << "Json::Value::const_iterator"; | 
 | } | 
 |  | 
 | void ValueTest::checkMemberCount(Json::Value& value, | 
 |                                  unsigned int expectedCount) { | 
 |   JSONTEST_ASSERT_EQUAL(expectedCount, value.size()); | 
 |  | 
 |   unsigned int count = 0; | 
 |   Json::Value::iterator itEnd = value.end(); | 
 |   for (Json::Value::iterator it = value.begin(); it != itEnd; ++it) { | 
 |     ++count; | 
 |   } | 
 |   JSONTEST_ASSERT_EQUAL(expectedCount, count) << "Json::Value::iterator"; | 
 |  | 
 |   JSONTEST_ASSERT_PRED(checkConstMemberCount(value, expectedCount)); | 
 | } | 
 |  | 
 | ValueTest::IsCheck::IsCheck() = default; | 
 |  | 
 | void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { | 
 |   JSONTEST_ASSERT_EQUAL(check.isObject_, value.isObject()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isArray_, value.isArray()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isBool_, value.isBool()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isDouble_, value.isDouble()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isInt_, value.isInt()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isUInt_, value.isUInt()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isIntegral_, value.isIntegral()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isNumeric_, value.isNumeric()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isString_, value.isString()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isNull_, value.isNull()); | 
 |  | 
 | #ifdef JSON_HAS_INT64 | 
 |   JSONTEST_ASSERT_EQUAL(check.isInt64_, value.isInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(check.isUInt64_, value.isUInt64()); | 
 | #else | 
 |   JSONTEST_ASSERT_EQUAL(false, value.isInt64()); | 
 |   JSONTEST_ASSERT_EQUAL(false, value.isUInt64()); | 
 | #endif | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareNull) { | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value(), Json::Value())); | 
 |   JSONTEST_ASSERT_PRED( | 
 |       checkIsEqual(Json::Value::nullSingleton(), Json::Value())); | 
 |   JSONTEST_ASSERT_PRED( | 
 |       checkIsEqual(Json::Value::nullSingleton(), Json::Value::nullSingleton())); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareInt) { | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(0, 10)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(10, 10)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(-10, -10)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(-10, 0)); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareUInt) { | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(0u, 10u)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(0u, Json::Value::maxUInt)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(10u, 10u)); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareDouble) { | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(0.0, 10.0)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(10.0, 10.0)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(-10.0, -10.0)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(-10.0, 0.0)); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareString) { | 
 |   JSONTEST_ASSERT_PRED(checkIsLess("", " ")); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess("", "a")); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess("abcd", "zyui")); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess("abc", "abcd")); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual("abcd", "abcd")); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(" ", " ")); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess("ABCD", "abcd")); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual("ABCD", "ABCD")); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareBoolean) { | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(false, true)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(false, false)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(true, true)); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareArray) { | 
 |   // array compare size then content | 
 |   Json::Value emptyArray(Json::arrayValue); | 
 |   Json::Value l1aArray; | 
 |   l1aArray.append(0); | 
 |   Json::Value l1bArray; | 
 |   l1bArray.append(10); | 
 |   Json::Value l2aArray; | 
 |   l2aArray.append(0); | 
 |   l2aArray.append(0); | 
 |   Json::Value l2bArray; | 
 |   l2bArray.append(0); | 
 |   l2bArray.append(10); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(emptyArray, l1aArray)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(emptyArray, l2aArray)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(l1aArray, l1bArray)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(l1bArray, l2aArray)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(l2aArray, l2bArray)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(emptyArray, Json::Value(emptyArray))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l1aArray, Json::Value(l1aArray))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l1bArray, Json::Value(l1bArray))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l2aArray, Json::Value(l2aArray))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l2bArray, Json::Value(l2bArray))); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareObject) { | 
 |   // object compare size then content | 
 |   Json::Value emptyObject(Json::objectValue); | 
 |   Json::Value l1aObject; | 
 |   l1aObject["key1"] = 0; | 
 |   Json::Value l1bObject; | 
 |   l1bObject["key1"] = 10; | 
 |   Json::Value l2aObject; | 
 |   l2aObject["key1"] = 0; | 
 |   l2aObject["key2"] = 0; | 
 |   Json::Value l2bObject; | 
 |   l2bObject["key1"] = 10; | 
 |   l2bObject["key2"] = 0; | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(emptyObject, l1aObject)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(l1aObject, l1bObject)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(l1bObject, l2aObject)); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(l2aObject, l2bObject)); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(emptyObject, Json::Value(emptyObject))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l1aObject, Json::Value(l1aObject))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l1bObject, Json::Value(l1bObject))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l2aObject, Json::Value(l2aObject))); | 
 |   JSONTEST_ASSERT_PRED(checkIsEqual(l2bObject, Json::Value(l2bObject))); | 
 |   { | 
 |     Json::Value aObject; | 
 |     aObject["a"] = 10; | 
 |     Json::Value bObject; | 
 |     bObject["b"] = 0; | 
 |     Json::Value cObject; | 
 |     cObject["c"] = 20; | 
 |     cObject["f"] = 15; | 
 |     Json::Value dObject; | 
 |     dObject["d"] = -2; | 
 |     dObject["e"] = 10; | 
 |     JSONTEST_ASSERT_PRED(checkIsLess(aObject, bObject)); | 
 |     JSONTEST_ASSERT_PRED(checkIsLess(bObject, cObject)); | 
 |     JSONTEST_ASSERT_PRED(checkIsLess(cObject, dObject)); | 
 |     JSONTEST_ASSERT_PRED(checkIsEqual(aObject, Json::Value(aObject))); | 
 |     JSONTEST_ASSERT_PRED(checkIsEqual(bObject, Json::Value(bObject))); | 
 |     JSONTEST_ASSERT_PRED(checkIsEqual(cObject, Json::Value(cObject))); | 
 |     JSONTEST_ASSERT_PRED(checkIsEqual(dObject, Json::Value(dObject))); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, compareType) { | 
 |   // object of different type are ordered according to their type | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(), Json::Value(1))); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(1), Json::Value(1u))); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(1u), Json::Value(1.0))); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(1.0), Json::Value("a"))); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(Json::Value("a"), Json::Value(true))); | 
 |   JSONTEST_ASSERT_PRED( | 
 |       checkIsLess(Json::Value(true), Json::Value(Json::arrayValue))); | 
 |   JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(Json::arrayValue), | 
 |                                    Json::Value(Json::objectValue))); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, CopyObject) { | 
 |   Json::Value arrayVal; | 
 |   arrayVal.append("val1"); | 
 |   arrayVal.append("val2"); | 
 |   arrayVal.append("val3"); | 
 |   Json::Value stringVal("string value"); | 
 |   Json::Value copy1, copy2; | 
 |   { | 
 |     Json::Value arrayCopy, stringCopy; | 
 |     arrayCopy.copy(arrayVal); | 
 |     stringCopy.copy(stringVal); | 
 |     JSONTEST_ASSERT_PRED(checkIsEqual(arrayCopy, arrayVal)); | 
 |     JSONTEST_ASSERT_PRED(checkIsEqual(stringCopy, stringVal)); | 
 |     arrayCopy.append("val4"); | 
 |     JSONTEST_ASSERT(arrayCopy.size() == 4); | 
 |     arrayVal.append("new4"); | 
 |     arrayVal.append("new5"); | 
 |     JSONTEST_ASSERT(arrayVal.size() == 5); | 
 |     JSONTEST_ASSERT(!(arrayCopy == arrayVal)); | 
 |     stringCopy = "another string"; | 
 |     JSONTEST_ASSERT(!(stringCopy == stringVal)); | 
 |     copy1.copy(arrayCopy); | 
 |     copy2.copy(stringCopy); | 
 |   } | 
 |   JSONTEST_ASSERT(arrayVal.size() == 5); | 
 |   JSONTEST_ASSERT(stringVal == "string value"); | 
 |   JSONTEST_ASSERT(copy1.size() == 4); | 
 |   JSONTEST_ASSERT(copy2 == "another string"); | 
 |   copy1.copy(stringVal); | 
 |   JSONTEST_ASSERT(copy1 == "string value"); | 
 |   copy2.copy(arrayVal); | 
 |   JSONTEST_ASSERT(copy2.size() == 5); | 
 |   { | 
 |     Json::Value srcObject, objectCopy, otherObject; | 
 |     srcObject["key0"] = 10; | 
 |     objectCopy.copy(srcObject); | 
 |     JSONTEST_ASSERT(srcObject["key0"] == 10); | 
 |     JSONTEST_ASSERT(objectCopy["key0"] == 10); | 
 |     JSONTEST_ASSERT(srcObject.getMemberNames().size() == 1); | 
 |     JSONTEST_ASSERT(objectCopy.getMemberNames().size() == 1); | 
 |     otherObject["key1"] = 15; | 
 |     otherObject["key2"] = 16; | 
 |     JSONTEST_ASSERT(otherObject.getMemberNames().size() == 2); | 
 |     objectCopy.copy(otherObject); | 
 |     JSONTEST_ASSERT(objectCopy["key1"] == 15); | 
 |     JSONTEST_ASSERT(objectCopy["key2"] == 16); | 
 |     JSONTEST_ASSERT(objectCopy.getMemberNames().size() == 2); | 
 |     otherObject["key1"] = 20; | 
 |     JSONTEST_ASSERT(objectCopy["key1"] == 15); | 
 |   } | 
 | } | 
 |  | 
 | void ValueTest::checkIsLess(const Json::Value& x, const Json::Value& y) { | 
 |   JSONTEST_ASSERT(x < y); | 
 |   JSONTEST_ASSERT(y > x); | 
 |   JSONTEST_ASSERT(x <= y); | 
 |   JSONTEST_ASSERT(y >= x); | 
 |   JSONTEST_ASSERT(!(x == y)); | 
 |   JSONTEST_ASSERT(!(y == x)); | 
 |   JSONTEST_ASSERT(!(x >= y)); | 
 |   JSONTEST_ASSERT(!(y <= x)); | 
 |   JSONTEST_ASSERT(!(x > y)); | 
 |   JSONTEST_ASSERT(!(y < x)); | 
 |   JSONTEST_ASSERT(x.compare(y) < 0); | 
 |   JSONTEST_ASSERT(y.compare(x) >= 0); | 
 | } | 
 |  | 
 | void ValueTest::checkIsEqual(const Json::Value& x, const Json::Value& y) { | 
 |   JSONTEST_ASSERT(x == y); | 
 |   JSONTEST_ASSERT(y == x); | 
 |   JSONTEST_ASSERT(x <= y); | 
 |   JSONTEST_ASSERT(y <= x); | 
 |   JSONTEST_ASSERT(x >= y); | 
 |   JSONTEST_ASSERT(y >= x); | 
 |   JSONTEST_ASSERT(!(x < y)); | 
 |   JSONTEST_ASSERT(!(y < x)); | 
 |   JSONTEST_ASSERT(!(x > y)); | 
 |   JSONTEST_ASSERT(!(y > x)); | 
 |   JSONTEST_ASSERT(x.compare(y) == 0); | 
 |   JSONTEST_ASSERT(y.compare(x) == 0); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, typeChecksThrowExceptions) { | 
 | #if JSON_USE_EXCEPTION | 
 |  | 
 |   Json::Value intVal(1); | 
 |   Json::Value strVal("Test"); | 
 |   Json::Value objVal(Json::objectValue); | 
 |   Json::Value arrVal(Json::arrayValue); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal["test"]); | 
 |   JSONTEST_ASSERT_THROWS(strVal["test"]); | 
 |   JSONTEST_ASSERT_THROWS(arrVal["test"]); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal.removeMember("test")); | 
 |   JSONTEST_ASSERT_THROWS(strVal.removeMember("test")); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.removeMember("test")); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal.getMemberNames()); | 
 |   JSONTEST_ASSERT_THROWS(strVal.getMemberNames()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.getMemberNames()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal[0]); | 
 |   JSONTEST_ASSERT_THROWS(objVal[0]); | 
 |   JSONTEST_ASSERT_THROWS(strVal[0]); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal.clear()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal.resize(1)); | 
 |   JSONTEST_ASSERT_THROWS(strVal.resize(1)); | 
 |   JSONTEST_ASSERT_THROWS(objVal.resize(1)); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(intVal.asCString()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(objVal.asString()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asString()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asInt()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asInt()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asInt()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asUInt()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asUInt()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asUInt()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asInt64()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asInt64()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asInt64()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asUInt64()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asUInt64()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asUInt64()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asDouble()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asDouble()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asDouble()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asFloat()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asFloat()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asFloat()); | 
 |  | 
 |   JSONTEST_ASSERT_THROWS(strVal.asBool()); | 
 |   JSONTEST_ASSERT_THROWS(objVal.asBool()); | 
 |   JSONTEST_ASSERT_THROWS(arrVal.asBool()); | 
 |  | 
 | #endif | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, offsetAccessors) { | 
 |   Json::Value x; | 
 |   JSONTEST_ASSERT(x.getOffsetStart() == 0); | 
 |   JSONTEST_ASSERT(x.getOffsetLimit() == 0); | 
 |   x.setOffsetStart(10); | 
 |   x.setOffsetLimit(20); | 
 |   JSONTEST_ASSERT(x.getOffsetStart() == 10); | 
 |   JSONTEST_ASSERT(x.getOffsetLimit() == 20); | 
 |   Json::Value y(x); | 
 |   JSONTEST_ASSERT(y.getOffsetStart() == 10); | 
 |   JSONTEST_ASSERT(y.getOffsetLimit() == 20); | 
 |   Json::Value z; | 
 |   z.swap(y); | 
 |   JSONTEST_ASSERT(z.getOffsetStart() == 10); | 
 |   JSONTEST_ASSERT(z.getOffsetLimit() == 20); | 
 |   JSONTEST_ASSERT(y.getOffsetStart() == 0); | 
 |   JSONTEST_ASSERT(y.getOffsetLimit() == 0); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, StaticString) { | 
 |   char mutant[] = "hello"; | 
 |   Json::StaticString ss(mutant); | 
 |   Json::String regular(mutant); | 
 |   mutant[1] = 'a'; | 
 |   JSONTEST_ASSERT_STRING_EQUAL("hallo", ss.c_str()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("hello", regular.c_str()); | 
 |   { | 
 |     Json::Value root; | 
 |     root["top"] = ss; | 
 |     JSONTEST_ASSERT_STRING_EQUAL("hallo", root["top"].asString()); | 
 |     mutant[1] = 'u'; | 
 |     JSONTEST_ASSERT_STRING_EQUAL("hullo", root["top"].asString()); | 
 |   } | 
 |   { | 
 |     Json::Value root; | 
 |     root["top"] = regular; | 
 |     JSONTEST_ASSERT_STRING_EQUAL("hello", root["top"].asString()); | 
 |     mutant[1] = 'u'; | 
 |     JSONTEST_ASSERT_STRING_EQUAL("hello", root["top"].asString()); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, WideString) { | 
 |   // https://github.com/open-source-parsers/jsoncpp/issues/756 | 
 |   const std::string uni = u8"\u5f0f\uff0c\u8fdb"; // "式,进" | 
 |   std::string styled; | 
 |   { | 
 |     Json::Value v; | 
 |     v["abc"] = uni; | 
 |     styled = v.toStyledString(); | 
 |   } | 
 |   Json::Value root; | 
 |   { | 
 |     JSONCPP_STRING errs; | 
 |     std::istringstream iss(styled); | 
 |     bool ok = parseFromStream(Json::CharReaderBuilder(), iss, &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     if (!ok) { | 
 |       std::cerr << "errs: " << errs << std::endl; | 
 |     } | 
 |   } | 
 |   JSONTEST_ASSERT_STRING_EQUAL(root["abc"].asString(), uni); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, CommentBefore) { | 
 |   Json::Value val; // fill val | 
 |   val.setComment(Json::String("// this comment should appear before"), | 
 |                  Json::commentBefore); | 
 |   Json::StreamWriterBuilder wbuilder; | 
 |   wbuilder.settings_["commentStyle"] = "All"; | 
 |   { | 
 |     char const expected[] = "// this comment should appear before\nnull"; | 
 |     Json::String result = Json::writeString(wbuilder, val); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |     Json::String res2 = val.toStyledString(); | 
 |     Json::String exp2 = "\n"; | 
 |     exp2 += expected; | 
 |     exp2 += "\n"; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); | 
 |   } | 
 |   Json::Value other = "hello"; | 
 |   val.swapPayload(other); | 
 |   { | 
 |     char const expected[] = "// this comment should appear before\n\"hello\""; | 
 |     Json::String result = Json::writeString(wbuilder, val); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |     Json::String res2 = val.toStyledString(); | 
 |     Json::String exp2 = "\n"; | 
 |     exp2 += expected; | 
 |     exp2 += "\n"; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("null\n", other.toStyledString()); | 
 |   } | 
 |   val = "hello"; | 
 |   // val.setComment("// this comment should appear before", | 
 |   // Json::CommentPlacement::commentBefore); Assignment over-writes comments. | 
 |   { | 
 |     char const expected[] = "\"hello\""; | 
 |     Json::String result = Json::writeString(wbuilder, val); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |     Json::String res2 = val.toStyledString(); | 
 |     Json::String exp2; | 
 |     exp2 += expected; | 
 |     exp2 += "\n"; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, zeroes) { | 
 |   char const cstr[] = "h\0i"; | 
 |   Json::String binary(cstr, sizeof(cstr)); // include trailing 0 | 
 |   JSONTEST_ASSERT_EQUAL(4U, binary.length()); | 
 |   Json::StreamWriterBuilder b; | 
 |   { | 
 |     Json::Value root; | 
 |     root = binary; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(binary, root.asString()); | 
 |   } | 
 |   { | 
 |     char const top[] = "top"; | 
 |     Json::Value root; | 
 |     root[top] = binary; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(binary, root[top].asString()); | 
 |     Json::Value removed; | 
 |     bool did; | 
 |     did = root.removeMember(top, top + sizeof(top) - 1U, &removed); | 
 |     JSONTEST_ASSERT(did); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); | 
 |     did = root.removeMember(top, top + sizeof(top) - 1U, &removed); | 
 |     JSONTEST_ASSERT(!did); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); // still | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, zeroesInKeys) { | 
 |   char const cstr[] = "h\0i"; | 
 |   Json::String binary(cstr, sizeof(cstr)); // include trailing 0 | 
 |   JSONTEST_ASSERT_EQUAL(4U, binary.length()); | 
 |   { | 
 |     Json::Value root; | 
 |     root[binary] = "there"; | 
 |     JSONTEST_ASSERT_STRING_EQUAL("there", root[binary].asString()); | 
 |     JSONTEST_ASSERT(!root.isMember("h")); | 
 |     JSONTEST_ASSERT(root.isMember(binary)); | 
 |     JSONTEST_ASSERT_STRING_EQUAL( | 
 |         "there", root.get(binary, Json::Value::nullSingleton()).asString()); | 
 |     Json::Value removed; | 
 |     bool did; | 
 |     did = root.removeMember(binary.data(), binary.data() + binary.length(), | 
 |                             &removed); | 
 |     JSONTEST_ASSERT(did); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); | 
 |     did = root.removeMember(binary.data(), binary.data() + binary.length(), | 
 |                             &removed); | 
 |     JSONTEST_ASSERT(!did); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); // still | 
 |     JSONTEST_ASSERT(!root.isMember(binary)); | 
 |     JSONTEST_ASSERT_STRING_EQUAL( | 
 |         "", root.get(binary, Json::Value::nullSingleton()).asString()); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, specialFloats) { | 
 |   Json::StreamWriterBuilder b; | 
 |   b.settings_["useSpecialFloats"] = true; | 
 |  | 
 |   Json::Value v = std::numeric_limits<double>::quiet_NaN(); | 
 |   Json::String expected = "NaN"; | 
 |   Json::String result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   v = std::numeric_limits<double>::infinity(); | 
 |   expected = "Infinity"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   v = -std::numeric_limits<double>::infinity(); | 
 |   expected = "-Infinity"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, precision) { | 
 |   Json::StreamWriterBuilder b; | 
 |   b.settings_["precision"] = 5; | 
 |  | 
 |   Json::Value v = 100.0 / 3; | 
 |   Json::String expected = "33.333"; | 
 |   Json::String result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   v = 0.25000000; | 
 |   expected = "0.25"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   v = 0.2563456; | 
 |   expected = "0.25635"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 1; | 
 |   expected = "0.3"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 17; | 
 |   v = 1234857476305.256345694873740545068; | 
 |   expected = "1234857476305.2563"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 24; | 
 |   v = 0.256345694873740545068; | 
 |   expected = "0.25634569487374054"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 5; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 0.256345694873740545068; | 
 |   expected = "0.25635"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 1; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 0.256345694873740545068; | 
 |   expected = "0.3"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 0; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 123.56345694873740545068; | 
 |   expected = "124"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 1; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 1230.001; | 
 |   expected = "1230.0"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 0; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 1230.001; | 
 |   expected = "1230"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 0; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 1231.5; | 
 |   expected = "1232"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |  | 
 |   b.settings_["precision"] = 10; | 
 |   b.settings_["precisionType"] = "decimal"; | 
 |   v = 0.23300000; | 
 |   expected = "0.233"; | 
 |   result = Json::writeString(b, v); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(ValueTest, searchValueByPath) { | 
 |   Json::Value root, subroot; | 
 |   root["property1"][0] = 0; | 
 |   root["property1"][1] = 1; | 
 |   subroot["object"] = "object"; | 
 |   root["property2"] = subroot; | 
 |  | 
 |   const Json::Value defaultValue("error"); | 
 |   Json::FastWriter writer; | 
 |  | 
 |   { | 
 |     const Json::String expected("{" | 
 |                                 "\"property1\":[0,1]," | 
 |                                 "\"property2\":{\"object\":\"object\"}" | 
 |                                 "}\n"); | 
 |     Json::String outcome = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, outcome); | 
 |  | 
 |     // Array member exists. | 
 |     const Json::Path path1(".property1.[%]", 1); | 
 |     Json::Value result = path1.resolve(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::Value(1), result); | 
 |     result = path1.resolve(root, defaultValue); | 
 |     JSONTEST_ASSERT_EQUAL(Json::Value(1), result); | 
 |  | 
 |     // Array member does not exist. | 
 |     const Json::Path path2(".property1.[2]"); | 
 |     result = path2.resolve(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::nullValue, result); | 
 |     result = path2.resolve(root, defaultValue); | 
 |     JSONTEST_ASSERT_EQUAL(defaultValue, result); | 
 |  | 
 |     // Access array path form error | 
 |     const Json::Path path3(".property1.0"); | 
 |     result = path3.resolve(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::nullValue, result); | 
 |     result = path3.resolve(root, defaultValue); | 
 |     JSONTEST_ASSERT_EQUAL(defaultValue, result); | 
 |  | 
 |     // Object member exists. | 
 |     const Json::Path path4(".property2.%", "object"); | 
 |     result = path4.resolve(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::Value("object"), result); | 
 |     result = path4.resolve(root, defaultValue); | 
 |     JSONTEST_ASSERT_EQUAL(Json::Value("object"), result); | 
 |  | 
 |     // Object member does not exist. | 
 |     const Json::Path path5(".property2.hello"); | 
 |     result = path5.resolve(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::nullValue, result); | 
 |     result = path5.resolve(root, defaultValue); | 
 |     JSONTEST_ASSERT_EQUAL(defaultValue, result); | 
 |  | 
 |     // Access object path form error | 
 |     const Json::Path path6(".property2.[0]"); | 
 |     result = path5.resolve(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::nullValue, result); | 
 |     result = path6.resolve(root, defaultValue); | 
 |     JSONTEST_ASSERT_EQUAL(defaultValue, result); | 
 |  | 
 |     // resolve will not change the value | 
 |     outcome = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, outcome); | 
 |   } | 
 |   { | 
 |     const Json::String expected("{" | 
 |                                 "\"property1\":[0,1,null]," | 
 |                                 "\"property2\":{" | 
 |                                 "\"hello\":null," | 
 |                                 "\"object\":\"object\"}}\n"); | 
 |     Json::Path path1(".property1.[%]", 2); | 
 |     Json::Value& value1 = path1.make(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::nullValue, value1); | 
 |  | 
 |     Json::Path path2(".property2.%", "hello"); | 
 |     Json::Value& value2 = path2.make(root); | 
 |     JSONTEST_ASSERT_EQUAL(Json::nullValue, value2); | 
 |  | 
 |     // make will change the value | 
 |     const Json::String outcome = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, outcome); | 
 |   } | 
 | } | 
 | struct FastWriterTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(FastWriterTest, dropNullPlaceholders) { | 
 |   Json::FastWriter writer; | 
 |   Json::Value nullValue; | 
 |   JSONTEST_ASSERT(writer.write(nullValue) == "null\n"); | 
 |  | 
 |   writer.dropNullPlaceholders(); | 
 |   JSONTEST_ASSERT(writer.write(nullValue) == "\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(FastWriterTest, enableYAMLCompatibility) { | 
 |   Json::FastWriter writer; | 
 |   Json::Value root; | 
 |   root["hello"] = "world"; | 
 |  | 
 |   JSONTEST_ASSERT(writer.write(root) == "{\"hello\":\"world\"}\n"); | 
 |  | 
 |   writer.enableYAMLCompatibility(); | 
 |   JSONTEST_ASSERT(writer.write(root) == "{\"hello\": \"world\"}\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(FastWriterTest, omitEndingLineFeed) { | 
 |   Json::FastWriter writer; | 
 |   Json::Value nullValue; | 
 |  | 
 |   JSONTEST_ASSERT(writer.write(nullValue) == "null\n"); | 
 |  | 
 |   writer.omitEndingLineFeed(); | 
 |   JSONTEST_ASSERT(writer.write(nullValue) == "null"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(FastWriterTest, writeNumericValue) { | 
 |   Json::FastWriter writer; | 
 |   const Json::String expected("{" | 
 |                               "\"emptyValue\":null," | 
 |                               "\"false\":false," | 
 |                               "\"null\":\"null\"," | 
 |                               "\"number\":-6200000000000000.0," | 
 |                               "\"real\":1.256," | 
 |                               "\"uintValue\":17" | 
 |                               "}\n"); | 
 |   Json::Value root; | 
 |   root["emptyValue"] = Json::nullValue; | 
 |   root["false"] = false; | 
 |   root["null"] = "null"; | 
 |   root["number"] = -6.2e+15; | 
 |   root["real"] = 1.256; | 
 |   root["uintValue"] = Json::Value(17U); | 
 |  | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(FastWriterTest, writeArrays) { | 
 |   Json::FastWriter writer; | 
 |   const Json::String expected("{" | 
 |                               "\"property1\":[\"value1\",\"value2\"]," | 
 |                               "\"property2\":[]" | 
 |                               "}\n"); | 
 |   Json::Value root; | 
 |   root["property1"][0] = "value1"; | 
 |   root["property1"][1] = "value2"; | 
 |   root["property2"] = Json::arrayValue; | 
 |  | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(FastWriterTest, writeNestedObjects) { | 
 |   Json::FastWriter writer; | 
 |   const Json::String expected("{" | 
 |                               "\"object1\":{" | 
 |                               "\"bool\":true," | 
 |                               "\"nested\":123" | 
 |                               "}," | 
 |                               "\"object2\":{}" | 
 |                               "}\n"); | 
 |   Json::Value root, child; | 
 |   child["nested"] = 123; | 
 |   child["bool"] = true; | 
 |   root["object1"] = child; | 
 |   root["object2"] = Json::objectValue; | 
 |  | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | struct StyledWriterTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeNumericValue) { | 
 |   Json::StyledWriter writer; | 
 |   const Json::String expected("{\n" | 
 |                               "   \"emptyValue\" : null,\n" | 
 |                               "   \"false\" : false,\n" | 
 |                               "   \"null\" : \"null\",\n" | 
 |                               "   \"number\" : -6200000000000000.0,\n" | 
 |                               "   \"real\" : 1.256,\n" | 
 |                               "   \"uintValue\" : 17\n" | 
 |                               "}\n"); | 
 |   Json::Value root; | 
 |   root["emptyValue"] = Json::nullValue; | 
 |   root["false"] = false; | 
 |   root["null"] = "null"; | 
 |   root["number"] = -6.2e+15; | 
 |   root["real"] = 1.256; | 
 |   root["uintValue"] = Json::Value(17U); | 
 |  | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeArrays) { | 
 |   Json::StyledWriter writer; | 
 |   const Json::String expected("{\n" | 
 |                               "   \"property1\" : [ \"value1\", \"value2\" ],\n" | 
 |                               "   \"property2\" : []\n" | 
 |                               "}\n"); | 
 |   Json::Value root; | 
 |   root["property1"][0] = "value1"; | 
 |   root["property1"][1] = "value2"; | 
 |   root["property2"] = Json::arrayValue; | 
 |  | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeNestedObjects) { | 
 |   Json::StyledWriter writer; | 
 |   const Json::String expected("{\n" | 
 |                               "   \"object1\" : {\n" | 
 |                               "      \"bool\" : true,\n" | 
 |                               "      \"nested\" : 123\n" | 
 |                               "   },\n" | 
 |                               "   \"object2\" : {}\n" | 
 |                               "}\n"); | 
 |   Json::Value root, child; | 
 |   child["nested"] = 123; | 
 |   child["bool"] = true; | 
 |   root["object1"] = child; | 
 |   root["object2"] = Json::objectValue; | 
 |  | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledWriterTest, multiLineArray) { | 
 |   Json::StyledWriter writer; | 
 |   { | 
 |     // Array member has more than 20 print effect rendering lines | 
 |     const Json::String expected("[\n   " | 
 |                                 "0,\n   1,\n   2,\n   " | 
 |                                 "3,\n   4,\n   5,\n   " | 
 |                                 "6,\n   7,\n   8,\n   " | 
 |                                 "9,\n   10,\n   11,\n   " | 
 |                                 "12,\n   13,\n   14,\n   " | 
 |                                 "15,\n   16,\n   17,\n   " | 
 |                                 "18,\n   19,\n   20\n]\n"); | 
 |     Json::Value root; | 
 |     for (Json::ArrayIndex i = 0; i < 21; i++) | 
 |       root[i] = i; | 
 |     const Json::String result = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     // Array members do not exceed 21 print effects to render a single line | 
 |     const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); | 
 |     Json::Value root; | 
 |     for (Json::ArrayIndex i = 0; i < 10; i++) | 
 |       root[i] = i; | 
 |     const Json::String result = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeValueWithComment) { | 
 |   Json::StyledWriter writer; | 
 |   { | 
 |     const Json::String expected("\n//commentBeforeValue\n\"hello\"\n"); | 
 |     Json::Value root = "hello"; | 
 |     root.setComment(Json::String("//commentBeforeValue"), Json::commentBefore); | 
 |     const Json::String result = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     const Json::String expected("\"hello\" //commentAfterValueOnSameLine\n"); | 
 |     Json::Value root = "hello"; | 
 |     root.setComment(Json::String("//commentAfterValueOnSameLine"), | 
 |                     Json::commentAfterOnSameLine); | 
 |     const Json::String result = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     const Json::String expected("\"hello\"\n//commentAfter\n\n"); | 
 |     Json::Value root = "hello"; | 
 |     root.setComment(Json::String("//commentAfter"), Json::commentAfter); | 
 |     const Json::String result = writer.write(root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 | } | 
 |  | 
 | struct StyledStreamWriterTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeNumericValue) { | 
 |   Json::StyledStreamWriter writer; | 
 |   const Json::String expected("{\n" | 
 |                               "\t\"emptyValue\" : null,\n" | 
 |                               "\t\"false\" : false,\n" | 
 |                               "\t\"null\" : \"null\",\n" | 
 |                               "\t\"number\" : -6200000000000000.0,\n" | 
 |                               "\t\"real\" : 1.256,\n" | 
 |                               "\t\"uintValue\" : 17\n" | 
 |                               "}\n"); | 
 |  | 
 |   Json::Value root; | 
 |   root["emptyValue"] = Json::nullValue; | 
 |   root["false"] = false; | 
 |   root["null"] = "null"; | 
 |   root["number"] = -6.2e+15; // big float number | 
 |   root["real"] = 1.256;      // float number | 
 |   root["uintValue"] = Json::Value(17U); | 
 |  | 
 |   Json::OStringStream sout; | 
 |   writer.write(sout, root); | 
 |   const Json::String result = sout.str(); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeArrays) { | 
 |   Json::StyledStreamWriter writer; | 
 |   const Json::String expected("{\n" | 
 |                               "\t\"property1\" : [ \"value1\", \"value2\" ],\n" | 
 |                               "\t\"property2\" : []\n" | 
 |                               "}\n"); | 
 |   Json::Value root; | 
 |   root["property1"][0] = "value1"; | 
 |   root["property1"][1] = "value2"; | 
 |   root["property2"] = Json::arrayValue; | 
 |  | 
 |   Json::OStringStream sout; | 
 |   writer.write(sout, root); | 
 |   const Json::String result = sout.str(); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeNestedObjects) { | 
 |   Json::StyledStreamWriter writer; | 
 |   const Json::String expected("{\n" | 
 |                               "\t\"object1\" : \n" | 
 |                               "\t" | 
 |                               "{\n" | 
 |                               "\t\t\"bool\" : true,\n" | 
 |                               "\t\t\"nested\" : 123\n" | 
 |                               "\t},\n" | 
 |                               "\t\"object2\" : {}\n" | 
 |                               "}\n"); | 
 |   Json::Value root, child; | 
 |   child["nested"] = 123; | 
 |   child["bool"] = true; | 
 |   root["object1"] = child; | 
 |   root["object2"] = Json::objectValue; | 
 |  | 
 |   Json::OStringStream sout; | 
 |   writer.write(sout, root); | 
 |   const Json::String result = sout.str(); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, multiLineArray) { | 
 |   { | 
 |     // Array member has more than 20 print effect rendering lines | 
 |     const Json::String expected("[\n\t0," | 
 |                                 "\n\t1," | 
 |                                 "\n\t2," | 
 |                                 "\n\t3," | 
 |                                 "\n\t4," | 
 |                                 "\n\t5," | 
 |                                 "\n\t6," | 
 |                                 "\n\t7," | 
 |                                 "\n\t8," | 
 |                                 "\n\t9," | 
 |                                 "\n\t10," | 
 |                                 "\n\t11," | 
 |                                 "\n\t12," | 
 |                                 "\n\t13," | 
 |                                 "\n\t14," | 
 |                                 "\n\t15," | 
 |                                 "\n\t16," | 
 |                                 "\n\t17," | 
 |                                 "\n\t18," | 
 |                                 "\n\t19," | 
 |                                 "\n\t20\n]\n"); | 
 |     Json::StyledStreamWriter writer; | 
 |     Json::Value root; | 
 |     for (Json::ArrayIndex i = 0; i < 21; i++) | 
 |       root[i] = i; | 
 |     Json::OStringStream sout; | 
 |     writer.write(sout, root); | 
 |     const Json::String result = sout.str(); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     Json::StyledStreamWriter writer; | 
 |     // Array members do not exceed 21 print effects to render a single line | 
 |     const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); | 
 |     Json::Value root; | 
 |     for (Json::ArrayIndex i = 0; i < 10; i++) | 
 |       root[i] = i; | 
 |     Json::OStringStream sout; | 
 |     writer.write(sout, root); | 
 |     const Json::String result = sout.str(); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeValueWithComment) { | 
 |   Json::StyledStreamWriter writer("\t"); | 
 |   { | 
 |     const Json::String expected("//commentBeforeValue\n\"hello\"\n"); | 
 |     Json::Value root = "hello"; | 
 |     Json::OStringStream sout; | 
 |     root.setComment(Json::String("//commentBeforeValue"), Json::commentBefore); | 
 |     writer.write(sout, root); | 
 |     const Json::String result = sout.str(); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     const Json::String expected("\"hello\" //commentAfterValueOnSameLine\n"); | 
 |     Json::Value root = "hello"; | 
 |     Json::OStringStream sout; | 
 |     root.setComment(Json::String("//commentAfterValueOnSameLine"), | 
 |                     Json::commentAfterOnSameLine); | 
 |     writer.write(sout, root); | 
 |     const Json::String result = sout.str(); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     const Json::String expected("\"hello\"\n//commentAfter\n"); | 
 |     Json::Value root = "hello"; | 
 |     Json::OStringStream sout; | 
 |     root.setComment(Json::String("//commentAfter"), Json::commentAfter); | 
 |     writer.write(sout, root); | 
 |     const Json::String result = sout.str(); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 | } | 
 |  | 
 | struct StreamWriterTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeNumericValue) { | 
 |   Json::StreamWriterBuilder writer; | 
 |   const Json::String expected("{\n" | 
 |                               "\t\"emptyValue\" : null,\n" | 
 |                               "\t\"false\" : false,\n" | 
 |                               "\t\"null\" : \"null\",\n" | 
 |                               "\t\"number\" : -6200000000000000.0,\n" | 
 |                               "\t\"real\" : 1.256,\n" | 
 |                               "\t\"uintValue\" : 17\n" | 
 |                               "}"); | 
 |   Json::Value root; | 
 |   root["emptyValue"] = Json::nullValue; | 
 |   root["false"] = false; | 
 |   root["null"] = "null"; | 
 |   root["number"] = -6.2e+15; | 
 |   root["real"] = 1.256; | 
 |   root["uintValue"] = Json::Value(17U); | 
 |  | 
 |   const Json::String result = Json::writeString(writer, root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeArrays) { | 
 |   Json::StreamWriterBuilder writer; | 
 |   const Json::String expected("{\n" | 
 |                               "\t\"property1\" : \n" | 
 |                               "\t[\n" | 
 |                               "\t\t\"value1\",\n" | 
 |                               "\t\t\"value2\"\n" | 
 |                               "\t],\n" | 
 |                               "\t\"property2\" : []\n" | 
 |                               "}"); | 
 |  | 
 |   Json::Value root; | 
 |   root["property1"][0] = "value1"; | 
 |   root["property1"][1] = "value2"; | 
 |   root["property2"] = Json::arrayValue; | 
 |  | 
 |   const Json::String result = Json::writeString(writer, root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeNestedObjects) { | 
 |   Json::StreamWriterBuilder writer; | 
 |   const Json::String expected("{\n" | 
 |                               "\t\"object1\" : \n" | 
 |                               "\t{\n" | 
 |                               "\t\t\"bool\" : true,\n" | 
 |                               "\t\t\"nested\" : 123\n" | 
 |                               "\t},\n" | 
 |                               "\t\"object2\" : {}\n" | 
 |                               "}"); | 
 |  | 
 |   Json::Value root, child; | 
 |   child["nested"] = 123; | 
 |   child["bool"] = true; | 
 |   root["object1"] = child; | 
 |   root["object2"] = Json::objectValue; | 
 |  | 
 |   const Json::String result = Json::writeString(writer, root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, multiLineArray) { | 
 |   Json::StreamWriterBuilder wb; | 
 |   wb.settings_["commentStyle"] = "None"; | 
 |   { | 
 |     // When wb.settings_["commentStyle"] = "None", the effect of | 
 |     // printing multiple lines will be displayed when there are | 
 |     // more than 20 array members. | 
 |     const Json::String expected("[\n\t0," | 
 |                                 "\n\t1," | 
 |                                 "\n\t2," | 
 |                                 "\n\t3," | 
 |                                 "\n\t4," | 
 |                                 "\n\t5," | 
 |                                 "\n\t6," | 
 |                                 "\n\t7," | 
 |                                 "\n\t8," | 
 |                                 "\n\t9," | 
 |                                 "\n\t10," | 
 |                                 "\n\t11," | 
 |                                 "\n\t12," | 
 |                                 "\n\t13," | 
 |                                 "\n\t14," | 
 |                                 "\n\t15," | 
 |                                 "\n\t16," | 
 |                                 "\n\t17," | 
 |                                 "\n\t18," | 
 |                                 "\n\t19," | 
 |                                 "\n\t20\n]"); | 
 |     Json::Value root; | 
 |     for (Json::ArrayIndex i = 0; i < 21; i++) | 
 |       root[i] = i; | 
 |     const Json::String result = Json::writeString(wb, root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 |   { | 
 |     // Array members do not exceed 21 print effects to render a single line | 
 |     const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]"); | 
 |     Json::Value root; | 
 |     for (Json::ArrayIndex i = 0; i < 10; i++) | 
 |       root[i] = i; | 
 |     const Json::String result = Json::writeString(wb, root); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, dropNullPlaceholders) { | 
 |   Json::StreamWriterBuilder b; | 
 |   Json::Value nullValue; | 
 |   b.settings_["dropNullPlaceholders"] = false; | 
 |   JSONTEST_ASSERT(Json::writeString(b, nullValue) == "null"); | 
 |   b.settings_["dropNullPlaceholders"] = true; | 
 |   JSONTEST_ASSERT(Json::writeString(b, nullValue).empty()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, enableYAMLCompatibility) { | 
 |   Json::StreamWriterBuilder b; | 
 |   Json::Value root; | 
 |   root["hello"] = "world"; | 
 |  | 
 |   b.settings_["indentation"] = ""; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); | 
 |  | 
 |   b.settings_["enableYAMLCompatibility"] = true; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\": \"world\"}"); | 
 |  | 
 |   b.settings_["enableYAMLCompatibility"] = false; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, indentation) { | 
 |   Json::StreamWriterBuilder b; | 
 |   Json::Value root; | 
 |   root["hello"] = "world"; | 
 |  | 
 |   b.settings_["indentation"] = ""; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); | 
 |  | 
 |   b.settings_["indentation"] = "\t"; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == | 
 |                   "{\n\t\"hello\" : \"world\"\n}"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeZeroes) { | 
 |   Json::String binary("hi", 3); // include trailing 0 | 
 |   JSONTEST_ASSERT_EQUAL(3, binary.length()); | 
 |   Json::String expected(R"("hi\u0000")"); // unicoded zero | 
 |   Json::StreamWriterBuilder b; | 
 |   { | 
 |     Json::Value root; | 
 |     root = binary; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(binary, root.asString()); | 
 |     Json::String out = Json::writeString(b, root); | 
 |     JSONTEST_ASSERT_EQUAL(expected.size(), out.size()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, out); | 
 |   } | 
 |   { | 
 |     Json::Value root; | 
 |     root["top"] = binary; | 
 |     JSONTEST_ASSERT_STRING_EQUAL(binary, root["top"].asString()); | 
 |     Json::String out = Json::writeString(b, root["top"]); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(expected, out); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, unicode) { | 
 |   // Create a Json value containing UTF-8 string with some chars that need | 
 |   // escape (tab,newline). | 
 |   Json::Value root; | 
 |   root["test"] = "\t\n\xF0\x91\xA2\xA1\x3D\xC4\xB3\xF0\x9B\x84\x9B\xEF\xBD\xA7"; | 
 |  | 
 |   Json::StreamWriterBuilder b; | 
 |  | 
 |   // Default settings - should be unicode escaped. | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == | 
 |                   "{\n\t\"test\" : " | 
 |                   "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); | 
 |  | 
 |   b.settings_["emitUTF8"] = true; | 
 |  | 
 |   // Should not be unicode escaped. | 
 |   JSONTEST_ASSERT( | 
 |       Json::writeString(b, root) == | 
 |       "{\n\t\"test\" : " | 
 |       "\"\\t\\n\xF0\x91\xA2\xA1=\xC4\xB3\xF0\x9B\x84\x9B\xEF\xBD\xA7\"\n}"); | 
 |  | 
 |   b.settings_["emitUTF8"] = false; | 
 |  | 
 |   // Should be unicode escaped. | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == | 
 |                   "{\n\t\"test\" : " | 
 |                   "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); | 
 | } | 
 |  | 
 | // Control chars should be escaped regardless of UTF-8 input encoding. | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, escapeControlCharacters) { | 
 |   auto uEscape = [](unsigned ch) { | 
 |     static const char h[] = "0123456789abcdef"; | 
 |     std::string r = "\\u"; | 
 |     r += h[(ch >> (3 * 4)) & 0xf]; | 
 |     r += h[(ch >> (2 * 4)) & 0xf]; | 
 |     r += h[(ch >> (1 * 4)) & 0xf]; | 
 |     r += h[(ch >> (0 * 4)) & 0xf]; | 
 |     return r; | 
 |   }; | 
 |   auto shortEscape = [](unsigned ch) -> const char* { | 
 |     switch (ch) { | 
 |     case '\"': | 
 |       return "\\\""; | 
 |     case '\\': | 
 |       return "\\\\"; | 
 |     case '\b': | 
 |       return "\\b"; | 
 |     case '\f': | 
 |       return "\\f"; | 
 |     case '\n': | 
 |       return "\\n"; | 
 |     case '\r': | 
 |       return "\\r"; | 
 |     case '\t': | 
 |       return "\\t"; | 
 |     default: | 
 |       return nullptr; | 
 |     } | 
 |   }; | 
 |  | 
 |   Json::StreamWriterBuilder b; | 
 |  | 
 |   for (bool emitUTF8 : {true, false}) { | 
 |     b.settings_["emitUTF8"] = emitUTF8; | 
 |  | 
 |     for (unsigned i = 0; i != 0x100; ++i) { | 
 |       if (!emitUTF8 && i >= 0x80) | 
 |         break; // The algorithm would try to parse UTF-8, so stop here. | 
 |  | 
 |       std::string raw({static_cast<char>(i)}); | 
 |       std::string esc = raw; | 
 |       if (i < 0x20) | 
 |         esc = uEscape(i); | 
 |       if (const char* shEsc = shortEscape(i)) | 
 |         esc = shEsc; | 
 |  | 
 |       // std::cout << "emit=" << emitUTF8 << ", i=" << std::hex << i << std::dec | 
 |       //          << std::endl; | 
 |  | 
 |       Json::Value root; | 
 |       root["test"] = raw; | 
 |       JSONTEST_ASSERT_STRING_EQUAL( | 
 |           std::string("{\n\t\"test\" : \"").append(esc).append("\"\n}"), | 
 |           Json::writeString(b, root)) | 
 |           << ", emit=" << emitUTF8 << ", i=" << i << ", raw=\"" << raw << "\"" | 
 |           << ", esc=\"" << esc << "\""; | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | #ifdef _WIN32 | 
 | JSONTEST_FIXTURE_LOCAL(StreamWriterTest, escapeTabCharacterWindows) { | 
 |   // Get the current locale before changing it | 
 |   std::string currentLocale = setlocale(LC_ALL, NULL); | 
 |   setlocale(LC_ALL, "English_United States.1252"); | 
 |  | 
 |   Json::Value root; | 
 |   root["test"] = "\tTabTesting\t"; | 
 |  | 
 |   Json::StreamWriterBuilder b; | 
 |  | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"test\" : " | 
 |                                                 "\"\\tTabTesting\\t\"\n}"); | 
 |  | 
 |   b.settings_["emitUTF8"] = true; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"test\" : " | 
 |                                                 "\"\\tTabTesting\\t\"\n}"); | 
 |  | 
 |   b.settings_["emitUTF8"] = false; | 
 |   JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"test\" : " | 
 |                                                 "\"\\tTabTesting\\t\"\n}"); | 
 |  | 
 |   // Restore the locale | 
 |   if (!currentLocale.empty()) | 
 |     setlocale(LC_ALL, currentLocale.c_str()); | 
 | } | 
 | #endif | 
 |  | 
 | struct ReaderTest : JsonTest::TestCase { | 
 |   void setStrictMode() { | 
 |     reader = std::unique_ptr<Json::Reader>( | 
 |         new Json::Reader(Json::Features{}.strictMode())); | 
 |   } | 
 |  | 
 |   void setFeatures(Json::Features& features) { | 
 |     reader = std::unique_ptr<Json::Reader>(new Json::Reader(features)); | 
 |   } | 
 |  | 
 |   void checkStructuredErrors( | 
 |       const std::vector<Json::Reader::StructuredError>& actual, | 
 |       const std::vector<Json::Reader::StructuredError>& expected) { | 
 |     JSONTEST_ASSERT_EQUAL(expected.size(), actual.size()); | 
 |     for (size_t i = 0; i < actual.size(); ++i) { | 
 |       const auto& a = actual[i]; | 
 |       const auto& e = expected[i]; | 
 |       JSONTEST_ASSERT_EQUAL(e.offset_start, a.offset_start) << i; | 
 |       JSONTEST_ASSERT_EQUAL(e.offset_limit, a.offset_limit) << i; | 
 |       JSONTEST_ASSERT_EQUAL(e.message, a.message) << i; | 
 |     } | 
 |   } | 
 |  | 
 |   template <typename Input> void checkParse(Input&& input) { | 
 |     JSONTEST_ASSERT(reader->parse(input, root)); | 
 |   } | 
 |  | 
 |   template <typename Input> | 
 |   void | 
 |   checkParse(Input&& input, | 
 |              const std::vector<Json::Reader::StructuredError>& structured) { | 
 |     JSONTEST_ASSERT(!reader->parse(input, root)); | 
 |     checkStructuredErrors(reader->getStructuredErrors(), structured); | 
 |   } | 
 |  | 
 |   template <typename Input> | 
 |   void checkParse(Input&& input, | 
 |                   const std::vector<Json::Reader::StructuredError>& structured, | 
 |                   const std::string& formatted) { | 
 |     checkParse(input, structured); | 
 |     JSONTEST_ASSERT_EQUAL(formatted, reader->getFormattedErrorMessages()); | 
 |   } | 
 |  | 
 |   std::unique_ptr<Json::Reader> reader{new Json::Reader()}; | 
 |   Json::Value root; | 
 | }; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { | 
 |   checkParse(R"({ "property" : "value" })"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseObject) { | 
 |   checkParse(R"({"property"})", | 
 |              {{11, 12, "Missing ':' after object member name"}}, | 
 |              "* Line 1, Column 12\n  Missing ':' after object member name\n"); | 
 |   checkParse( | 
 |       R"({"property" : "value" )", | 
 |       {{22, 22, "Missing ',' or '}' in object declaration"}}, | 
 |       "* Line 1, Column 23\n  Missing ',' or '}' in object declaration\n"); | 
 |   checkParse(R"({"property" : "value", )", | 
 |              {{23, 23, "Missing '}' or object member name"}}, | 
 |              "* Line 1, Column 24\n  Missing '}' or object member name\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseArray) { | 
 |   checkParse( | 
 |       R"([ "value" )", {{10, 10, "Missing ',' or ']' in array declaration"}}, | 
 |       "* Line 1, Column 11\n  Missing ',' or ']' in array declaration\n"); | 
 |   checkParse( | 
 |       R"([ "value1" "value2" ] )", | 
 |       {{11, 19, "Missing ',' or ']' in array declaration"}}, | 
 |       "* Line 1, Column 12\n  Missing ',' or ']' in array declaration\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) { | 
 |   checkParse(R"([ "\u8a2a" ])"); | 
 |   checkParse( | 
 |       R"([ "\ud801" ])", | 
 |       {{2, 10, | 
 |         "additional six characters expected to parse unicode surrogate " | 
 |         "pair."}}, | 
 |       "* Line 1, Column 3\n" | 
 |       "  additional six characters expected to parse unicode surrogate pair.\n" | 
 |       "See Line 1, Column 10 for detail.\n"); | 
 |   checkParse(R"([ "\ud801\d1234" ])", | 
 |              {{2, 16, | 
 |                "expecting another \\u token to begin the " | 
 |                "second half of a unicode surrogate pair"}}, | 
 |              "* Line 1, Column 3\n" | 
 |              "  expecting another \\u token to begin the " | 
 |              "second half of a unicode surrogate pair\n" | 
 |              "See Line 1, Column 12 for detail.\n"); | 
 |   checkParse(R"([ "\ua3t@" ])", | 
 |              {{2, 10, | 
 |                "Bad unicode escape sequence in string: " | 
 |                "hexadecimal digit expected."}}, | 
 |              "* Line 1, Column 3\n" | 
 |              "  Bad unicode escape sequence in string: " | 
 |              "hexadecimal digit expected.\n" | 
 |              "See Line 1, Column 9 for detail.\n"); | 
 |   checkParse( | 
 |       R"([ "\ua3t" ])", | 
 |       {{2, 9, "Bad unicode escape sequence in string: four digits expected."}}, | 
 |       "* Line 1, Column 3\n" | 
 |       "  Bad unicode escape sequence in string: four digits expected.\n" | 
 |       "See Line 1, Column 6 for detail.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseComment) { | 
 |   checkParse( | 
 |       R"({ /*commentBeforeValue*/ "property" : "value" }//commentAfterValue)" | 
 |       "\n"); | 
 |   checkParse(" true //comment1\n//comment2\r//comment3\r\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, streamParseWithNoErrors) { | 
 |   std::string styled = R"({ "property" : "value" })"; | 
 |   std::istringstream iss(styled); | 
 |   checkParse(iss); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { | 
 |   checkParse(R"({)" | 
 |              R"( "property" : ["value", "value2"],)" | 
 |              R"( "obj" : { "nested" : -6.2e+15, "bool" : true},)" | 
 |              R"( "null" : null,)" | 
 |              R"( "false" : false)" | 
 |              R"( })"); | 
 |   auto checkOffsets = [&](const Json::Value& v, int start, int limit) { | 
 |     JSONTEST_ASSERT_EQUAL(start, v.getOffsetStart()); | 
 |     JSONTEST_ASSERT_EQUAL(limit, v.getOffsetLimit()); | 
 |   }; | 
 |   checkOffsets(root, 0, 115); | 
 |   checkOffsets(root["property"], 15, 34); | 
 |   checkOffsets(root["property"][0], 16, 23); | 
 |   checkOffsets(root["property"][1], 25, 33); | 
 |   checkOffsets(root["obj"], 44, 81); | 
 |   checkOffsets(root["obj"]["nested"], 57, 65); | 
 |   checkOffsets(root["obj"]["bool"], 76, 80); | 
 |   checkOffsets(root["null"], 92, 96); | 
 |   checkOffsets(root["false"], 108, 113); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { | 
 |   checkParse(R"({ "property" :: "value" })", | 
 |              {{14, 15, "Syntax error: value, object or array expected."}}, | 
 |              "* Line 1, Column 15\n  Syntax error: value, object or array " | 
 |              "expected.\n"); | 
 |   checkParse("s", {{0, 1, "Syntax error: value, object or array expected."}}, | 
 |              "* Line 1, Column 1\n  Syntax error: value, object or array " | 
 |              "expected.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseSpecialFloat) { | 
 |   checkParse(R"({ "a" : Infi })", | 
 |              {{8, 9, "Syntax error: value, object or array expected."}}, | 
 |              "* Line 1, Column 9\n  Syntax error: value, object or array " | 
 |              "expected.\n"); | 
 |   checkParse(R"({ "a" : Infiniaa })", | 
 |              {{8, 9, "Syntax error: value, object or array expected."}}, | 
 |              "* Line 1, Column 9\n  Syntax error: value, object or array " | 
 |              "expected.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, strictModeParseNumber) { | 
 |   setStrictMode(); | 
 |   checkParse( | 
 |       "123", | 
 |       {{0, 3, | 
 |         "A valid JSON document must be either an array or an object value."}}, | 
 |       "* Line 1, Column 1\n" | 
 |       "  A valid JSON document must be either an array or an object value.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) { | 
 |   checkParse(R"({ "pr)" | 
 |              u8"\u4f50\u85e4" // 佐藤 | 
 |              R"(erty" :: "value" })", | 
 |              {{18, 19, "Syntax error: value, object or array expected."}}, | 
 |              "* Line 1, Column 19\n  Syntax error: value, object or array " | 
 |              "expected.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) { | 
 |   checkParse(R"({ "property" : "v\alue" })", | 
 |              {{15, 23, "Bad escape sequence in string"}}, | 
 |              "* Line 1, Column 16\n" | 
 |              "  Bad escape sequence in string\n" | 
 |              "See Line 1, Column 20 for detail.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) { | 
 |   checkParse(R"({ "AUTHOR" : 123 })"); | 
 |   if (!root["AUTHOR"].isString()) { | 
 |     JSONTEST_ASSERT( | 
 |         reader->pushError(root["AUTHOR"], "AUTHOR must be a string")); | 
 |   } | 
 |   JSONTEST_ASSERT_STRING_EQUAL(reader->getFormattedErrorMessages(), | 
 |                                "* Line 1, Column 14\n" | 
 |                                "  AUTHOR must be a string\n"); | 
 |  | 
 |   checkParse(R"({ "AUTHOR" : 123 })"); | 
 |   if (!root["AUTHOR"].isString()) { | 
 |     JSONTEST_ASSERT(reader->pushError(root["AUTHOR"], "AUTHOR must be a string", | 
 |                                       root["AUTHOR"])); | 
 |   } | 
 |   JSONTEST_ASSERT_STRING_EQUAL(reader->getFormattedErrorMessages(), | 
 |                                "* Line 1, Column 14\n" | 
 |                                "  AUTHOR must be a string\n" | 
 |                                "See Line 1, Column 14 for detail.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ReaderTest, allowNumericKeysTest) { | 
 |   Json::Features features; | 
 |   features.allowNumericKeys_ = true; | 
 |   setFeatures(features); | 
 |   checkParse(R"({ 123 : "abc" })"); | 
 | } | 
 |  | 
 | struct CharReaderTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   Json::Value root; | 
 |   char const doc[] = R"({ "property" : "value" })"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT(errs.empty()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrorsTestingOffsets) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   Json::Value root; | 
 |   char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " | 
 |                      "{ \"nested\" : -6.2e+15, \"num\" : +123, \"bool\" : " | 
 |                      "true}, \"null\" : null, \"false\" : false }"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT(errs.empty()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseNumber) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   Json::Value root; | 
 |   { | 
 |     // if intvalue > threshold, treat the number as a double. | 
 |     // 21 digits | 
 |     char const doc[] = "[111111111111111111111]"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL(1.1111111111111111e+020, root[0]); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   { | 
 |     char const doc[] = "[\"\"]"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL("", root[0]); | 
 |   } | 
 |   { | 
 |     char const doc[] = R"(["\u8A2a"])"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL(u8"\u8A2a", root[0].asString()); // "訪" | 
 |   } | 
 |   { | 
 |     char const doc[] = R"([ "\uD801" ])"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" | 
 |                             "  additional six characters expected to " | 
 |                             "parse unicode surrogate pair.\n" | 
 |                             "See Line 1, Column 10 for detail.\n"); | 
 |   } | 
 |   { | 
 |     char const doc[] = R"([ "\uD801\d1234" ])"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" | 
 |                             "  expecting another \\u token to begin the " | 
 |                             "second half of a unicode surrogate pair\n" | 
 |                             "See Line 1, Column 12 for detail.\n"); | 
 |   } | 
 |   { | 
 |     char const doc[] = R"([ "\ua3t@" ])"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" | 
 |                             "  Bad unicode escape sequence in string: " | 
 |                             "hexadecimal digit expected.\n" | 
 |                             "See Line 1, Column 9 for detail.\n"); | 
 |   } | 
 |   { | 
 |     char const doc[] = R"([ "\ua3t" ])"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT( | 
 |         errs == | 
 |         "* Line 1, Column 3\n" | 
 |         "  Bad unicode escape sequence in string: four digits expected.\n" | 
 |         "See Line 1, Column 6 for detail.\n"); | 
 |   } | 
 |   { | 
 |     b.settings_["allowSingleQuotes"] = true; | 
 |     CharReaderPtr charreader(b.newCharReader()); | 
 |     char const doc[] = R"({'a': 'x\ty', "b":'x\\y'})"; | 
 |     bool ok = charreader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(2u, root.size()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("x\ty", root["a"].asString()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("x\\y", root["b"].asString()); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseComment) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   { | 
 |     char const doc[] = "//comment1\n { //comment2\n \"property\" :" | 
 |                        " \"value\" //comment3\n } //comment4\n"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL("value", root["property"]); | 
 |   } | 
 |   { | 
 |     char const doc[] = "{ \"property\" //comment\n : \"value\" }"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 14\n" | 
 |                             "  Missing ':' after object member name\n"); | 
 |   } | 
 |   { | 
 |     char const doc[] = "//comment1\n [ //comment2\n \"value\" //comment3\n," | 
 |                        " //comment4\n true //comment5\n ] //comment6\n"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL("value", root[0]); | 
 |     JSONTEST_ASSERT_EQUAL(true, root[1]); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   { | 
 |     char const doc[] = R"({ "property" : "value" )"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 24\n" | 
 |                             "  Missing ',' or '}' in object declaration\n"); | 
 |     JSONTEST_ASSERT_EQUAL("value", root["property"]); | 
 |   } | 
 |   { | 
 |     char const doc[] = R"({ "property" : "value" ,)"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 25\n" | 
 |                             "  Missing '}' or object member name\n"); | 
 |     JSONTEST_ASSERT_EQUAL("value", root["property"]); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseArrayWithErrors) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   { | 
 |     char const doc[] = "[ \"value\" "; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 11\n" | 
 |                             "  Missing ',' or ']' in array declaration\n"); | 
 |     JSONTEST_ASSERT_EQUAL("value", root[0]); | 
 |   } | 
 |   { | 
 |     char const doc[] = R"([ "value1" "value2" ])"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT(errs == "* Line 1, Column 12\n" | 
 |                             "  Missing ',' or ']' in array declaration\n"); | 
 |     JSONTEST_ASSERT_EQUAL("value1", root[0]); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   Json::Value root; | 
 |   char const doc[] = R"({ "property" :: "value" })"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(!ok); | 
 |   JSONTEST_ASSERT(errs == | 
 |                   "* Line 1, Column 15\n  Syntax error: value, object or array " | 
 |                   "expected.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseChineseWithOneError) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   Json::Value root; | 
 |   char const doc[] = "{ \"pr佐藤erty\" :: \"value\" }"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(!ok); | 
 |   JSONTEST_ASSERT(errs == | 
 |                   "* Line 1, Column 19\n  Syntax error: value, object or array " | 
 |                   "expected.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   Json::Value root; | 
 |   char const doc[] = R"({ "property" : "v\alue" })"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(!ok); | 
 |   JSONTEST_ASSERT(errs == | 
 |                   "* Line 1, Column 16\n  Bad escape sequence in string\nSee " | 
 |                   "Line 1, Column 20 for detail.\n"); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   char const doc[] = R"({ "property" : "value" })"; | 
 |   { | 
 |     b.settings_["stackLimit"] = 2; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL("value", root["property"]); | 
 |   } | 
 |   { | 
 |     b.settings_["stackLimit"] = 1; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     JSONTEST_ASSERT_THROWS( | 
 |         reader->parse(doc, doc + std::strlen(doc), &root, &errs)); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderTest, testOperator) { | 
 |   const std::string styled = R"({ "property" : "value" })"; | 
 |   std::istringstream iss(styled); | 
 |   Json::Value root; | 
 |   iss >> root; | 
 |   JSONTEST_ASSERT_EQUAL("value", root["property"]); | 
 | } | 
 |  | 
 | struct CharReaderStrictModeTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   char const doc[] = | 
 |       R"({ "property" : "value", "key" : "val1", "key" : "val2" })"; | 
 |   { | 
 |     b.strictMode(&b.settings_); | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 41\n" | 
 |                                  "  Duplicate key: 'key'\n", | 
 |                                  errs); | 
 |     JSONTEST_ASSERT_EQUAL("val1", root["key"]); // so far | 
 |   } | 
 | } | 
 | struct CharReaderFailIfExtraTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { | 
 |   // This is interpreted as a string value followed by a colon. | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   char const doc[] = R"( "property" : "value" })"; | 
 |   { | 
 |     b.settings_["failIfExtra"] = false; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT(errs.empty()); | 
 |     JSONTEST_ASSERT_EQUAL("property", root); | 
 |   } | 
 |   { | 
 |     b.settings_["failIfExtra"] = true; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 13\n" | 
 |                                  "  Extra non-whitespace after JSON value.\n", | 
 |                                  errs); | 
 |     JSONTEST_ASSERT_EQUAL("property", root); | 
 |   } | 
 |   { | 
 |     b.strictMode(&b.settings_); | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 13\n" | 
 |                                  "  Extra non-whitespace after JSON value.\n", | 
 |                                  errs); | 
 |     JSONTEST_ASSERT_EQUAL("property", root); | 
 |   } | 
 |   { | 
 |     b.strictMode(&b.settings_); | 
 |     b.settings_["failIfExtra"] = false; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL( | 
 |         "* Line 1, Column 1\n" | 
 |         "  A valid JSON document must be either an array or an object value.\n", | 
 |         errs); | 
 |     JSONTEST_ASSERT_EQUAL("property", root); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { | 
 |   // This is interpreted as an int value followed by a colon. | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   char const doc[] = "1:2:3"; | 
 |   b.settings_["failIfExtra"] = true; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(!ok); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 2\n" | 
 |                                "  Extra non-whitespace after JSON value.\n", | 
 |                                errs); | 
 |   JSONTEST_ASSERT_EQUAL(1, root.asInt()); | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterObject) { | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   { | 
 |     char const doc[] = "{ \"property\" : \"value\" } //trailing\n//comment\n"; | 
 |     b.settings_["failIfExtra"] = true; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL("value", root["property"]); | 
 |   } | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterArray) { | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   char const doc[] = "[ \"property\" , \"value\" ] //trailing\n//comment\n"; | 
 |   b.settings_["failIfExtra"] = true; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |   JSONTEST_ASSERT_EQUAL("value", root[1u]); | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterBool) { | 
 |   Json::CharReaderBuilder b; | 
 |   Json::Value root; | 
 |   char const doc[] = " true /*trailing\ncomment*/"; | 
 |   b.settings_["failIfExtra"] = true; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::String errs; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |   JSONTEST_ASSERT_EQUAL(true, root.asBool()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, parseComment) { | 
 |   Json::CharReaderBuilder b; | 
 |   b.settings_["failIfExtra"] = true; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   { | 
 |     char const doc[] = " true //comment1\n//comment2\r//comment3\r\n"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.asBool()); | 
 |   } | 
 |   { | 
 |     char const doc[] = " true //com\rment"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("* Line 2, Column 1\n" | 
 |                                  "  Extra non-whitespace after JSON value.\n", | 
 |                                  errs); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.asBool()); | 
 |   } | 
 |   { | 
 |     char const doc[] = " true //com\nment"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("* Line 2, Column 1\n" | 
 |                                  "  Extra non-whitespace after JSON value.\n", | 
 |                                  errs); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.asBool()); | 
 |   } | 
 | } | 
 |  | 
 | struct CharReaderAllowDropNullTest : JsonTest::TestCase { | 
 |   using Value = Json::Value; | 
 |   using ValueCheck = std::function<void(const Value&)>; | 
 |  | 
 |   Value nullValue = Value{Json::nullValue}; | 
 |   Value emptyArray = Value{Json::arrayValue}; | 
 |  | 
 |   ValueCheck checkEq(const Value& v) { | 
 |     return [=](const Value& root) { JSONTEST_ASSERT_EQUAL(root, v); }; | 
 |   } | 
 |  | 
 |   static ValueCheck objGetAnd(std::string idx, ValueCheck f) { | 
 |     return [=](const Value& root) { f(root.get(idx, true)); }; | 
 |   } | 
 |  | 
 |   static ValueCheck arrGetAnd(int idx, ValueCheck f) { | 
 |     return [=](const Value& root) { f(root[idx]); }; | 
 |   } | 
 | }; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { | 
 |   struct TestSpec { | 
 |     int line; | 
 |     std::string doc; | 
 |     size_t rootSize; | 
 |     ValueCheck onRoot; | 
 |   }; | 
 |   const TestSpec specs[] = { | 
 |       {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, | 
 |       {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, | 
 |       {__LINE__, R"({"a":})", 1, objGetAnd("a", checkEq(nullValue))}, | 
 |       {__LINE__, "[]", 0, checkEq(emptyArray)}, | 
 |       {__LINE__, "[null]", 1, nullptr}, | 
 |       {__LINE__, "[,]", 2, nullptr}, | 
 |       {__LINE__, "[,,,]", 4, nullptr}, | 
 |       {__LINE__, "[null,]", 2, nullptr}, | 
 |       {__LINE__, "[,null]", 2, nullptr}, | 
 |       {__LINE__, "[,,]", 3, nullptr}, | 
 |       {__LINE__, "[null,,]", 3, nullptr}, | 
 |       {__LINE__, "[,null,]", 3, nullptr}, | 
 |       {__LINE__, "[,,null]", 3, nullptr}, | 
 |       {__LINE__, "[[],,,]", 4, arrGetAnd(0, checkEq(emptyArray))}, | 
 |       {__LINE__, "[,[],,]", 4, arrGetAnd(1, checkEq(emptyArray))}, | 
 |       {__LINE__, "[,,,[]]", 4, arrGetAnd(3, checkEq(emptyArray))}, | 
 |   }; | 
 |   for (const auto& spec : specs) { | 
 |     Json::CharReaderBuilder b; | 
 |     b.settings_["allowDroppedNullPlaceholders"] = true; | 
 |     std::unique_ptr<Json::CharReader> reader(b.newCharReader()); | 
 |  | 
 |     Json::Value root; | 
 |     Json::String errs; | 
 |     bool ok = reader->parse(spec.doc.data(), spec.doc.data() + spec.doc.size(), | 
 |                             &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL(errs, ""); | 
 |     if (spec.onRoot) { | 
 |       spec.onRoot(root); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | struct CharReaderAllowNumericKeysTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderAllowNumericKeysTest, allowNumericKeys) { | 
 |   Json::CharReaderBuilder b; | 
 |   b.settings_["allowNumericKeys"] = true; | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   char const doc[] = "{15:true,-16:true,12.01:true}"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |   JSONTEST_ASSERT_EQUAL(3u, root.size()); | 
 |   JSONTEST_ASSERT_EQUAL(true, root.get("15", false)); | 
 |   JSONTEST_ASSERT_EQUAL(true, root.get("-16", false)); | 
 |   JSONTEST_ASSERT_EQUAL(true, root.get("12.01", false)); | 
 | } | 
 |  | 
 | struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderAllowSingleQuotesTest, issue182) { | 
 |   Json::CharReaderBuilder b; | 
 |   b.settings_["allowSingleQuotes"] = true; | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   { | 
 |     char const doc[] = "{'a':true,\"b\":true}"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(2u, root.size()); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.get("a", false)); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.get("b", false)); | 
 |   } | 
 |   { | 
 |     char const doc[] = "{'a': 'x', \"b\":'y'}"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(2u, root.size()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString()); | 
 |   } | 
 | } | 
 |  | 
 | struct CharReaderAllowZeroesTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderAllowZeroesTest, issue176) { | 
 |   Json::CharReaderBuilder b; | 
 |   b.settings_["allowSingleQuotes"] = true; | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   { | 
 |     char const doc[] = "{'a':true,\"b\":true}"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(2u, root.size()); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.get("a", false)); | 
 |     JSONTEST_ASSERT_EQUAL(true, root.get("b", false)); | 
 |   } | 
 |   { | 
 |     char const doc[] = "{'a': 'x', \"b\":'y'}"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(2u, root.size()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString()); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString()); | 
 |   } | 
 | } | 
 |  | 
 | struct CharReaderAllowSpecialFloatsTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, specialFloat) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   { | 
 |     char const doc[] = "{\"a\": NaN}"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL( | 
 |         "* Line 1, Column 7\n" | 
 |         "  Syntax error: value, object or array expected.\n", | 
 |         errs); | 
 |   } | 
 |   { | 
 |     char const doc[] = "{\"a\": Infinity}"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(!ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL( | 
 |         "* Line 1, Column 7\n" | 
 |         "  Syntax error: value, object or array expected.\n", | 
 |         errs); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { | 
 |   Json::CharReaderBuilder b; | 
 |   b.settings_["allowSpecialFloats"] = true; | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   { | 
 |     char const doc[] = R"({"a":NaN,"b":Infinity,"c":-Infinity,"d":+Infinity})"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(4u, root.size()); | 
 |     double n = root["a"].asDouble(); | 
 |     JSONTEST_ASSERT(std::isnan(n)); | 
 |     JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), | 
 |                           root.get("b", 0.0)); | 
 |     JSONTEST_ASSERT_EQUAL(-std::numeric_limits<double>::infinity(), | 
 |                           root.get("c", 0.0)); | 
 |     JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), | 
 |                           root.get("d", 0.0)); | 
 |   } | 
 |  | 
 |   struct TestData { | 
 |     int line; | 
 |     bool ok; | 
 |     Json::String in; | 
 |   }; | 
 |   const TestData test_data[] = { | 
 |       {__LINE__, true, "{\"a\":9}"},          // | 
 |       {__LINE__, false, "{\"a\":0Infinity}"}, // | 
 |       {__LINE__, false, "{\"a\":1Infinity}"}, // | 
 |       {__LINE__, false, "{\"a\":9Infinity}"}, // | 
 |       {__LINE__, false, "{\"a\":0nfinity}"},  // | 
 |       {__LINE__, false, "{\"a\":1nfinity}"},  // | 
 |       {__LINE__, false, "{\"a\":9nfinity}"},  // | 
 |       {__LINE__, false, "{\"a\":nfinity}"},   // | 
 |       {__LINE__, false, "{\"a\":.nfinity}"},  // | 
 |       {__LINE__, false, "{\"a\":9nfinity}"},  // | 
 |       {__LINE__, false, "{\"a\":-nfinity}"},  // | 
 |       {__LINE__, true, "{\"a\":Infinity}"},   // | 
 |       {__LINE__, false, "{\"a\":.Infinity}"}, // | 
 |       {__LINE__, false, "{\"a\":_Infinity}"}, // | 
 |       {__LINE__, false, "{\"a\":_nfinity}"},  // | 
 |       {__LINE__, true, "{\"a\":-Infinity}"},  // | 
 |       {__LINE__, true, "{\"a\":+Infinity}"}   // | 
 |   }; | 
 |   for (const auto& td : test_data) { | 
 |     bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), | 
 |                             &root, &errs); | 
 |     // clang-format off | 
 |     JSONTEST_ASSERT(td.ok == ok) << | 
 |         "line:" << td.line << "\n  " << | 
 |         "expected: {ok:" << td.ok << ", in:\'" << td.in << "\'}\n " << | 
 |         "actual: {ok:" << ok << "}\n"; | 
 |     // clang-format on | 
 |   } | 
 |  | 
 |   { | 
 |     char const doc[] = R"({"posInf": +Infinity, "NegInf": -Infinity})"; | 
 |     bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |     JSONTEST_ASSERT(ok); | 
 |     JSONTEST_ASSERT_STRING_EQUAL("", errs); | 
 |     JSONTEST_ASSERT_EQUAL(2u, root.size()); | 
 |     JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), | 
 |                           root["posInf"].asDouble()); | 
 |     JSONTEST_ASSERT_EQUAL(-std::numeric_limits<double>::infinity(), | 
 |                           root["NegInf"].asDouble()); | 
 |   } | 
 | } | 
 |  | 
 | struct EscapeSequenceTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, readerParseEscapeSequence) { | 
 |   Json::Reader reader; | 
 |   Json::Value root; | 
 |   bool ok = reader.parse("[\"\\\"\",\"\\/\",\"\\\\\",\"\\b\"," | 
 |                          "\"\\f\",\"\\n\",\"\\r\",\"\\t\"," | 
 |                          "\"\\u0278\",\"\\ud852\\udf62\"]\n", | 
 |                          root); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); | 
 |   JSONTEST_ASSERT(reader.getStructuredErrors().empty()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, charReaderParseEscapeSequence) { | 
 |   Json::CharReaderBuilder b; | 
 |   CharReaderPtr reader(b.newCharReader()); | 
 |   Json::Value root; | 
 |   Json::String errs; | 
 |   char const doc[] = "[\"\\\"\",\"\\/\",\"\\\\\",\"\\b\"," | 
 |                      "\"\\f\",\"\\n\",\"\\r\",\"\\t\"," | 
 |                      "\"\\u0278\",\"\\ud852\\udf62\"]"; | 
 |   bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT(errs.empty()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, writeEscapeSequence) { | 
 |   Json::FastWriter writer; | 
 |   const Json::String expected("[\"\\\"\",\"\\\\\",\"\\b\"," | 
 |                               "\"\\f\",\"\\n\",\"\\r\",\"\\t\"," | 
 |                               "\"\\u0278\",\"\\ud852\\udf62\"]\n"); | 
 |   Json::Value root; | 
 |   root[0] = "\""; | 
 |   root[1] = "\\"; | 
 |   root[2] = "\b"; | 
 |   root[3] = "\f"; | 
 |   root[4] = "\n"; | 
 |   root[5] = "\r"; | 
 |   root[6] = "\t"; | 
 |   root[7] = "ɸ"; | 
 |   root[8] = "𤭢"; | 
 |   const Json::String result = writer.write(root); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, result); | 
 | } | 
 |  | 
 | struct BuilderTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(BuilderTest, settings) { | 
 |   { | 
 |     Json::Value errs; | 
 |     Json::CharReaderBuilder rb; | 
 |     JSONTEST_ASSERT_EQUAL(false, rb.settings_.isMember("foo")); | 
 |     JSONTEST_ASSERT_EQUAL(true, rb.validate(&errs)); | 
 |     rb["foo"] = "bar"; | 
 |     JSONTEST_ASSERT_EQUAL(true, rb.settings_.isMember("foo")); | 
 |     JSONTEST_ASSERT_EQUAL(false, rb.validate(&errs)); | 
 |   } | 
 |   { | 
 |     Json::Value errs; | 
 |     Json::StreamWriterBuilder wb; | 
 |     JSONTEST_ASSERT_EQUAL(false, wb.settings_.isMember("foo")); | 
 |     JSONTEST_ASSERT_EQUAL(true, wb.validate(&errs)); | 
 |     wb["foo"] = "bar"; | 
 |     JSONTEST_ASSERT_EQUAL(true, wb.settings_.isMember("foo")); | 
 |     JSONTEST_ASSERT_EQUAL(false, wb.validate(&errs)); | 
 |   } | 
 | } | 
 |  | 
 | struct BomTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(BomTest, skipBom) { | 
 |   const std::string with_bom = "\xEF\xBB\xBF{\"key\" : \"value\"}"; | 
 |   Json::Value root; | 
 |   JSONCPP_STRING errs; | 
 |   std::istringstream iss(with_bom); | 
 |   bool ok = parseFromStream(Json::CharReaderBuilder(), iss, &root, &errs); | 
 |   // The default behavior is to skip the BOM, so we can parse it normally. | 
 |   JSONTEST_ASSERT(ok); | 
 |   JSONTEST_ASSERT(errs.empty()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(root["key"].asString(), "value"); | 
 | } | 
 | JSONTEST_FIXTURE_LOCAL(BomTest, notSkipBom) { | 
 |   const std::string with_bom = "\xEF\xBB\xBF{\"key\" : \"value\"}"; | 
 |   Json::Value root; | 
 |   JSONCPP_STRING errs; | 
 |   std::istringstream iss(with_bom); | 
 |   Json::CharReaderBuilder b; | 
 |   b.settings_["skipBom"] = false; | 
 |   bool ok = parseFromStream(b, iss, &root, &errs); | 
 |   // Detect the BOM, and failed on it. | 
 |   JSONTEST_ASSERT(!ok); | 
 |   JSONTEST_ASSERT(!errs.empty()); | 
 | } | 
 |  | 
 | struct IteratorTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, convert) { | 
 |   Json::Value j; | 
 |   const Json::Value& cj = j; | 
 |   auto it = j.begin(); | 
 |   Json::Value::const_iterator cit; | 
 |   cit = it; | 
 |   JSONTEST_ASSERT(cit == cj.begin()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, decrement) { | 
 |   Json::Value json; | 
 |   json["k1"] = "a"; | 
 |   json["k2"] = "b"; | 
 |   std::vector<std::string> values; | 
 |   for (auto it = json.end(); it != json.begin();) { | 
 |     --it; | 
 |     values.push_back(it->asString()); | 
 |   } | 
 |   JSONTEST_ASSERT((values == std::vector<std::string>{"b", "a"})); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, reverseIterator) { | 
 |   Json::Value json; | 
 |   json["k1"] = "a"; | 
 |   json["k2"] = "b"; | 
 |   std::vector<std::string> values; | 
 |   using Iter = decltype(json.begin()); | 
 |   auto re = std::reverse_iterator<Iter>(json.begin()); | 
 |   for (auto it = std::reverse_iterator<Iter>(json.end()); it != re; ++it) { | 
 |     values.push_back(it->asString()); | 
 |   } | 
 |   JSONTEST_ASSERT((values == std::vector<std::string>{"b", "a"})); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { | 
 |   { | 
 |     Json::Value json; | 
 |     json["k1"] = "a"; | 
 |     json["k2"] = "b"; | 
 |     int i = 0; | 
 |     auto it = json.begin(); | 
 |     for (;; ++it, ++i) { | 
 |       auto dist = it - json.begin(); | 
 |       JSONTEST_ASSERT_EQUAL(i, dist); | 
 |       if (it == json.end()) | 
 |         break; | 
 |     } | 
 |   } | 
 |   { | 
 |     Json::Value empty; | 
 |     JSONTEST_ASSERT_EQUAL(0, empty.end() - empty.end()); | 
 |     JSONTEST_ASSERT_EQUAL(0, empty.end() - empty.begin()); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, nullValues) { | 
 |   { | 
 |     Json::Value json; | 
 |     auto end = json.end(); | 
 |     auto endCopy = end; | 
 |     JSONTEST_ASSERT(endCopy == end); | 
 |     endCopy = end; | 
 |     JSONTEST_ASSERT(endCopy == end); | 
 |   } | 
 |   { | 
 |     // Same test, now with const Value. | 
 |     const Json::Value json; | 
 |     auto end = json.end(); | 
 |     auto endCopy = end; | 
 |     JSONTEST_ASSERT(endCopy == end); | 
 |     endCopy = end; | 
 |     JSONTEST_ASSERT(endCopy == end); | 
 |   } | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, staticStringKey) { | 
 |   Json::Value json; | 
 |   json[Json::StaticString("k1")] = "a"; | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("k1"), json.begin().key()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, names) { | 
 |   Json::Value json; | 
 |   json["k1"] = "a"; | 
 |   json["k2"] = "b"; | 
 |   Json::ValueIterator it = json.begin(); | 
 |   JSONTEST_ASSERT(it != json.end()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("k1"), it.key()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("k1", it.name()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("k1", it.memberName()); | 
 |   JSONTEST_ASSERT_EQUAL(-1, it.index()); | 
 |   ++it; | 
 |   JSONTEST_ASSERT(it != json.end()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value("k2"), it.key()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("k2", it.name()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("k2", it.memberName()); | 
 |   JSONTEST_ASSERT_EQUAL(-1, it.index()); | 
 |   ++it; | 
 |   JSONTEST_ASSERT(it == json.end()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, indexes) { | 
 |   Json::Value json; | 
 |   json[0] = "a"; | 
 |   json[1] = "b"; | 
 |   Json::ValueIterator it = json.begin(); | 
 |   JSONTEST_ASSERT(it != json.end()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(0)), it.key()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("", it.name()); | 
 |   JSONTEST_ASSERT_EQUAL(0, it.index()); | 
 |   ++it; | 
 |   JSONTEST_ASSERT(it != json.end()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(1)), it.key()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL("", it.name()); | 
 |   JSONTEST_ASSERT_EQUAL(1, it.index()); | 
 |   ++it; | 
 |   JSONTEST_ASSERT(it == json.end()); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(IteratorTest, constness) { | 
 |   Json::Value const v; | 
 |   JSONTEST_ASSERT_THROWS( | 
 |       Json::Value::iterator it(v.begin())); // Compile, but throw. | 
 |  | 
 |   Json::Value value; | 
 |  | 
 |   for (int i = 9; i < 12; ++i) { | 
 |     Json::OStringStream out; | 
 |     out << std::setw(2) << i; | 
 |     Json::String str = out.str(); | 
 |     value[str] = str; | 
 |   } | 
 |  | 
 |   Json::OStringStream out; | 
 |   // in old code, this will get a compile error | 
 |   Json::Value::const_iterator iter = value.begin(); | 
 |   for (; iter != value.end(); ++iter) { | 
 |     out << *iter << ','; | 
 |   } | 
 |   Json::String expected = R"(" 9","10","11",)"; | 
 |   JSONTEST_ASSERT_STRING_EQUAL(expected, out.str()); | 
 | } | 
 |  | 
 | struct RValueTest : JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(RValueTest, moveConstruction) { | 
 |   Json::Value json; | 
 |   json["key"] = "value"; | 
 |   Json::Value moved = std::move(json); | 
 |   JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not | 
 |                                   // equal. | 
 |   JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type()); | 
 |   JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type()); | 
 | } | 
 |  | 
 | struct FuzzTest : JsonTest::TestCase {}; | 
 |  | 
 | // Build and run the fuzz test without any fuzzer, so that it's guaranteed not | 
 | // go out of date, even if it's never run as an actual fuzz test. | 
 | JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) { | 
 |   const std::string example = "{}"; | 
 |   JSONTEST_ASSERT_EQUAL( | 
 |       0, | 
 |       LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t*>(example.c_str()), | 
 |                              example.size())); | 
 | } | 
 |  | 
 | struct ParseWithStructuredErrorsTest : JsonTest::TestCase { | 
 |   void testErrors( | 
 |       const std::string& doc, bool success, | 
 |       const std::vector<Json::CharReader::StructuredError>& expectedErrors) { | 
 |     Json::CharReaderBuilder b; | 
 |     CharReaderPtr reader(b.newCharReader()); | 
 |     Json::Value root; | 
 |     JSONTEST_ASSERT_EQUAL( | 
 |         reader->parse(doc.data(), doc.data() + doc.length(), &root, nullptr), | 
 |         success); | 
 |     auto actualErrors = reader->getStructuredErrors(); | 
 |     JSONTEST_ASSERT_EQUAL(expectedErrors.size(), actualErrors.size()); | 
 |     for (std::size_t i = 0; i < actualErrors.size(); i++) { | 
 |       const auto& a = actualErrors[i]; | 
 |       const auto& e = expectedErrors[i]; | 
 |       JSONTEST_ASSERT_EQUAL(a.offset_start, e.offset_start); | 
 |       JSONTEST_ASSERT_EQUAL(a.offset_limit, e.offset_limit); | 
 |       JSONTEST_ASSERT_STRING_EQUAL(a.message, e.message); | 
 |     } | 
 |   } | 
 | }; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ParseWithStructuredErrorsTest, success) { | 
 |   testErrors("{}", true, {}); | 
 | } | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(ParseWithStructuredErrorsTest, singleError) { | 
 |   testErrors("{ 1 : 2 }", false, {{2, 3, "Missing '}' or object member name"}}); | 
 | } | 
 |  | 
 | int main(int argc, const char* argv[]) { | 
 |   JsonTest::Runner runner; | 
 |  | 
 |   for (auto& local : local_) { | 
 |     runner.add(local); | 
 |   } | 
 |  | 
 |   return runner.runCommandLine(argc, argv); | 
 | } | 
 |  | 
 | struct MemberTemplateAs : JsonTest::TestCase { | 
 |   template <typename T, typename F> | 
 |   JsonTest::TestResult& EqEval(T v, F f) const { | 
 |     const Json::Value j = v; | 
 |     return JSONTEST_ASSERT_EQUAL(j.as<T>(), f(j)); | 
 |   } | 
 | }; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(MemberTemplateAs, BehavesSameAsNamedAs) { | 
 |   const Json::Value jstr = "hello world"; | 
 |   JSONTEST_ASSERT_STRING_EQUAL(jstr.as<const char*>(), jstr.asCString()); | 
 |   JSONTEST_ASSERT_STRING_EQUAL(jstr.as<Json::String>(), jstr.asString()); | 
 |   EqEval(Json::Int(64), [](const Json::Value& j) { return j.asInt(); }); | 
 |   EqEval(Json::UInt(64), [](const Json::Value& j) { return j.asUInt(); }); | 
 | #if defined(JSON_HAS_INT64) | 
 |   EqEval(Json::Int64(64), [](const Json::Value& j) { return j.asInt64(); }); | 
 |   EqEval(Json::UInt64(64), [](const Json::Value& j) { return j.asUInt64(); }); | 
 | #endif // if defined(JSON_HAS_INT64) | 
 |   EqEval(Json::LargestInt(64), | 
 |          [](const Json::Value& j) { return j.asLargestInt(); }); | 
 |   EqEval(Json::LargestUInt(64), | 
 |          [](const Json::Value& j) { return j.asLargestUInt(); }); | 
 |  | 
 |   EqEval(69.69f, [](const Json::Value& j) { return j.asFloat(); }); | 
 |   EqEval(69.69, [](const Json::Value& j) { return j.asDouble(); }); | 
 |   EqEval(false, [](const Json::Value& j) { return j.asBool(); }); | 
 |   EqEval(true, [](const Json::Value& j) { return j.asBool(); }); | 
 | } | 
 |  | 
 | class MemberTemplateIs : public JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(MemberTemplateIs, BehavesSameAsNamedIs) { | 
 |   const Json::Value values[] = {true, 142, 40.63, "hello world"}; | 
 |   for (const Json::Value& j : values) { | 
 |     JSONTEST_ASSERT_EQUAL(j.is<bool>(), j.isBool()); | 
 |     JSONTEST_ASSERT_EQUAL(j.is<Json::Int>(), j.isInt()); | 
 |     JSONTEST_ASSERT_EQUAL(j.is<Json::Int64>(), j.isInt64()); | 
 |     JSONTEST_ASSERT_EQUAL(j.is<Json::UInt>(), j.isUInt()); | 
 |     JSONTEST_ASSERT_EQUAL(j.is<Json::UInt64>(), j.isUInt64()); | 
 |     JSONTEST_ASSERT_EQUAL(j.is<double>(), j.isDouble()); | 
 |     JSONTEST_ASSERT_EQUAL(j.is<Json::String>(), j.isString()); | 
 |   } | 
 | } | 
 |  | 
 | class VersionTest : public JsonTest::TestCase {}; | 
 |  | 
 | JSONTEST_FIXTURE_LOCAL(VersionTest, VersionNumbersMatch) { | 
 |   std::ostringstream vstr; | 
 |   vstr << JSONCPP_VERSION_MAJOR << '.' << JSONCPP_VERSION_MINOR << '.' | 
 |        << JSONCPP_VERSION_PATCH; | 
 |   JSONTEST_ASSERT_EQUAL(vstr.str(), std::string(JSONCPP_VERSION_STRING)); | 
 | } | 
 |  | 
 | #if defined(__GNUC__) | 
 | #pragma GCC diagnostic pop | 
 | #endif |