diff options
Diffstat (limited to '3rdparty/jsoncpp/src')
-rw-r--r-- | 3rdparty/jsoncpp/src/CMakeLists.txt | 5 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/jsontestrunner/CMakeLists.txt | 25 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/jsontestrunner/main.cpp | 325 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/jsontestrunner/sconscript | 9 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/CMakeLists.txt | 80 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/json_reader.cpp | 1977 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/json_tool.h | 87 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/json_value.cpp | 1544 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/json_valueiterator.inl | 162 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/json_writer.cpp | 1179 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/sconscript | 8 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/lib_json/version.h.in | 14 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/test_lib_json/CMakeLists.txt | 38 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/test_lib_json/jsontest.cpp | 443 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/test_lib_json/jsontest.h | 280 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/test_lib_json/main.cpp | 2406 | ||||
-rw-r--r-- | 3rdparty/jsoncpp/src/test_lib_json/sconscript | 10 |
17 files changed, 0 insertions, 8592 deletions
diff --git a/3rdparty/jsoncpp/src/CMakeLists.txt b/3rdparty/jsoncpp/src/CMakeLists.txt deleted file mode 100644 index 608d3f7b67d..00000000000 --- a/3rdparty/jsoncpp/src/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -ADD_SUBDIRECTORY(lib_json) -IF(JSONCPP_WITH_TESTS) - ADD_SUBDIRECTORY(jsontestrunner) - ADD_SUBDIRECTORY(test_lib_json) -ENDIF(JSONCPP_WITH_TESTS) diff --git a/3rdparty/jsoncpp/src/jsontestrunner/CMakeLists.txt b/3rdparty/jsoncpp/src/jsontestrunner/CMakeLists.txt deleted file mode 100644 index 820a7cd3524..00000000000 --- a/3rdparty/jsoncpp/src/jsontestrunner/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -FIND_PACKAGE(PythonInterp 2.6) - -ADD_EXECUTABLE(jsontestrunner_exe - main.cpp - ) - -IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS( -DJSON_DLL ) - TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib) -ELSE(BUILD_SHARED_LIBS) - TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib_static) -ENDIF(BUILD_SHARED_LIBS) - -SET_TARGET_PROPERTIES(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe) - -IF(PYTHONINTERP_FOUND) - # Run end to end parser/writer tests - SET(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test) - SET(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py) - ADD_CUSTOM_TARGET(jsoncpp_readerwriter_tests - "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data" - DEPENDS jsontestrunner_exe jsoncpp_test - ) - ADD_CUSTOM_TARGET(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests) -ENDIF(PYTHONINTERP_FOUND) diff --git a/3rdparty/jsoncpp/src/jsontestrunner/main.cpp b/3rdparty/jsoncpp/src/jsontestrunner/main.cpp deleted file mode 100644 index 1ec1fb6fbcd..00000000000 --- a/3rdparty/jsoncpp/src/jsontestrunner/main.cpp +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// 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 - -/* This executable is used for testing parser/writer using real JSON files. - */ - -#include <json/json.h> -#include <algorithm> // sort -#include <sstream> -#include <stdio.h> - -#if defined(_MSC_VER) && _MSC_VER >= 1310 -#pragma warning(disable : 4996) // disable fopen deprecation warning -#endif - -struct Options -{ - std::string path; - Json::Features features; - bool parseOnly; - typedef std::string (*writeFuncType)(Json::Value const&); - writeFuncType write; -}; - -static std::string normalizeFloatingPointStr(double value) { - char buffer[32]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) - sprintf_s(buffer, sizeof(buffer), "%.16g", value); -#else - snprintf(buffer, sizeof(buffer), "%.16g", value); -#endif - buffer[sizeof(buffer) - 1] = 0; - std::string s(buffer); - std::string::size_type index = s.find_last_of("eE"); - if (index != std::string::npos) { - std::string::size_type hasSign = - (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - std::string::size_type exponentStartIndex = index + 1 + hasSign; - std::string normalized = s.substr(0, exponentStartIndex); - std::string::size_type indexDigit = - s.find_first_not_of('0', exponentStartIndex); - std::string exponent = "0"; - if (indexDigit != - std::string::npos) // There is an exponent different from 0 - { - exponent = s.substr(indexDigit); - } - return normalized + exponent; - } - return s; -} - -static std::string readInputTestFile(const char* path) { - FILE* file = fopen(path, "rb"); - if (!file) - return std::string(""); - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - std::string text; - char* buffer = new char[size + 1]; - buffer[size] = 0; - if (fread(buffer, 1, size, file) == (unsigned long)size) - text = buffer; - fclose(file); - delete[] buffer; - return text; -} - -static void -printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") { - if (value.hasComment(Json::commentBefore)) { - fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); - } - switch (value.type()) { - case Json::nullValue: - fprintf(fout, "%s=null\n", path.c_str()); - break; - case Json::intValue: - fprintf(fout, - "%s=%s\n", - path.c_str(), - Json::valueToString(value.asLargestInt()).c_str()); - break; - case Json::uintValue: - fprintf(fout, - "%s=%s\n", - path.c_str(), - Json::valueToString(value.asLargestUInt()).c_str()); - break; - case Json::realValue: - fprintf(fout, - "%s=%s\n", - path.c_str(), - normalizeFloatingPointStr(value.asDouble()).c_str()); - break; - case Json::stringValue: - fprintf(fout, "%s=\"%s\"\n", path.c_str(), value.asString().c_str()); - break; - case Json::booleanValue: - fprintf(fout, "%s=%s\n", path.c_str(), value.asBool() ? "true" : "false"); - break; - case Json::arrayValue: { - fprintf(fout, "%s=[]\n", path.c_str()); - int size = value.size(); - for (int index = 0; index < size; ++index) { - static char buffer[16]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) - sprintf_s(buffer, sizeof(buffer), "[%d]", index); -#else - snprintf(buffer, sizeof(buffer), "[%d]", index); -#endif - printValueTree(fout, value[index], path + buffer); - } - } break; - case Json::objectValue: { - fprintf(fout, "%s={}\n", path.c_str()); - Json::Value::Members members(value.getMemberNames()); - std::sort(members.begin(), members.end()); - std::string suffix = *(path.end() - 1) == '.' ? "" : "."; - for (Json::Value::Members::iterator it = members.begin(); - it != members.end(); - ++it) { - const std::string& name = *it; - printValueTree(fout, value[name], path + suffix + name); - } - } break; - default: - break; - } - - if (value.hasComment(Json::commentAfter)) { - fprintf(fout, "%s\n", value.getComment(Json::commentAfter).c_str()); - } -} - -static int parseAndSaveValueTree(const std::string& input, - const std::string& actual, - const std::string& kind, - const Json::Features& features, - bool parseOnly, - Json::Value* root) -{ - Json::Reader reader(features); - bool parsingSuccessful = reader.parse(input, *root); - if (!parsingSuccessful) { - printf("Failed to parse %s file: \n%s\n", - kind.c_str(), - reader.getFormattedErrorMessages().c_str()); - return 1; - } - if (!parseOnly) { - FILE* factual = fopen(actual.c_str(), "wt"); - if (!factual) { - printf("Failed to create %s actual file.\n", kind.c_str()); - return 2; - } - printValueTree(factual, *root); - fclose(factual); - } - return 0; -} -// static std::string useFastWriter(Json::Value const& root) { -// Json::FastWriter writer; -// writer.enableYAMLCompatibility(); -// return writer.write(root); -// } -static std::string useStyledWriter( - Json::Value const& root) -{ - Json::StyledWriter writer; - return writer.write(root); -} -static std::string useStyledStreamWriter( - Json::Value const& root) -{ - Json::StyledStreamWriter writer; - std::ostringstream sout; - writer.write(sout, root); - return sout.str(); -} -static std::string useBuiltStyledStreamWriter( - Json::Value const& root) -{ - Json::StreamWriterBuilder builder; - return Json::writeString(builder, root); -} -static int rewriteValueTree( - const std::string& rewritePath, - const Json::Value& root, - Options::writeFuncType write, - std::string* rewrite) -{ - *rewrite = write(root); - FILE* fout = fopen(rewritePath.c_str(), "wt"); - if (!fout) { - printf("Failed to create rewrite file: %s\n", rewritePath.c_str()); - return 2; - } - fprintf(fout, "%s\n", rewrite->c_str()); - fclose(fout); - return 0; -} - -static std::string removeSuffix(const std::string& path, - const std::string& extension) { - if (extension.length() >= path.length()) - return std::string(""); - std::string suffix = path.substr(path.length() - extension.length()); - if (suffix != extension) - return std::string(""); - return path.substr(0, path.length() - extension.length()); -} - -static void printConfig() { -// Print the configuration used to compile JsonCpp -#if defined(JSON_NO_INT64) - printf("JSON_NO_INT64=1\n"); -#else - printf("JSON_NO_INT64=0\n"); -#endif -} - -static int printUsage(const char* argv[]) { - printf("Usage: %s [--strict] input-json-file", argv[0]); - return 3; -} - -static int parseCommandLine( - int argc, const char* argv[], Options* opts) -{ - opts->parseOnly = false; - opts->write = &useStyledWriter; - if (argc < 2) { - return printUsage(argv); - } - int index = 1; - if (std::string(argv[index]) == "--json-checker") { - opts->features = Json::Features::strictMode(); - opts->parseOnly = true; - ++index; - } - if (std::string(argv[index]) == "--json-config") { - printConfig(); - return 3; - } - if (std::string(argv[index]) == "--json-writer") { - ++index; - std::string const writerName(argv[index++]); - if (writerName == "StyledWriter") { - opts->write = &useStyledWriter; - } else if (writerName == "StyledStreamWriter") { - opts->write = &useStyledStreamWriter; - } else if (writerName == "BuiltStyledStreamWriter") { - opts->write = &useBuiltStyledStreamWriter; - } else { - printf("Unknown '--json-writer %s'\n", writerName.c_str()); - return 4; - } - } - if (index == argc || index + 1 < argc) { - return printUsage(argv); - } - opts->path = argv[index]; - return 0; -} -static int runTest(Options const& opts) -{ - int exitCode = 0; - - std::string input = readInputTestFile(opts.path.c_str()); - if (input.empty()) { - printf("Failed to read input or empty input: %s\n", opts.path.c_str()); - return 3; - } - - std::string basePath = removeSuffix(opts.path, ".json"); - if (!opts.parseOnly && basePath.empty()) { - printf("Bad input path. Path does not end with '.expected':\n%s\n", - opts.path.c_str()); - return 3; - } - - std::string const actualPath = basePath + ".actual"; - std::string const rewritePath = basePath + ".rewrite"; - std::string const rewriteActualPath = basePath + ".actual-rewrite"; - - Json::Value root; - exitCode = parseAndSaveValueTree( - input, actualPath, "input", - opts.features, opts.parseOnly, &root); - if (exitCode || opts.parseOnly) { - return exitCode; - } - std::string rewrite; - exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite); - if (exitCode) { - return exitCode; - } - Json::Value rewriteRoot; - exitCode = parseAndSaveValueTree( - rewrite, rewriteActualPath, "rewrite", - opts.features, opts.parseOnly, &rewriteRoot); - if (exitCode) { - return exitCode; - } - return 0; -} -int main(int argc, const char* argv[]) { - Options opts; - int exitCode = parseCommandLine(argc, argv, &opts); - if (exitCode != 0) { - printf("Failed to parse command-line."); - return exitCode; - } - try { - return runTest(opts); - } - catch (const std::exception& e) { - printf("Unhandled exception:\n%s\n", e.what()); - return 1; - } -} diff --git a/3rdparty/jsoncpp/src/jsontestrunner/sconscript b/3rdparty/jsoncpp/src/jsontestrunner/sconscript deleted file mode 100644 index 6e68e31533e..00000000000 --- a/3rdparty/jsoncpp/src/jsontestrunner/sconscript +++ /dev/null @@ -1,9 +0,0 @@ -Import( 'env_testing buildJSONTests' ) - -buildJSONTests( env_testing, Split( """ - main.cpp - """ ), - 'jsontestrunner' ) - -# For 'check' to work, 'libs' must be built first. -env_testing.Depends('jsontestrunner', '#libs') diff --git a/3rdparty/jsoncpp/src/lib_json/CMakeLists.txt b/3rdparty/jsoncpp/src/lib_json/CMakeLists.txt deleted file mode 100644 index 79ffa2ec5fe..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -if( CMAKE_COMPILER_IS_GNUCXX ) - #Get compiler version. - execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion - OUTPUT_VARIABLE GNUCXX_VERSION ) - - #-Werror=* was introduced -after- GCC 4.1.2 - if( GNUCXX_VERSION VERSION_GREATER 4.1.2 ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=strict-aliasing") - endif() -endif( CMAKE_COMPILER_IS_GNUCXX ) - -SET( JSONCPP_INCLUDE_DIR ../../include ) - -SET( PUBLIC_HEADERS - ${JSONCPP_INCLUDE_DIR}/json/config.h - ${JSONCPP_INCLUDE_DIR}/json/forwards.h - ${JSONCPP_INCLUDE_DIR}/json/features.h - ${JSONCPP_INCLUDE_DIR}/json/value.h - ${JSONCPP_INCLUDE_DIR}/json/reader.h - ${JSONCPP_INCLUDE_DIR}/json/writer.h - ${JSONCPP_INCLUDE_DIR}/json/assertions.h - ${JSONCPP_INCLUDE_DIR}/json/version.h - ) - -SOURCE_GROUP( "Public API" FILES ${PUBLIC_HEADERS} ) - -SET(jsoncpp_sources - json_tool.h - json_reader.cpp - json_valueiterator.inl - json_value.cpp - json_writer.cpp - version.h.in) - -# Install instructions for this target -IF(JSONCPP_WITH_CMAKE_PACKAGE) - SET(INSTALL_EXPORT EXPORT jsoncpp) -ELSE(JSONCPP_WITH_CMAKE_PACKAGE) - SET(INSTALL_EXPORT) -ENDIF(JSONCPP_WITH_CMAKE_PACKAGE) - -IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS( -DJSON_DLL_BUILD ) - ADD_LIBRARY(jsoncpp_lib SHARED ${PUBLIC_HEADERS} ${jsoncpp_sources}) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_VERSION_MAJOR}) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp - DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) - - INSTALL( TARGETS jsoncpp_lib ${INSTALL_EXPORT} - RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR} - LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR}) - - IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib PUBLIC - $<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}> - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>) - ENDIF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - -ENDIF() - -IF(BUILD_STATIC_LIBS) - ADD_LIBRARY(jsoncpp_lib_static STATIC ${PUBLIC_HEADERS} ${jsoncpp_sources}) - SET_TARGET_PROPERTIES( jsoncpp_lib_static PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_VERSION_MAJOR}) - SET_TARGET_PROPERTIES( jsoncpp_lib_static PROPERTIES OUTPUT_NAME jsoncpp - DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) - - INSTALL( TARGETS jsoncpp_lib_static ${INSTALL_EXPORT} - RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR} - LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR}) - - IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib_static PUBLIC - $<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}> - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}> - ) - ENDIF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - -ENDIF() diff --git a/3rdparty/jsoncpp/src/lib_json/json_reader.cpp b/3rdparty/jsoncpp/src/lib_json/json_reader.cpp deleted file mode 100644 index ceff66c3134..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/json_reader.cpp +++ /dev/null @@ -1,1977 +0,0 @@ -// Copyright 2007-2011 Baptiste Lepilleur -// 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(JSON_IS_AMALGAMATION) -#include <json/assertions.h> -#include <json/reader.h> -#include <json/value.h> -#include "json_tool.h" -#endif // if !defined(JSON_IS_AMALGAMATION) -#include <utility> -#include <cstdio> -#include <cassert> -#include <cstring> -#include <istream> -#include <sstream> -#include <memory> -#include <set> - -#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below -#define snprintf _snprintf -#endif - -#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 -// Disable warning about strdup being deprecated. -#pragma warning(disable : 4996) -#endif - -static int const stackLimit_g = 1000; -static int stackDepth_g = 0; // see readValue() - -namespace Json { - -#if __cplusplus >= 201103L -typedef std::unique_ptr<CharReader> CharReaderPtr; -#else -typedef std::auto_ptr<CharReader> CharReaderPtr; -#endif - -// Implementation of class Features -// //////////////////////////////// - -Features::Features() - : allowComments_(true), strictRoot_(false), - allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} - -Features Features::all() { return Features(); } - -Features Features::strictMode() { - Features features; - features.allowComments_ = false; - features.strictRoot_ = true; - features.allowDroppedNullPlaceholders_ = false; - features.allowNumericKeys_ = false; - return features; -} - -// Implementation of class Reader -// //////////////////////////////// - -static bool containsNewLine(Reader::Location begin, Reader::Location end) { - for (; begin < end; ++begin) - if (*begin == '\n' || *begin == '\r') - return true; - return false; -} - -// Class Reader -// ////////////////////////////////////////////////////////////////// - -Reader::Reader() - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(Features::all()), - collectComments_() {} - -Reader::Reader(const Features& features) - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(features), collectComments_() { -} - -bool -Reader::parse(const std::string& document, Value& root, bool collectComments) { - document_ = document; - const char* begin = document_.c_str(); - const char* end = begin + document_.length(); - return parse(begin, end, root, collectComments); -} - -bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { - // std::istream_iterator<char> begin(sin); - // std::istream_iterator<char> end; - // Those would allow streamed input from a file, if parse() were a - // template function. - - // Since std::string is reference-counted, this at least does not - // create an extra copy. - std::string doc; - std::getline(sin, doc, (char)EOF); - return parse(doc, root, collectComments); -} - -bool Reader::parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments) { - if (!features_.allowComments_) { - collectComments = false; - } - - begin_ = beginDoc; - end_ = endDoc; - collectComments_ = collectComments; - current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; - commentsBefore_ = ""; - errors_.clear(); - while (!nodes_.empty()) - nodes_.pop(); - nodes_.push(&root); - - stackDepth_g = 0; // Yes, this is bad coding, but options are limited. - bool successful = readValue(); - Token token; - skipCommentTokens(token); - if (collectComments_ && !commentsBefore_.empty()) - root.setComment(commentsBefore_, commentAfter); - if (features_.strictRoot_) { - if (!root.isArray() && !root.isObject()) { - // Set error location to start of doc, ideally should be first token found - // in doc - token.type_ = tokenError; - token.start_ = beginDoc; - token.end_ = endDoc; - addError( - "A valid JSON document must be either an array or an object value.", - token); - return false; - } - } - return successful; -} - -bool Reader::readValue() { - // This is a non-reentrant way to support a stackLimit. Terrible! - // But this deprecated class has a security problem: Bad input can - // cause a seg-fault. This seems like a fair, binary-compatible way - // to prevent the problem. - if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); - ++stackDepth_g; - - Token token; - skipCommentTokens(token); - bool successful = true; - - if (collectComments_ && !commentsBefore_.empty()) { - currentValue().setComment(commentsBefore_, commentBefore); - commentsBefore_ = ""; - } - - switch (token.type_) { - case tokenObjectBegin: - successful = readObject(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenArrayBegin: - successful = readArray(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenNumber: - successful = decodeNumber(token); - break; - case tokenString: - successful = decodeString(token); - break; - case tokenTrue: - { - Value v(true); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenFalse: - { - Value v(false); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNull: - { - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenArraySeparator: - case tokenObjectEnd: - case tokenArrayEnd: - if (features_.allowDroppedNullPlaceholders_) { - // "Un-read" the current token and mark the current value as a null - // token. - current_--; - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(current_ - begin_ - 1); - currentValue().setOffsetLimit(current_ - begin_); - break; - } // Else, fall through... - default: - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return addError("Syntax error: value, object or array expected.", token); - } - - if (collectComments_) { - lastValueEnd_ = current_; - lastValue_ = ¤tValue(); - } - - --stackDepth_g; - return successful; -} - -void Reader::skipCommentTokens(Token& token) { - if (features_.allowComments_) { - do { - readToken(token); - } while (token.type_ == tokenComment); - } else { - readToken(token); - } -} - -bool Reader::readToken(Token& token) { - skipSpaces(); - token.start_ = current_; - Char c = getNextChar(); - bool ok = true; - switch (c) { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = readString(); - break; - case '/': - token.type_ = tokenComment; - ok = readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - token.type_ = tokenNumber; - readNumber(); - break; - case 't': - token.type_ = tokenTrue; - ok = match("rue", 3); - break; - case 'f': - token.type_ = tokenFalse; - ok = match("alse", 4); - break; - case 'n': - token.type_ = tokenNull; - ok = match("ull", 3); - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: - ok = false; - break; - } - if (!ok) - token.type_ = tokenError; - token.end_ = current_; - return true; -} - -void Reader::skipSpaces() { - while (current_ != end_) { - Char c = *current_; - if (c == ' ' || c == '\t' || c == '\r' || c == '\n') - ++current_; - else - break; - } -} - -bool Reader::match(Location pattern, int patternLength) { - if (end_ - current_ < patternLength) - return false; - int index = patternLength; - while (index--) - if (current_[index] != pattern[index]) - return false; - current_ += patternLength; - return true; -} - -bool Reader::readComment() { - Location commentBegin = current_ - 1; - Char c = getNextChar(); - bool successful = false; - if (c == '*') - successful = readCStyleComment(); - else if (c == '/') - successful = readCppStyleComment(); - if (!successful) - return false; - - if (collectComments_) { - CommentPlacement placement = commentBefore; - if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, current_)) - placement = commentAfterOnSameLine; - } - - addComment(commentBegin, current_, placement); - } - return true; -} - -static std::string normalizeEOL(Reader::Location begin, Reader::Location end) { - std::string normalized; - normalized.reserve(end - begin); - Reader::Location current = begin; - while (current != end) { - char c = *current++; - if (c == '\r') { - if (current != end && *current == '\n') - // convert dos EOL - ++current; - // convert Mac EOL - normalized += '\n'; - } else { - normalized += c; - } - } - return normalized; -} - -void -Reader::addComment(Location begin, Location end, CommentPlacement placement) { - assert(collectComments_); - const std::string& normalized = normalizeEOL(begin, end); - if (placement == commentAfterOnSameLine) { - assert(lastValue_ != 0); - lastValue_->setComment(normalized, placement); - } else { - commentsBefore_ += normalized; - } -} - -bool Reader::readCStyleComment() { - while (current_ != end_) { - Char c = getNextChar(); - if (c == '*' && *current_ == '/') - break; - } - return getNextChar() == '/'; -} - -bool Reader::readCppStyleComment() { - while (current_ != end_) { - Char c = getNextChar(); - if (c == '\n') - break; - if (c == '\r') { - // Consume DOS EOL. It will be normalized in addComment. - if (current_ != end_ && *current_ == '\n') - getNextChar(); - // Break on Moc OS 9 EOL. - break; - } - } - return true; -} - -void Reader::readNumber() { - const char *p = current_; - char c = '0'; // stopgap for already consumed character - // integral part - while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : 0; - // fractional part - if (c == '.') { - c = (current_ = p) < end_ ? *p++ : 0; - while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : 0; - } - // exponential part - if (c == 'e' || c == 'E') { - c = (current_ = p) < end_ ? *p++ : 0; - if (c == '+' || c == '-') - c = (current_ = p) < end_ ? *p++ : 0; - while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : 0; - } -} - -bool Reader::readString() { - Char c = 0; - while (current_ != end_) { - c = getNextChar(); - if (c == '\\') - getNextChar(); - else if (c == '"') - break; - } - return c == '"'; -} - -bool Reader::readObject(Token& tokenStart) { - Token tokenName; - std::string name; - Value init(objectValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - while (readToken(tokenName)) { - bool initialTokenOk = true; - while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); - if (!initialTokenOk) - break; - if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object - return true; - name = ""; - if (tokenName.type_ == tokenString) { - if (!decodeString(tokenName, name)) - return recoverFromError(tokenObjectEnd); - } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { - Value numberName; - if (!decodeNumber(tokenName, numberName)) - return recoverFromError(tokenObjectEnd); - name = numberName.asString(); - } else { - break; - } - - Token colon; - if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover( - "Missing ':' after object member name", colon, tokenObjectEnd); - } - Value& value = currentValue()[name]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); - if (!ok) // error already set - return recoverFromError(tokenObjectEnd); - - Token comma; - if (!readToken(comma) || - (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment)) { - return addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); - } - bool finalizeTokenOk = true; - while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); - if (comma.type_ == tokenObjectEnd) - return true; - } - return addErrorAndRecover( - "Missing '}' or object member name", tokenName, tokenObjectEnd); -} - -bool Reader::readArray(Token& tokenStart) { - Value init(arrayValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - skipSpaces(); - if (*current_ == ']') // empty array - { - Token endArray; - readToken(endArray); - return true; - } - int index = 0; - for (;;) { - Value& value = currentValue()[index++]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); - if (!ok) // error already set - return recoverFromError(tokenArrayEnd); - - Token token; - // Accept Comment after last item in the array. - ok = readToken(token); - while (token.type_ == tokenComment && ok) { - ok = readToken(token); - } - bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); - if (!ok || badTokenType) { - return addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); - } - if (token.type_ == tokenArrayEnd) - break; - } - return true; -} - -bool Reader::decodeNumber(Token& token) { - Value decoded; - if (!decodeNumber(token, decoded)) - return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return true; -} - -bool Reader::decodeNumber(Token& token, Value& decoded) { - // Attempts to parse the number as an integer. If the number is - // larger than the maximum supported value of an integer then - // we decode the number as a double. - Location current = token.start_; - bool isNegative = *current == '-'; - if (isNegative) - ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of them. - Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(-Value::minLargestInt) - : Value::maxLargestUInt; - Value::LargestUInt threshold = maxIntegerValue / 10; - Value::LargestUInt value = 0; - while (current < token.end_) { - Char c = *current++; - if (c < '0' || c > '9') - return decodeDouble(token, decoded); - Value::UInt digit(c - '0'); - if (value >= threshold) { - // We've hit or exceeded the max value divided by 10 (rounded down). If - // a) we've only just touched the limit, b) this is the last digit, and - // c) it's small enough to fit in that rounding delta, we're okay. - // Otherwise treat this number as a double to avoid overflow. - if (value > threshold || current != token.end_ || - digit > maxIntegerValue % 10) { - return decodeDouble(token, decoded); - } - } - value = value * 10 + digit; - } - if (isNegative) - decoded = -Value::LargestInt(value); - else if (value <= Value::LargestUInt(Value::maxInt)) - decoded = Value::LargestInt(value); - else - decoded = value; - return true; -} - -bool Reader::decodeDouble(Token& token) { - Value decoded; - if (!decodeDouble(token, decoded)) - return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return true; -} - -bool Reader::decodeDouble(Token& token, Value& decoded) { - double value = 0; - std::string buffer(token.start_, token.end_); - std::istringstream is(buffer); - if (!(is >> value)) - return addError("'" + std::string(token.start_, token.end_) + - "' is not a number.", - token); - decoded = value; - return true; -} - -bool Reader::decodeString(Token& token) { - std::string decoded_string; - if (!decodeString(token, decoded_string)) - return false; - Value decoded(decoded_string); - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return true; -} - -bool Reader::decodeString(Token& token, std::string& decoded) { - decoded.reserve(token.end_ - token.start_ - 2); - Location current = token.start_ + 1; // skip '"' - Location end = token.end_ - 1; // do not include '"' - while (current != end) { - Char c = *current++; - if (c == '"') - break; - else if (c == '\\') { - if (current == end) - return addError("Empty escape sequence in string", token, current); - Char escape = *current++; - switch (escape) { - case '"': - decoded += '"'; - break; - case '/': - decoded += '/'; - break; - case '\\': - decoded += '\\'; - break; - case 'b': - decoded += '\b'; - break; - case 'f': - decoded += '\f'; - break; - case 'n': - decoded += '\n'; - break; - case 'r': - decoded += '\r'; - break; - case 't': - decoded += '\t'; - break; - case 'u': { - unsigned int unicode; - if (!decodeUnicodeCodePoint(token, current, end, unicode)) - return false; - decoded += codePointToUTF8(unicode); - } break; - default: - return addError("Bad escape sequence in string", token, current); - } - } else { - decoded += c; - } - } - return true; -} - -bool Reader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { - - if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) - return false; - if (unicode >= 0xD800 && unicode <= 0xDBFF) { - // surrogate pairs - if (end - current < 6) - return addError( - "additional six characters expected to parse unicode surrogate pair.", - token, - current); - unsigned int surrogatePair; - if (*(current++) == '\\' && *(current++) == 'u') { - if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { - unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); - } else - return false; - } else - return addError("expecting another \\u token to begin the second half of " - "a unicode surrogate pair", - token, - current); - } - return true; -} - -bool Reader::decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode) { - if (end - current < 4) - return addError( - "Bad unicode escape sequence in string: four digits expected.", - token, - current); - unicode = 0; - for (int index = 0; index < 4; ++index) { - Char c = *current++; - unicode *= 16; - if (c >= '0' && c <= '9') - unicode += c - '0'; - else if (c >= 'a' && c <= 'f') - unicode += c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - unicode += c - 'A' + 10; - else - return addError( - "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, - current); - } - return true; -} - -bool -Reader::addError(const std::string& message, Token& token, Location extra) { - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = extra; - errors_.push_back(info); - return false; -} - -bool Reader::recoverFromError(TokenType skipUntilToken) { - int errorCount = int(errors_.size()); - Token skip; - for (;;) { - if (!readToken(skip)) - errors_.resize(errorCount); // discard errors caused by recovery - if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) - break; - } - errors_.resize(errorCount); - return false; -} - -bool Reader::addErrorAndRecover(const std::string& message, - Token& token, - TokenType skipUntilToken) { - addError(message, token); - return recoverFromError(skipUntilToken); -} - -Value& Reader::currentValue() { return *(nodes_.top()); } - -Reader::Char Reader::getNextChar() { - if (current_ == end_) - return 0; - return *current_++; -} - -void Reader::getLocationLineAndColumn(Location location, - int& line, - int& column) const { - Location current = begin_; - Location lastLineStart = current; - line = 0; - while (current < location && current != end_) { - Char c = *current++; - if (c == '\r') { - if (*current == '\n') - ++current; - lastLineStart = current; - ++line; - } else if (c == '\n') { - lastLineStart = current; - ++line; - } - } - // column & line start at 1 - column = int(location - lastLineStart) + 1; - ++line; -} - -std::string Reader::getLocationLineAndColumn(Location location) const { - int line, column; - getLocationLineAndColumn(location, line, column); - char buffer[18 + 16 + 16 + 1]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) -#if defined(WINCE) - _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); -#else - sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); -#endif -#else - snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); -#endif - return buffer; -} - -// Deprecated. Preserved for backward compatibility -std::string Reader::getFormatedErrorMessages() const { - return getFormattedErrorMessages(); -} - -std::string Reader::getFormattedErrorMessages() const { - std::string formattedMessage; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { - const ErrorInfo& error = *itError; - formattedMessage += - "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; - formattedMessage += " " + error.message_ + "\n"; - if (error.extra_) - formattedMessage += - "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; - } - return formattedMessage; -} - -std::vector<Reader::StructuredError> Reader::getStructuredErrors() const { - std::vector<Reader::StructuredError> allErrors; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { - const ErrorInfo& error = *itError; - Reader::StructuredError structured; - structured.offset_start = error.token_.start_ - begin_; - structured.offset_limit = error.token_.end_ - begin_; - structured.message = error.message_; - allErrors.push_back(structured); - } - return allErrors; -} - -bool Reader::pushError(const Value& value, const std::string& message) { - size_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length) - return false; - Token token; - token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = end_ + value.getOffsetLimit(); - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = 0; - errors_.push_back(info); - return true; -} - -bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) { - size_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length - || extra.getOffsetLimit() > length) - return false; - Token token; - token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = begin_ + value.getOffsetLimit(); - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = begin_ + extra.getOffsetStart(); - errors_.push_back(info); - return true; -} - -bool Reader::good() const { - return !errors_.size(); -} - -// exact copy of Features -class OurFeatures { -public: - static OurFeatures all(); - OurFeatures(); - bool allowComments_; - bool strictRoot_; - bool allowDroppedNullPlaceholders_; - bool allowNumericKeys_; - bool allowSingleQuotes_; - bool failIfExtra_; - bool rejectDupKeys_; - int stackLimit_; -}; // OurFeatures - -// exact copy of Implementation of class Features -// //////////////////////////////// - -OurFeatures::OurFeatures() - : allowComments_(true), strictRoot_(false) - , allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) - , allowSingleQuotes_(false) - , failIfExtra_(false) -{ -} - -OurFeatures OurFeatures::all() { return OurFeatures(); } - -// Implementation of class Reader -// //////////////////////////////// - -// exact copy of Reader, renamed to OurReader -class OurReader { -public: - typedef char Char; - typedef const Char* Location; - struct StructuredError { - size_t offset_start; - size_t offset_limit; - std::string message; - }; - - OurReader(OurFeatures const& features); - bool parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments = true); - std::string getFormattedErrorMessages() const; - std::vector<StructuredError> getStructuredErrors() const; - bool pushError(const Value& value, const std::string& message); - bool pushError(const Value& value, const std::string& message, const Value& extra); - bool good() const; - -private: - OurReader(OurReader const&); // no impl - void operator=(OurReader const&); // no impl - - enum TokenType { - tokenEndOfStream = 0, - tokenObjectBegin, - tokenObjectEnd, - tokenArrayBegin, - tokenArrayEnd, - tokenString, - tokenNumber, - tokenTrue, - tokenFalse, - tokenNull, - tokenArraySeparator, - tokenMemberSeparator, - tokenComment, - tokenError - }; - - class Token { - public: - TokenType type_; - Location start_; - Location end_; - }; - - class ErrorInfo { - public: - Token token_; - std::string message_; - Location extra_; - }; - - typedef std::deque<ErrorInfo> Errors; - - bool readToken(Token& token); - void skipSpaces(); - bool match(Location pattern, int patternLength); - bool readComment(); - bool readCStyleComment(); - bool readCppStyleComment(); - bool readString(); - bool readStringSingleQuote(); - void readNumber(); - bool readValue(); - bool readObject(Token& token); - bool readArray(Token& token); - bool decodeNumber(Token& token); - bool decodeNumber(Token& token, Value& decoded); - bool decodeString(Token& token); - bool decodeString(Token& token, std::string& decoded); - bool decodeDouble(Token& token); - bool decodeDouble(Token& token, Value& decoded); - bool decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode); - bool addError(const std::string& message, Token& token, Location extra = 0); - bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const std::string& message, - Token& token, - TokenType skipUntilToken); - void skipUntilSpace(); - Value& currentValue(); - Char getNextChar(); - void - getLocationLineAndColumn(Location location, int& line, int& column) const; - std::string getLocationLineAndColumn(Location location) const; - void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); - - typedef std::stack<Value*> Nodes; - Nodes nodes_; - Errors errors_; - std::string document_; - Location begin_; - Location end_; - Location current_; - Location lastValueEnd_; - Value* lastValue_; - std::string commentsBefore_; - int stackDepth_; - - OurFeatures const features_; - bool collectComments_; -}; // OurReader - -// complete copy of Read impl, for OurReader - -OurReader::OurReader(OurFeatures const& features) - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(features), collectComments_() { -} - -bool OurReader::parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments) { - if (!features_.allowComments_) { - collectComments = false; - } - - begin_ = beginDoc; - end_ = endDoc; - collectComments_ = collectComments; - current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; - commentsBefore_ = ""; - errors_.clear(); - while (!nodes_.empty()) - nodes_.pop(); - nodes_.push(&root); - - stackDepth_ = 0; - bool successful = readValue(); - Token token; - skipCommentTokens(token); - if (features_.failIfExtra_) { - if (token.type_ != tokenError && token.type_ != tokenEndOfStream) { - addError("Extra non-whitespace after JSON value.", token); - return false; - } - } - if (collectComments_ && !commentsBefore_.empty()) - root.setComment(commentsBefore_, commentAfter); - if (features_.strictRoot_) { - if (!root.isArray() && !root.isObject()) { - // Set error location to start of doc, ideally should be first token found - // in doc - token.type_ = tokenError; - token.start_ = beginDoc; - token.end_ = endDoc; - addError( - "A valid JSON document must be either an array or an object value.", - token); - return false; - } - } - return successful; -} - -bool OurReader::readValue() { - if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); - ++stackDepth_; - Token token; - skipCommentTokens(token); - bool successful = true; - - if (collectComments_ && !commentsBefore_.empty()) { - currentValue().setComment(commentsBefore_, commentBefore); - commentsBefore_ = ""; - } - - switch (token.type_) { - case tokenObjectBegin: - successful = readObject(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenArrayBegin: - successful = readArray(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenNumber: - successful = decodeNumber(token); - break; - case tokenString: - successful = decodeString(token); - break; - case tokenTrue: - { - Value v(true); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenFalse: - { - Value v(false); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNull: - { - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenArraySeparator: - case tokenObjectEnd: - case tokenArrayEnd: - if (features_.allowDroppedNullPlaceholders_) { - // "Un-read" the current token and mark the current value as a null - // token. - current_--; - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(current_ - begin_ - 1); - currentValue().setOffsetLimit(current_ - begin_); - break; - } // else, fall through ... - default: - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return addError("Syntax error: value, object or array expected.", token); - } - - if (collectComments_) { - lastValueEnd_ = current_; - lastValue_ = ¤tValue(); - } - - --stackDepth_; - return successful; -} - -void OurReader::skipCommentTokens(Token& token) { - if (features_.allowComments_) { - do { - readToken(token); - } while (token.type_ == tokenComment); - } else { - readToken(token); - } -} - -bool OurReader::readToken(Token& token) { - skipSpaces(); - token.start_ = current_; - Char c = getNextChar(); - bool ok = true; - switch (c) { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = readString(); - break; - case '\'': - if (features_.allowSingleQuotes_) { - token.type_ = tokenString; - ok = readStringSingleQuote(); - break; - } // else continue - case '/': - token.type_ = tokenComment; - ok = readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - token.type_ = tokenNumber; - readNumber(); - break; - case 't': - token.type_ = tokenTrue; - ok = match("rue", 3); - break; - case 'f': - token.type_ = tokenFalse; - ok = match("alse", 4); - break; - case 'n': - token.type_ = tokenNull; - ok = match("ull", 3); - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: - ok = false; - break; - } - if (!ok) - token.type_ = tokenError; - token.end_ = current_; - return true; -} - -void OurReader::skipSpaces() { - while (current_ != end_) { - Char c = *current_; - if (c == ' ' || c == '\t' || c == '\r' || c == '\n') - ++current_; - else - break; - } -} - -bool OurReader::match(Location pattern, int patternLength) { - if (end_ - current_ < patternLength) - return false; - int index = patternLength; - while (index--) - if (current_[index] != pattern[index]) - return false; - current_ += patternLength; - return true; -} - -bool OurReader::readComment() { - Location commentBegin = current_ - 1; - Char c = getNextChar(); - bool successful = false; - if (c == '*') - successful = readCStyleComment(); - else if (c == '/') - successful = readCppStyleComment(); - if (!successful) - return false; - - if (collectComments_) { - CommentPlacement placement = commentBefore; - if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, current_)) - placement = commentAfterOnSameLine; - } - - addComment(commentBegin, current_, placement); - } - return true; -} - -void -OurReader::addComment(Location begin, Location end, CommentPlacement placement) { - assert(collectComments_); - const std::string& normalized = normalizeEOL(begin, end); - if (placement == commentAfterOnSameLine) { - assert(lastValue_ != 0); - lastValue_->setComment(normalized, placement); - } else { - commentsBefore_ += normalized; - } -} - -bool OurReader::readCStyleComment() { - while (current_ != end_) { - Char c = getNextChar(); - if (c == '*' && *current_ == '/') - break; - } - return getNextChar() == '/'; -} - -bool OurReader::readCppStyleComment() { - while (current_ != end_) { - Char c = getNextChar(); - if (c == '\n') - break; - if (c == '\r') { - // Consume DOS EOL. It will be normalized in addComment. - if (current_ != end_ && *current_ == '\n') - getNextChar(); - // Break on Moc OS 9 EOL. - break; - } - } - return true; -} - -void OurReader::readNumber() { - const char *p = current_; - char c = '0'; // stopgap for already consumed character - // integral part - while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : 0; - // fractional part - if (c == '.') { - c = (current_ = p) < end_ ? *p++ : 0; - while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : 0; - } - // exponential part - if (c == 'e' || c == 'E') { - c = (current_ = p) < end_ ? *p++ : 0; - if (c == '+' || c == '-') - c = (current_ = p) < end_ ? *p++ : 0; - while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : 0; - } -} -bool OurReader::readString() { - Char c = 0; - while (current_ != end_) { - c = getNextChar(); - if (c == '\\') - getNextChar(); - else if (c == '"') - break; - } - return c == '"'; -} - - -bool OurReader::readStringSingleQuote() { - Char c = 0; - while (current_ != end_) { - c = getNextChar(); - if (c == '\\') - getNextChar(); - else if (c == '\'') - break; - } - return c == '\''; -} - -bool OurReader::readObject(Token& tokenStart) { - Token tokenName; - std::string name; - Value init(objectValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - while (readToken(tokenName)) { - bool initialTokenOk = true; - while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); - if (!initialTokenOk) - break; - if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object - return true; - name = ""; - if (tokenName.type_ == tokenString) { - if (!decodeString(tokenName, name)) - return recoverFromError(tokenObjectEnd); - } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { - Value numberName; - if (!decodeNumber(tokenName, numberName)) - return recoverFromError(tokenObjectEnd); - name = numberName.asString(); - } else { - break; - } - - Token colon; - if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover( - "Missing ':' after object member name", colon, tokenObjectEnd); - } - if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); - if (features_.rejectDupKeys_ && currentValue().isMember(name)) { - std::string msg = "Duplicate key: '" + name + "'"; - return addErrorAndRecover( - msg, tokenName, tokenObjectEnd); - } - Value& value = currentValue()[name]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); - if (!ok) // error already set - return recoverFromError(tokenObjectEnd); - - Token comma; - if (!readToken(comma) || - (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment)) { - return addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); - } - bool finalizeTokenOk = true; - while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); - if (comma.type_ == tokenObjectEnd) - return true; - } - return addErrorAndRecover( - "Missing '}' or object member name", tokenName, tokenObjectEnd); -} - -bool OurReader::readArray(Token& tokenStart) { - Value init(arrayValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - skipSpaces(); - if (*current_ == ']') // empty array - { - Token endArray; - readToken(endArray); - return true; - } - int index = 0; - for (;;) { - Value& value = currentValue()[index++]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); - if (!ok) // error already set - return recoverFromError(tokenArrayEnd); - - Token token; - // Accept Comment after last item in the array. - ok = readToken(token); - while (token.type_ == tokenComment && ok) { - ok = readToken(token); - } - bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); - if (!ok || badTokenType) { - return addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); - } - if (token.type_ == tokenArrayEnd) - break; - } - return true; -} - -bool OurReader::decodeNumber(Token& token) { - Value decoded; - if (!decodeNumber(token, decoded)) - return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return true; -} - -bool OurReader::decodeNumber(Token& token, Value& decoded) { - // Attempts to parse the number as an integer. If the number is - // larger than the maximum supported value of an integer then - // we decode the number as a double. - Location current = token.start_; - bool isNegative = *current == '-'; - if (isNegative) - ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of them. - Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(-Value::minLargestInt) - : Value::maxLargestUInt; - Value::LargestUInt threshold = maxIntegerValue / 10; - Value::LargestUInt value = 0; - while (current < token.end_) { - Char c = *current++; - if (c < '0' || c > '9') - return decodeDouble(token, decoded); - Value::UInt digit(c - '0'); - if (value >= threshold) { - // We've hit or exceeded the max value divided by 10 (rounded down). If - // a) we've only just touched the limit, b) this is the last digit, and - // c) it's small enough to fit in that rounding delta, we're okay. - // Otherwise treat this number as a double to avoid overflow. - if (value > threshold || current != token.end_ || - digit > maxIntegerValue % 10) { - return decodeDouble(token, decoded); - } - } - value = value * 10 + digit; - } - if (isNegative) - decoded = -Value::LargestInt(value); - else if (value <= Value::LargestUInt(Value::maxInt)) - decoded = Value::LargestInt(value); - else - decoded = value; - return true; -} - -bool OurReader::decodeDouble(Token& token) { - Value decoded; - if (!decodeDouble(token, decoded)) - return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return true; -} - -bool OurReader::decodeDouble(Token& token, Value& decoded) { - double value = 0; - const int bufferSize = 32; - int count; - int length = int(token.end_ - token.start_); - - // Sanity check to avoid buffer overflow exploits. - if (length < 0) { - return addError("Unable to parse token length", token); - } - - // Avoid using a string constant for the format control string given to - // sscanf, as this can cause hard to debug crashes on OS X. See here for more - // info: - // - // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html - char format[] = "%lf"; - - if (length <= bufferSize) { - Char buffer[bufferSize + 1]; - memcpy(buffer, token.start_, length); - buffer[length] = 0; - count = sscanf(buffer, format, &value); - } else { - std::string buffer(token.start_, token.end_); - count = sscanf(buffer.c_str(), format, &value); - } - - if (count != 1) - return addError("'" + std::string(token.start_, token.end_) + - "' is not a number.", - token); - decoded = value; - return true; -} - -bool OurReader::decodeString(Token& token) { - std::string decoded_string; - if (!decodeString(token, decoded_string)) - return false; - Value decoded(decoded_string); - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return true; -} - -bool OurReader::decodeString(Token& token, std::string& decoded) { - decoded.reserve(token.end_ - token.start_ - 2); - Location current = token.start_ + 1; // skip '"' - Location end = token.end_ - 1; // do not include '"' - while (current != end) { - Char c = *current++; - if (c == '"') - break; - else if (c == '\\') { - if (current == end) - return addError("Empty escape sequence in string", token, current); - Char escape = *current++; - switch (escape) { - case '"': - decoded += '"'; - break; - case '/': - decoded += '/'; - break; - case '\\': - decoded += '\\'; - break; - case 'b': - decoded += '\b'; - break; - case 'f': - decoded += '\f'; - break; - case 'n': - decoded += '\n'; - break; - case 'r': - decoded += '\r'; - break; - case 't': - decoded += '\t'; - break; - case 'u': { - unsigned int unicode; - if (!decodeUnicodeCodePoint(token, current, end, unicode)) - return false; - decoded += codePointToUTF8(unicode); - } break; - default: - return addError("Bad escape sequence in string", token, current); - } - } else { - decoded += c; - } - } - return true; -} - -bool OurReader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { - - if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) - return false; - if (unicode >= 0xD800 && unicode <= 0xDBFF) { - // surrogate pairs - if (end - current < 6) - return addError( - "additional six characters expected to parse unicode surrogate pair.", - token, - current); - unsigned int surrogatePair; - if (*(current++) == '\\' && *(current++) == 'u') { - if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { - unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); - } else - return false; - } else - return addError("expecting another \\u token to begin the second half of " - "a unicode surrogate pair", - token, - current); - } - return true; -} - -bool OurReader::decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode) { - if (end - current < 4) - return addError( - "Bad unicode escape sequence in string: four digits expected.", - token, - current); - unicode = 0; - for (int index = 0; index < 4; ++index) { - Char c = *current++; - unicode *= 16; - if (c >= '0' && c <= '9') - unicode += c - '0'; - else if (c >= 'a' && c <= 'f') - unicode += c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - unicode += c - 'A' + 10; - else - return addError( - "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, - current); - } - return true; -} - -bool -OurReader::addError(const std::string& message, Token& token, Location extra) { - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = extra; - errors_.push_back(info); - return false; -} - -bool OurReader::recoverFromError(TokenType skipUntilToken) { - int errorCount = int(errors_.size()); - Token skip; - for (;;) { - if (!readToken(skip)) - errors_.resize(errorCount); // discard errors caused by recovery - if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) - break; - } - errors_.resize(errorCount); - return false; -} - -bool OurReader::addErrorAndRecover(const std::string& message, - Token& token, - TokenType skipUntilToken) { - addError(message, token); - return recoverFromError(skipUntilToken); -} - -Value& OurReader::currentValue() { return *(nodes_.top()); } - -OurReader::Char OurReader::getNextChar() { - if (current_ == end_) - return 0; - return *current_++; -} - -void OurReader::getLocationLineAndColumn(Location location, - int& line, - int& column) const { - Location current = begin_; - Location lastLineStart = current; - line = 0; - while (current < location && current != end_) { - Char c = *current++; - if (c == '\r') { - if (*current == '\n') - ++current; - lastLineStart = current; - ++line; - } else if (c == '\n') { - lastLineStart = current; - ++line; - } - } - // column & line start at 1 - column = int(location - lastLineStart) + 1; - ++line; -} - -std::string OurReader::getLocationLineAndColumn(Location location) const { - int line, column; - getLocationLineAndColumn(location, line, column); - char buffer[18 + 16 + 16 + 1]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) -#if defined(WINCE) - _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); -#else - sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); -#endif -#else - snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); -#endif - return buffer; -} - -std::string OurReader::getFormattedErrorMessages() const { - std::string formattedMessage; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { - const ErrorInfo& error = *itError; - formattedMessage += - "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; - formattedMessage += " " + error.message_ + "\n"; - if (error.extra_) - formattedMessage += - "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; - } - return formattedMessage; -} - -std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const { - std::vector<OurReader::StructuredError> allErrors; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { - const ErrorInfo& error = *itError; - OurReader::StructuredError structured; - structured.offset_start = error.token_.start_ - begin_; - structured.offset_limit = error.token_.end_ - begin_; - structured.message = error.message_; - allErrors.push_back(structured); - } - return allErrors; -} - -bool OurReader::pushError(const Value& value, const std::string& message) { - size_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length) - return false; - Token token; - token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = end_ + value.getOffsetLimit(); - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = 0; - errors_.push_back(info); - return true; -} - -bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) { - size_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length - || extra.getOffsetLimit() > length) - return false; - Token token; - token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = begin_ + value.getOffsetLimit(); - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = begin_ + extra.getOffsetStart(); - errors_.push_back(info); - return true; -} - -bool OurReader::good() const { - return !errors_.size(); -} - - -class OurCharReader : public CharReader { - bool const collectComments_; - OurReader reader_; -public: - OurCharReader( - bool collectComments, - OurFeatures const& features) - : collectComments_(collectComments) - , reader_(features) - {} - virtual bool parse( - char const* beginDoc, char const* endDoc, - Value* root, std::string* errs) { - bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); - if (errs) { - *errs = reader_.getFormattedErrorMessages(); - } - return ok; - } -}; - -CharReaderBuilder::CharReaderBuilder() -{ - setDefaults(&settings_); -} -CharReaderBuilder::~CharReaderBuilder() -{} -CharReader* CharReaderBuilder::newCharReader() const -{ - bool collectComments = settings_["collectComments"].asBool(); - OurFeatures features = OurFeatures::all(); - features.allowComments_ = settings_["allowComments"].asBool(); - features.strictRoot_ = settings_["strictRoot"].asBool(); - features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); - features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); - features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); - features.stackLimit_ = settings_["stackLimit"].asInt(); - features.failIfExtra_ = settings_["failIfExtra"].asBool(); - features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); - return new OurCharReader(collectComments, features); -} -static void getValidReaderKeys(std::set<std::string>* valid_keys) -{ - valid_keys->clear(); - valid_keys->insert("collectComments"); - valid_keys->insert("allowComments"); - valid_keys->insert("strictRoot"); - valid_keys->insert("allowDroppedNullPlaceholders"); - valid_keys->insert("allowNumericKeys"); - valid_keys->insert("allowSingleQuotes"); - valid_keys->insert("stackLimit"); - valid_keys->insert("failIfExtra"); - valid_keys->insert("rejectDupKeys"); -} -bool CharReaderBuilder::validate(Json::Value* invalid) const -{ - Json::Value my_invalid; - if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL - Json::Value& inv = *invalid; - std::set<std::string> valid_keys; - getValidReaderKeys(&valid_keys); - Value::Members keys = settings_.getMemberNames(); - size_t n = keys.size(); - for (size_t i = 0; i < n; ++i) { - std::string const& key = keys[i]; - if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = settings_[key]; - } - } - return 0u == inv.size(); -} -Value& CharReaderBuilder::operator[](std::string key) -{ - return settings_[key]; -} -// static -void CharReaderBuilder::strictMode(Json::Value* settings) -{ -//! [CharReaderBuilderStrictMode] - (*settings)["allowComments"] = false; - (*settings)["strictRoot"] = true; - (*settings)["allowDroppedNullPlaceholders"] = false; - (*settings)["allowNumericKeys"] = false; - (*settings)["allowSingleQuotes"] = false; - (*settings)["failIfExtra"] = true; - (*settings)["rejectDupKeys"] = true; -//! [CharReaderBuilderStrictMode] -} -// static -void CharReaderBuilder::setDefaults(Json::Value* settings) -{ -//! [CharReaderBuilderDefaults] - (*settings)["collectComments"] = true; - (*settings)["allowComments"] = true; - (*settings)["strictRoot"] = false; - (*settings)["allowDroppedNullPlaceholders"] = false; - (*settings)["allowNumericKeys"] = false; - (*settings)["allowSingleQuotes"] = false; - (*settings)["stackLimit"] = 1000; - (*settings)["failIfExtra"] = false; - (*settings)["rejectDupKeys"] = false; -//! [CharReaderBuilderDefaults] -} - -////////////////////////////////// -// global functions - -bool parseFromStream( - CharReader::Factory const& fact, std::istream& sin, - Value* root, std::string* errs) -{ - std::ostringstream ssin; - ssin << sin.rdbuf(); - std::string doc = ssin.str(); - char const* begin = doc.data(); - char const* end = begin + doc.size(); - // Note that we do not actually need a null-terminator. - CharReaderPtr const reader(fact.newCharReader()); - return reader->parse(begin, end, root, errs); -} - -std::istream& operator>>(std::istream& sin, Value& root) { - CharReaderBuilder b; - std::string errs; - bool ok = parseFromStream(b, sin, &root, &errs); - if (!ok) { - fprintf(stderr, - "Error from reader: %s", - errs.c_str()); - - throwRuntimeError("reader error"); - } - return sin; -} - -} // namespace Json diff --git a/3rdparty/jsoncpp/src/lib_json/json_tool.h b/3rdparty/jsoncpp/src/lib_json/json_tool.h deleted file mode 100644 index f9b61c38c70..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/json_tool.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// 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 - -#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED -#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED - -/* This header provides common string manipulation support, such as UTF-8, - * portable conversion from/to string... - * - * It is an internal header that must not be exposed. - */ - -namespace Json { - -/// Converts a unicode code-point to UTF-8. -static inline std::string codePointToUTF8(unsigned int cp) { - std::string result; - - // based on description from http://en.wikipedia.org/wiki/UTF-8 - - if (cp <= 0x7f) { - result.resize(1); - result[0] = static_cast<char>(cp); - } else if (cp <= 0x7FF) { - result.resize(2); - result[1] = static_cast<char>(0x80 | (0x3f & cp)); - result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6))); - } else if (cp <= 0xFFFF) { - result.resize(3); - result[2] = static_cast<char>(0x80 | (0x3f & cp)); - result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6))); - result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12))); - } else if (cp <= 0x10FFFF) { - result.resize(4); - result[3] = static_cast<char>(0x80 | (0x3f & cp)); - result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); - result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12))); - result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18))); - } - - return result; -} - -/// Returns true if ch is a control character (in range [0,32[). -static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; } - -enum { - /// Constant that specify the size of the buffer that must be passed to - /// uintToString. - uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1 -}; - -// Defines a char buffer for use with uintToString(). -typedef char UIntToStringBuffer[uintToStringBufferSize]; - -/** Converts an unsigned integer to string. - * @param value Unsigned interger to convert to string - * @param current Input/Output string buffer. - * Must have at least uintToStringBufferSize chars free. - */ -static inline void uintToString(LargestUInt value, char*& current) { - *--current = 0; - do { - *--current = char(value % 10) + '0'; - value /= 10; - } while (value != 0); -} - -/** Change ',' to '.' everywhere in buffer. - * - * We had a sophisticated way, but it did not work in WinCE. - * @see https://github.com/open-source-parsers/jsoncpp/pull/9 - */ -static inline void fixNumericLocale(char* begin, char* end) { - while (begin < end) { - if (*begin == ',') { - *begin = '.'; - } - ++begin; - } -} - -} // namespace Json { - -#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED diff --git a/3rdparty/jsoncpp/src/lib_json/json_value.cpp b/3rdparty/jsoncpp/src/lib_json/json_value.cpp deleted file mode 100644 index cc7d4d3d8ba..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/json_value.cpp +++ /dev/null @@ -1,1544 +0,0 @@ -// Copyright 2011 Baptiste Lepilleur -// 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(JSON_IS_AMALGAMATION) -#include <json/assertions.h> -#include <json/value.h> -#include <json/writer.h> -#endif // if !defined(JSON_IS_AMALGAMATION) -#include <math.h> -#include <sstream> -#include <utility> -#include <cstring> -#include <cassert> -#ifdef JSON_USE_CPPTL -#include <cpptl/conststring.h> -#endif -#include <cstddef> // size_t -#include <algorithm> // min() - -#define JSON_ASSERT_UNREACHABLE assert(false) - -namespace Json { - -// This is a walkaround to avoid the static initialization of Value::null. -// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of -// 8 (instead of 4) as a bit of future-proofing. -#if defined(__ARMEL__) -#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) -#else -#define ALIGNAS(byte_alignment) -#endif -static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; -const unsigned char& kNullRef = kNull[0]; -const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); -const Value& Value::nullRef = null; - -const Int Value::minInt = Int(~(UInt(-1) / 2)); -const Int Value::maxInt = Int(UInt(-1) / 2); -const UInt Value::maxUInt = UInt(-1); -#if defined(JSON_HAS_INT64) -const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); -const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); -const UInt64 Value::maxUInt64 = UInt64(-1); -// The constant is hard-coded because some compiler have trouble -// converting Value::maxUInt64 to a double correctly (AIX/xlC). -// Assumes that UInt64 is a 64 bits integer. -static const double maxUInt64AsDouble = 18446744073709551615.0; -#endif // defined(JSON_HAS_INT64) -const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); -const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); -const LargestUInt Value::maxLargestUInt = LargestUInt(-1); - -#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) -template <typename T, typename U> -static inline bool InRange(double d, T min, U max) { - return d >= min && d <= max; -} -#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) -static inline double integerToDouble(Json::UInt64 value) { - return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1); -} - -template <typename T> static inline double integerToDouble(T value) { - return static_cast<double>(value); -} - -template <typename T, typename U> -static inline bool InRange(double d, T min, U max) { - return d >= integerToDouble(min) && d <= integerToDouble(max); -} -#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - -/** Duplicates the specified string value. - * @param value Pointer to the string to duplicate. Must be zero-terminated if - * length is "unknown". - * @param length Length of the value. if equals to unknown, then it will be - * computed using strlen(value). - * @return Pointer on the duplicate instance of string. - */ -static inline char* duplicateStringValue(const char* value, - size_t length) { - // Avoid an integer overflow in the call to malloc below by limiting length - // to a sane value. - if (length >= (size_t)Value::maxInt) - length = Value::maxInt - 1; - - char* newString = static_cast<char*>(malloc(length + 1)); - if (newString == NULL) { - throwRuntimeError( - "in Json::Value::duplicateStringValue(): " - "Failed to allocate string value buffer"); - } - memcpy(newString, value, length); - newString[length] = 0; - return newString; -} - -/* Record the length as a prefix. - */ -static inline char* duplicateAndPrefixStringValue( - const char* value, - unsigned int length) -{ - // Avoid an integer overflow in the call to malloc below by limiting length - // to a sane value. - JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U, - "in Json::Value::duplicateAndPrefixStringValue(): " - "length too big for prefixing"); - unsigned actualLength = length + sizeof(unsigned) + 1U; - char* newString = static_cast<char*>(malloc(actualLength)); - if (newString == 0) { - throwRuntimeError( - "in Json::Value::duplicateAndPrefixStringValue(): " - "Failed to allocate string value buffer"); - } - *reinterpret_cast<unsigned*>(newString) = length; - memcpy(newString + sizeof(unsigned), value, length); - newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later - return newString; -} -inline static void decodePrefixedString( - bool isPrefixed, char const* prefixed, - unsigned* length, char const** value) -{ - if (!isPrefixed) { - *length = static_cast<unsigned>(strlen(prefixed)); - *value = prefixed; - } else { - *length = *reinterpret_cast<unsigned const*>(prefixed); - *value = prefixed + sizeof(unsigned); - } -} -/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). - */ -static inline void releaseStringValue(char* value) { free(value); } - -} // namespace Json - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ValueInternals... -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -#if !defined(JSON_IS_AMALGAMATION) - -#include "json_valueiterator.inl" -#endif // if !defined(JSON_IS_AMALGAMATION) - -namespace Json { - -class JSON_API Exception : public std::exception { -public: - Exception(std::string const& msg); - virtual ~Exception() throw(); - virtual char const* what() const throw(); -protected: - std::string const msg_; -}; -class JSON_API RuntimeError : public Exception { -public: - RuntimeError(std::string const& msg); -}; -class JSON_API LogicError : public Exception { -public: - LogicError(std::string const& msg); -}; - -Exception::Exception(std::string const& msg) - : msg_(msg) -{} -Exception::~Exception() throw() -{} -char const* Exception::what() const throw() -{ - return msg_.c_str(); -} -RuntimeError::RuntimeError(std::string const& msg) - : Exception(msg) -{} -LogicError::LogicError(std::string const& msg) - : Exception(msg) -{} -void throwRuntimeError(std::string const& msg) -{ - throw RuntimeError(msg); -} -void throwLogicError(std::string const& msg) -{ - throw LogicError(msg); -} - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::CommentInfo -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -Value::CommentInfo::CommentInfo() : comment_(0) {} - -Value::CommentInfo::~CommentInfo() { - if (comment_) - releaseStringValue(comment_); -} - -void Value::CommentInfo::setComment(const char* text, size_t len) { - if (comment_) { - releaseStringValue(comment_); - comment_ = 0; - } - JSON_ASSERT(text != 0); - JSON_ASSERT_MESSAGE( - text[0] == '\0' || text[0] == '/', - "in Json::Value::setComment(): Comments must start with /"); - // It seems that /**/ style comments are acceptable as well. - comment_ = duplicateStringValue(text, len); -} - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::CZString -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -// Notes: policy_ indicates if the string was allocated when -// a string is stored. - -Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {} - -Value::CZString::CZString(char const* str, unsigned length, DuplicationPolicy allocate) - : cstr_(str) -{ - // allocate != duplicate - storage_.policy_ = allocate; - storage_.length_ = length; -} - -Value::CZString::CZString(const CZString& other) - : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0 - ? duplicateStringValue(other.cstr_, other.storage_.length_) - : other.cstr_) -{ - storage_.policy_ = (other.cstr_ - ? (other.storage_.policy_ == noDuplication - ? noDuplication : duplicate) - : other.storage_.policy_); - storage_.length_ = other.storage_.length_; -} - -Value::CZString::~CZString() { - if (cstr_ && storage_.policy_ == duplicate) - releaseStringValue(const_cast<char*>(cstr_)); -} - -void Value::CZString::swap(CZString& other) { - std::swap(cstr_, other.cstr_); - std::swap(index_, other.index_); -} - -Value::CZString& Value::CZString::operator=(CZString other) { - swap(other); - return *this; -} - -bool Value::CZString::operator<(const CZString& other) const { - if (!cstr_) return index_ < other.index_; - //return strcmp(cstr_, other.cstr_) < 0; - // Assume both are strings. - unsigned this_len = this->storage_.length_; - unsigned other_len = other.storage_.length_; - unsigned min_len = std::min(this_len, other_len); - int comp = memcmp(this->cstr_, other.cstr_, min_len); - if (comp < 0) return true; - if (comp > 0) return false; - return (this_len < other_len); -} - -bool Value::CZString::operator==(const CZString& other) const { - if (!cstr_) return index_ == other.index_; - //return strcmp(cstr_, other.cstr_) == 0; - // Assume both are strings. - unsigned this_len = this->storage_.length_; - unsigned other_len = other.storage_.length_; - if (this_len != other_len) return false; - int comp = memcmp(this->cstr_, other.cstr_, this_len); - return comp == 0; -} - -ArrayIndex Value::CZString::index() const { return index_; } - -//const char* Value::CZString::c_str() const { return cstr_; } -const char* Value::CZString::data() const { return cstr_; } -unsigned Value::CZString::length() const { return storage_.length_; } -bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; } - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::Value -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -/*! \internal Default constructor initialization must be equivalent to: - * memset( this, 0, sizeof(Value) ) - * This optimization is used in ValueInternalMap fast allocator. - */ -Value::Value(ValueType type) { - initBasic(type); - switch (type) { - case nullValue: - break; - case intValue: - case uintValue: - value_.int_ = 0; - break; - case realValue: - value_.real_ = 0.0; - break; - case stringValue: - value_.string_ = 0; - break; - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(); - break; - case booleanValue: - value_.bool_ = false; - break; - default: - JSON_ASSERT_UNREACHABLE; - } -} - -Value::Value(Int value) { - initBasic(intValue); - value_.int_ = value; -} - -Value::Value(UInt value) { - initBasic(uintValue); - value_.uint_ = value; -} -#if defined(JSON_HAS_INT64) -Value::Value(Int64 value) { - initBasic(intValue); - value_.int_ = value; -} -Value::Value(UInt64 value) { - initBasic(uintValue); - value_.uint_ = value; -} -#endif // defined(JSON_HAS_INT64) - -Value::Value(double value) { - initBasic(realValue); - value_.real_ = value; -} - -Value::Value(const char* value) { - initBasic(stringValue, true); - value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value))); -} - -Value::Value(const char* beginValue, const char* endValue) { - initBasic(stringValue, true); - value_.string_ = - duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue)); -} - -Value::Value(const std::string& value) { - initBasic(stringValue, true); - value_.string_ = - duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length())); -} - -Value::Value(const StaticString& value) { - initBasic(stringValue); - value_.string_ = const_cast<char*>(value.c_str()); -} - -#ifdef JSON_USE_CPPTL -Value::Value(const CppTL::ConstString& value) { - initBasic(stringValue, true); - value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length())); -} -#endif - -Value::Value(bool value) { - initBasic(booleanValue); - value_.bool_ = value; -} - -Value::Value(Value const& other) - : type_(other.type_), allocated_(false) - , - comments_(0), start_(other.start_), limit_(other.limit_) -{ - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - value_ = other.value_; - break; - case stringValue: - if (other.value_.string_ && other.allocated_) { - unsigned len; - char const* str; - decodePrefixedString(other.allocated_, other.value_.string_, - &len, &str); - value_.string_ = duplicateAndPrefixStringValue(str, len); - allocated_ = true; - } else { - value_.string_ = other.value_.string_; - allocated_ = false; - } - break; - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(*other.value_.map_); - break; - default: - JSON_ASSERT_UNREACHABLE; - } - if (other.comments_) { - comments_ = new CommentInfo[numberOfCommentPlacement]; - for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { - const CommentInfo& otherComment = other.comments_[comment]; - if (otherComment.comment_) - comments_[comment].setComment( - otherComment.comment_, strlen(otherComment.comment_)); - } - } -} - -Value::~Value() { - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - break; - case stringValue: - if (allocated_) - releaseStringValue(value_.string_); - break; - case arrayValue: - case objectValue: - delete value_.map_; - break; - default: - JSON_ASSERT_UNREACHABLE; - } - - if (comments_) - delete[] comments_; -} - -Value& Value::operator=(Value other) { - swap(other); - return *this; -} - -void Value::swapPayload(Value& other) { - ValueType temp = type_; - type_ = other.type_; - other.type_ = temp; - std::swap(value_, other.value_); - int temp2 = allocated_; - allocated_ = other.allocated_; - other.allocated_ = temp2; -} - -void Value::swap(Value& other) { - swapPayload(other); - std::swap(comments_, other.comments_); - std::swap(start_, other.start_); - std::swap(limit_, other.limit_); -} - -ValueType Value::type() const { return type_; } - -int Value::compare(const Value& other) const { - if (*this < other) - return -1; - if (*this > other) - return 1; - return 0; -} - -bool Value::operator<(const Value& other) const { - int typeDelta = type_ - other.type_; - if (typeDelta) - return typeDelta < 0 ? true : false; - switch (type_) { - case nullValue: - return false; - case intValue: - return value_.int_ < other.value_.int_; - case uintValue: - return value_.uint_ < other.value_.uint_; - case realValue: - return value_.real_ < other.value_.real_; - case booleanValue: - return value_.bool_ < other.value_.bool_; - case stringValue: - { - if ((value_.string_ == 0) || (other.value_.string_ == 0)) { - if (other.value_.string_) return true; - else return false; - } - unsigned this_len; - unsigned other_len; - char const* this_str; - char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); - unsigned min_len = std::min(this_len, other_len); - int comp = memcmp(this_str, other_str, min_len); - if (comp < 0) return true; - if (comp > 0) return false; - return (this_len < other_len); - } - case arrayValue: - case objectValue: { - int delta = int(value_.map_->size() - other.value_.map_->size()); - if (delta) - return delta < 0; - return (*value_.map_) < (*other.value_.map_); - } - default: - JSON_ASSERT_UNREACHABLE; - } - return false; // unreachable -} - -bool Value::operator<=(const Value& other) const { return !(other < *this); } - -bool Value::operator>=(const Value& other) const { return !(*this < other); } - -bool Value::operator>(const Value& other) const { return other < *this; } - -bool Value::operator==(const Value& other) const { - // if ( type_ != other.type_ ) - // GCC 2.95.3 says: - // attempt to take address of bit-field structure member `Json::Value::type_' - // Beats me, but a temp solves the problem. - int temp = other.type_; - if (type_ != temp) - return false; - switch (type_) { - case nullValue: - return true; - case intValue: - return value_.int_ == other.value_.int_; - case uintValue: - return value_.uint_ == other.value_.uint_; - case realValue: - return value_.real_ == other.value_.real_; - case booleanValue: - return value_.bool_ == other.value_.bool_; - case stringValue: - { - if ((value_.string_ == 0) || (other.value_.string_ == 0)) { - return (value_.string_ == other.value_.string_); - } - unsigned this_len; - unsigned other_len; - char const* this_str; - char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); - if (this_len != other_len) return false; - int comp = memcmp(this_str, other_str, this_len); - return comp == 0; - } - case arrayValue: - case objectValue: - return value_.map_->size() == other.value_.map_->size() && - (*value_.map_) == (*other.value_.map_); - default: - JSON_ASSERT_UNREACHABLE; - } - return false; // unreachable -} - -bool Value::operator!=(const Value& other) const { return !(*this == other); } - -const char* Value::asCString() const { - JSON_ASSERT_MESSAGE(type_ == stringValue, - "in Json::Value::asCString(): requires stringValue"); - if (value_.string_ == 0) return 0; - unsigned this_len; - char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - return this_str; -} - -bool Value::getString(char const** str, char const** end) const { - if (type_ != stringValue) return false; - if (value_.string_ == 0) return false; - unsigned length; - decodePrefixedString(this->allocated_, this->value_.string_, &length, str); - *end = *str + length; - return true; -} - -std::string Value::asString() const { - switch (type_) { - case nullValue: - return ""; - case stringValue: - { - if (value_.string_ == 0) return ""; - unsigned this_len; - char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - return std::string(this_str, this_len); - } - case booleanValue: - return value_.bool_ ? "true" : "false"; - case intValue: - return valueToString(value_.int_); - case uintValue: - return valueToString(value_.uint_); - case realValue: - return valueToString(value_.real_); - default: - JSON_FAIL_MESSAGE("Type is not convertible to string"); - } -} - -#ifdef JSON_USE_CPPTL -CppTL::ConstString Value::asConstString() const { - unsigned len; - char const* str; - decodePrefixedString(allocated_, value_.string_, - &len, &str); - return CppTL::ConstString(str, len); -} -#endif - -Value::Int Value::asInt() const { - switch (type_) { - case intValue: - JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); - return Int(value_.int_); - case uintValue: - JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); - return Int(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), - "double out of Int range"); - return Int(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to Int."); -} - -Value::UInt Value::asUInt() const { - switch (type_) { - case intValue: - JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); - return UInt(value_.int_); - case uintValue: - JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); - return UInt(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), - "double out of UInt range"); - return UInt(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to UInt."); -} - -#if defined(JSON_HAS_INT64) - -Value::Int64 Value::asInt64() const { - switch (type_) { - case intValue: - return Int64(value_.int_); - case uintValue: - JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); - return Int64(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), - "double out of Int64 range"); - return Int64(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to Int64."); -} - -Value::UInt64 Value::asUInt64() const { - switch (type_) { - case intValue: - JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); - return UInt64(value_.int_); - case uintValue: - return UInt64(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), - "double out of UInt64 range"); - return UInt64(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); -} -#endif // if defined(JSON_HAS_INT64) - -LargestInt Value::asLargestInt() const { -#if defined(JSON_NO_INT64) - return asInt(); -#else - return asInt64(); -#endif -} - -LargestUInt Value::asLargestUInt() const { -#if defined(JSON_NO_INT64) - return asUInt(); -#else - return asUInt64(); -#endif -} - -double Value::asDouble() const { - switch (type_) { - case intValue: - return static_cast<double>(value_.int_); - case uintValue: -#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return static_cast<double>(value_.uint_); -#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return integerToDouble(value_.uint_); -#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - case realValue: - return value_.real_; - case nullValue: - return 0.0; - case booleanValue: - return value_.bool_ ? 1.0 : 0.0; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to double."); -} - -float Value::asFloat() const { - switch (type_) { - case intValue: - return static_cast<float>(value_.int_); - case uintValue: -#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return static_cast<float>(value_.uint_); -#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return integerToDouble(value_.uint_); -#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - case realValue: - return static_cast<float>(value_.real_); - case nullValue: - return 0.0; - case booleanValue: - return value_.bool_ ? 1.0f : 0.0f; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to float."); -} - -bool Value::asBool() const { - switch (type_) { - case booleanValue: - return value_.bool_; - case nullValue: - return false; - case intValue: - return value_.int_ ? true : false; - case uintValue: - return value_.uint_ ? true : false; - case realValue: - return value_.real_ ? true : false; - default: - break; - } - JSON_FAIL_MESSAGE("Value is not convertible to bool."); -} - -bool Value::isConvertibleTo(ValueType other) const { - switch (other) { - case nullValue: - return (isNumeric() && asDouble() == 0.0) || - (type_ == booleanValue && value_.bool_ == false) || - (type_ == stringValue && asString() == "") || - (type_ == arrayValue && value_.map_->size() == 0) || - (type_ == objectValue && value_.map_->size() == 0) || - type_ == nullValue; - case intValue: - return isInt() || - (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || - type_ == booleanValue || type_ == nullValue; - case uintValue: - return isUInt() || - (type_ == realValue && InRange(value_.real_, 0, maxUInt)) || - type_ == booleanValue || type_ == nullValue; - case realValue: - return isNumeric() || type_ == booleanValue || type_ == nullValue; - case booleanValue: - return isNumeric() || type_ == booleanValue || type_ == nullValue; - case stringValue: - return isNumeric() || type_ == booleanValue || type_ == stringValue || - type_ == nullValue; - case arrayValue: - return type_ == arrayValue || type_ == nullValue; - case objectValue: - return type_ == objectValue || type_ == nullValue; - } - JSON_ASSERT_UNREACHABLE; - return false; -} - -/// Number of values in array or object -ArrayIndex Value::size() const { - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - case stringValue: - return 0; - case arrayValue: // size of the array is highest index + 1 - if (!value_.map_->empty()) { - ObjectValues::const_iterator itLast = value_.map_->end(); - --itLast; - return (*itLast).first.index() + 1; - } - return 0; - case objectValue: - return ArrayIndex(value_.map_->size()); - } - JSON_ASSERT_UNREACHABLE; - return 0; // unreachable; -} - -bool Value::empty() const { - if (isNull() || isArray() || isObject()) - return size() == 0u; - else - return false; -} - -bool Value::operator!() const { return isNull(); } - -void Value::clear() { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || - type_ == objectValue, - "in Json::Value::clear(): requires complex value"); - start_ = 0; - limit_ = 0; - switch (type_) { - case arrayValue: - case objectValue: - value_.map_->clear(); - break; - default: - break; - } -} - -void Value::resize(ArrayIndex newSize) { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue, - "in Json::Value::resize(): requires arrayValue"); - if (type_ == nullValue) - *this = Value(arrayValue); - ArrayIndex oldSize = size(); - if (newSize == 0) - clear(); - else if (newSize > oldSize) - (*this)[newSize - 1]; - else { - for (ArrayIndex index = newSize; index < oldSize; ++index) { - value_.map_->erase(index); - } - assert(size() == newSize); - } -} - -Value& Value::operator[](ArrayIndex index) { - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == arrayValue, - "in Json::Value::operator[](ArrayIndex): requires arrayValue"); - if (type_ == nullValue) - *this = Value(arrayValue); - CZString key(index); - ObjectValues::iterator it = value_.map_->lower_bound(key); - if (it != value_.map_->end() && (*it).first == key) - return (*it).second; - - ObjectValues::value_type defaultValue(key, nullRef); - it = value_.map_->insert(it, defaultValue); - return (*it).second; -} - -Value& Value::operator[](int index) { - JSON_ASSERT_MESSAGE( - index >= 0, - "in Json::Value::operator[](int index): index cannot be negative"); - return (*this)[ArrayIndex(index)]; -} - -const Value& Value::operator[](ArrayIndex index) const { - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == arrayValue, - "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); - if (type_ == nullValue) - return nullRef; - CZString key(index); - ObjectValues::const_iterator it = value_.map_->find(key); - if (it == value_.map_->end()) - return nullRef; - return (*it).second; -} - -const Value& Value::operator[](int index) const { - JSON_ASSERT_MESSAGE( - index >= 0, - "in Json::Value::operator[](int index) const: index cannot be negative"); - return (*this)[ArrayIndex(index)]; -} - -void Value::initBasic(ValueType type, bool allocated) { - type_ = type; - allocated_ = allocated; - comments_ = 0; - start_ = 0; - limit_ = 0; -} - -// Access an object value by name, create a null member if it does not exist. -// @pre Type of '*this' is object or null. -// @param key is null-terminated. -Value& Value::resolveReference(const char* key) { - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::resolveReference(): requires objectValue"); - if (type_ == nullValue) - *this = Value(objectValue); - CZString actualKey( - key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE! - ObjectValues::iterator it = value_.map_->lower_bound(actualKey); - if (it != value_.map_->end() && (*it).first == actualKey) - return (*it).second; - - ObjectValues::value_type defaultValue(actualKey, nullRef); - it = value_.map_->insert(it, defaultValue); - Value& value = (*it).second; - return value; -} - -// @param key is not null-terminated. -Value& Value::resolveReference(char const* key, char const* end) -{ - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::resolveReference(key, end): requires objectValue"); - if (type_ == nullValue) - *this = Value(objectValue); - CZString actualKey( - key, static_cast<unsigned>(end-key), CZString::duplicateOnCopy); - ObjectValues::iterator it = value_.map_->lower_bound(actualKey); - if (it != value_.map_->end() && (*it).first == actualKey) - return (*it).second; - - ObjectValues::value_type defaultValue(actualKey, nullRef); - it = value_.map_->insert(it, defaultValue); - Value& value = (*it).second; - return value; -} - -Value Value::get(ArrayIndex index, const Value& defaultValue) const { - const Value* value = &((*this)[index]); - return value == &nullRef ? defaultValue : *value; -} - -bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } - -Value const* Value::find(char const* key, char const* end) const -{ - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::find(key, end, found): requires objectValue or nullValue"); - if (type_ == nullValue) return NULL; - CZString actualKey(key, static_cast<unsigned>(end-key), CZString::noDuplication); - ObjectValues::const_iterator it = value_.map_->find(actualKey); - if (it == value_.map_->end()) return NULL; - return &(*it).second; -} -const Value& Value::operator[](const char* key) const -{ - Value const* found = find(key, key + strlen(key)); - if (!found) return nullRef; - return *found; -} -Value const& Value::operator[](std::string const& key) const -{ - Value const* found = find(key.data(), key.data() + key.length()); - if (!found) return nullRef; - return *found; -} - -Value& Value::operator[](const char* key) { - return resolveReference(key, key + strlen(key)); -} - -Value& Value::operator[](const std::string& key) { - return resolveReference(key.data(), key.data() + key.length()); -} - -Value& Value::operator[](const StaticString& key) { - return resolveReference(key.c_str()); -} - -#ifdef JSON_USE_CPPTL -Value& Value::operator[](const CppTL::ConstString& key) { - return resolveReference(key.c_str(), key.end_c_str()); -} -Value const& Value::operator[](CppTL::ConstString const& key) const -{ - Value const* found = find(key.c_str(), key.end_c_str()); - if (!found) return nullRef; - return *found; -} -#endif - -Value& Value::append(const Value& value) { return (*this)[size()] = value; } - -Value Value::get(char const* key, char const* end, Value const& defaultValue) const -{ - Value const* found = find(key, end); - return !found ? defaultValue : *found; -} -Value Value::get(char const* key, Value const& defaultValue) const -{ - return get(key, key + strlen(key), defaultValue); -} -Value Value::get(std::string const& key, Value const& defaultValue) const -{ - return get(key.data(), key.data() + key.length(), defaultValue); -} - - -bool Value::removeMember(const char* key, const char* end, Value* removed) -{ - if (type_ != objectValue) { - return false; - } - CZString actualKey(key, static_cast<unsigned>(end-key), CZString::noDuplication); - ObjectValues::iterator it = value_.map_->find(actualKey); - if (it == value_.map_->end()) - return false; - *removed = it->second; - value_.map_->erase(it); - return true; -} -bool Value::removeMember(const char* key, Value* removed) -{ - return removeMember(key, key + strlen(key), removed); -} -bool Value::removeMember(std::string const& key, Value* removed) -{ - return removeMember(key.data(), key.data() + key.length(), removed); -} -Value Value::removeMember(const char* key) -{ - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, - "in Json::Value::removeMember(): requires objectValue"); - if (type_ == nullValue) - return nullRef; - - Value removed; // null - removeMember(key, key + strlen(key), &removed); - return removed; // still null if removeMember() did nothing -} -Value Value::removeMember(const std::string& key) -{ - return removeMember(key.c_str()); -} - -bool Value::removeIndex(ArrayIndex index, Value* removed) { - if (type_ != arrayValue) { - return false; - } - CZString key(index); - ObjectValues::iterator it = value_.map_->find(key); - if (it == value_.map_->end()) { - return false; - } - *removed = it->second; - ArrayIndex oldSize = size(); - // shift left all items left, into the place of the "removed" - for (ArrayIndex i = index; i < (oldSize - 1); ++i){ - CZString key(i); - (*value_.map_)[key] = (*this)[i + 1]; - } - // erase the last one ("leftover") - CZString keyLast(oldSize - 1); - ObjectValues::iterator itLast = value_.map_->find(keyLast); - value_.map_->erase(itLast); - return true; -} - -#ifdef JSON_USE_CPPTL -Value Value::get(const CppTL::ConstString& key, - const Value& defaultValue) const { - return get(key.c_str(), key.end_c_str(), defaultValue); -} -#endif - -bool Value::isMember(char const* key, char const* end) const -{ - Value const* value = find(key, end); - return NULL != value; -} -bool Value::isMember(char const* key) const -{ - return isMember(key, key + strlen(key)); -} -bool Value::isMember(std::string const& key) const -{ - return isMember(key.data(), key.data() + key.length()); -} - -#ifdef JSON_USE_CPPTL -bool Value::isMember(const CppTL::ConstString& key) const { - return isMember(key.c_str(), key.end_c_str()); -} -#endif - -Value::Members Value::getMemberNames() const { - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::getMemberNames(), value must be objectValue"); - if (type_ == nullValue) - return Value::Members(); - Members members; - members.reserve(value_.map_->size()); - ObjectValues::const_iterator it = value_.map_->begin(); - ObjectValues::const_iterator itEnd = value_.map_->end(); - for (; it != itEnd; ++it) { - members.push_back(std::string((*it).first.data(), - (*it).first.length())); - } - return members; -} -// -//# ifdef JSON_USE_CPPTL -// EnumMemberNames -// Value::enumMemberNames() const -//{ -// if ( type_ == objectValue ) -// { -// return CppTL::Enum::any( CppTL::Enum::transform( -// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), -// MemberNamesTransform() ) ); -// } -// return EnumMemberNames(); -//} -// -// -// EnumValues -// Value::enumValues() const -//{ -// if ( type_ == objectValue || type_ == arrayValue ) -// return CppTL::Enum::anyValues( *(value_.map_), -// CppTL::Type<const Value &>() ); -// return EnumValues(); -//} -// -//# endif - -static bool IsIntegral(double d) { - double integral_part; - return modf(d, &integral_part) == 0.0; -} - -bool Value::isNull() const { return type_ == nullValue; } - -bool Value::isBool() const { return type_ == booleanValue; } - -bool Value::isInt() const { - switch (type_) { - case intValue: - return value_.int_ >= minInt && value_.int_ <= maxInt; - case uintValue: - return value_.uint_ <= UInt(maxInt); - case realValue: - return value_.real_ >= minInt && value_.real_ <= maxInt && - IsIntegral(value_.real_); - default: - break; - } - return false; -} - -bool Value::isUInt() const { - switch (type_) { - case intValue: - return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); - case uintValue: - return value_.uint_ <= maxUInt; - case realValue: - return value_.real_ >= 0 && value_.real_ <= maxUInt && - IsIntegral(value_.real_); - default: - break; - } - return false; -} - -bool Value::isInt64() const { -#if defined(JSON_HAS_INT64) - switch (type_) { - case intValue: - return true; - case uintValue: - return value_.uint_ <= UInt64(maxInt64); - case realValue: - // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a - // double, so double(maxInt64) will be rounded up to 2^63. Therefore we - // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && - value_.real_ < double(maxInt64) && IsIntegral(value_.real_); - default: - break; - } -#endif // JSON_HAS_INT64 - return false; -} - -bool Value::isUInt64() const { -#if defined(JSON_HAS_INT64) - switch (type_) { - case intValue: - return value_.int_ >= 0; - case uintValue: - return true; - case realValue: - // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a - // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we - // require the value to be strictly less than the limit. - return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble && - IsIntegral(value_.real_); - default: - break; - } -#endif // JSON_HAS_INT64 - return false; -} - -bool Value::isIntegral() const { -#if defined(JSON_HAS_INT64) - return isInt64() || isUInt64(); -#else - return isInt() || isUInt(); -#endif -} - -bool Value::isDouble() const { return type_ == realValue || isIntegral(); } - -bool Value::isNumeric() const { return isIntegral() || isDouble(); } - -bool Value::isString() const { return type_ == stringValue; } - -bool Value::isArray() const { return type_ == arrayValue; } - -bool Value::isObject() const { return type_ == objectValue; } - -void Value::setComment(const char* comment, size_t len, CommentPlacement placement) { - if (!comments_) - comments_ = new CommentInfo[numberOfCommentPlacement]; - if ((len > 0) && (comment[len-1] == '\n')) { - // Always discard trailing newline, to aid indentation. - len -= 1; - } - comments_[placement].setComment(comment, len); -} - -void Value::setComment(const char* comment, CommentPlacement placement) { - setComment(comment, strlen(comment), placement); -} - -void Value::setComment(const std::string& comment, CommentPlacement placement) { - setComment(comment.c_str(), comment.length(), placement); -} - -bool Value::hasComment(CommentPlacement placement) const { - return comments_ != 0 && comments_[placement].comment_ != 0; -} - -std::string Value::getComment(CommentPlacement placement) const { - if (hasComment(placement)) - return comments_[placement].comment_; - return ""; -} - -void Value::setOffsetStart(size_t start) { start_ = start; } - -void Value::setOffsetLimit(size_t limit) { limit_ = limit; } - -size_t Value::getOffsetStart() const { return start_; } - -size_t Value::getOffsetLimit() const { return limit_; } - -std::string Value::toStyledString() const { - StyledWriter writer; - return writer.write(*this); -} - -Value::const_iterator Value::begin() const { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return const_iterator(value_.map_->begin()); - break; - default: - break; - } - return const_iterator(); -} - -Value::const_iterator Value::end() const { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return const_iterator(value_.map_->end()); - break; - default: - break; - } - return const_iterator(); -} - -Value::iterator Value::begin() { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return iterator(value_.map_->begin()); - break; - default: - break; - } - return iterator(); -} - -Value::iterator Value::end() { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return iterator(value_.map_->end()); - break; - default: - break; - } - return iterator(); -} - -// class PathArgument -// ////////////////////////////////////////////////////////////////// - -PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {} - -PathArgument::PathArgument(ArrayIndex index) - : key_(), index_(index), kind_(kindIndex) {} - -PathArgument::PathArgument(const char* key) - : key_(key), index_(), kind_(kindKey) {} - -PathArgument::PathArgument(const std::string& key) - : key_(key.c_str()), index_(), kind_(kindKey) {} - -// class Path -// ////////////////////////////////////////////////////////////////// - -Path::Path(const std::string& path, - const PathArgument& a1, - const PathArgument& a2, - const PathArgument& a3, - const PathArgument& a4, - const PathArgument& a5) { - InArgs in; - in.push_back(&a1); - in.push_back(&a2); - in.push_back(&a3); - in.push_back(&a4); - in.push_back(&a5); - makePath(path, in); -} - -void Path::makePath(const std::string& path, const InArgs& in) { - const char* current = path.c_str(); - const char* end = current + path.length(); - InArgs::const_iterator itInArg = in.begin(); - while (current != end) { - if (*current == '[') { - ++current; - if (*current == '%') - addPathInArg(path, in, itInArg, PathArgument::kindIndex); - else { - ArrayIndex index = 0; - for (; current != end && *current >= '0' && *current <= '9'; ++current) - index = index * 10 + ArrayIndex(*current - '0'); - args_.push_back(index); - } - if (current == end || *current++ != ']') - invalidPath(path, int(current - path.c_str())); - } else if (*current == '%') { - addPathInArg(path, in, itInArg, PathArgument::kindKey); - ++current; - } else if (*current == '.') { - ++current; - } else { - const char* beginName = current; - while (current != end && !strchr("[.", *current)) - ++current; - args_.push_back(std::string(beginName, current)); - } - } -} - -void Path::addPathInArg(const std::string& /*path*/, - const InArgs& in, - InArgs::const_iterator& itInArg, - PathArgument::Kind kind) { - if (itInArg == in.end()) { - // Error: missing argument %d - } else if ((*itInArg)->kind_ != kind) { - // Error: bad argument type - } else { - args_.push_back(**itInArg); - } -} - -void Path::invalidPath(const std::string& /*path*/, int /*location*/) { - // Error: invalid path. -} - -const Value& Path::resolve(const Value& root) const { - const Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { - const PathArgument& arg = *it; - if (arg.kind_ == PathArgument::kindIndex) { - if (!node->isArray() || !node->isValidIndex(arg.index_)) { - // Error: unable to resolve path (array value expected at position... - } - node = &((*node)[arg.index_]); - } else if (arg.kind_ == PathArgument::kindKey) { - if (!node->isObject()) { - // Error: unable to resolve path (object value expected at position...) - } - node = &((*node)[arg.key_]); - if (node == &Value::nullRef) { - // Error: unable to resolve path (object has no member named '' at - // position...) - } - } - } - return *node; -} - -Value Path::resolve(const Value& root, const Value& defaultValue) const { - const Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { - const PathArgument& arg = *it; - if (arg.kind_ == PathArgument::kindIndex) { - if (!node->isArray() || !node->isValidIndex(arg.index_)) - return defaultValue; - node = &((*node)[arg.index_]); - } else if (arg.kind_ == PathArgument::kindKey) { - if (!node->isObject()) - return defaultValue; - node = &((*node)[arg.key_]); - if (node == &Value::nullRef) - return defaultValue; - } - } - return *node; -} - -Value& Path::make(Value& root) const { - Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { - const PathArgument& arg = *it; - if (arg.kind_ == PathArgument::kindIndex) { - if (!node->isArray()) { - // Error: node is not an array at position ... - } - node = &((*node)[arg.index_]); - } else if (arg.kind_ == PathArgument::kindKey) { - if (!node->isObject()) { - // Error: node is not an object at position... - } - node = &((*node)[arg.key_]); - } - } - return *node; -} - -} // namespace Json diff --git a/3rdparty/jsoncpp/src/lib_json/json_valueiterator.inl b/3rdparty/jsoncpp/src/lib_json/json_valueiterator.inl deleted file mode 100644 index d01d3c018c9..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/json_valueiterator.inl +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// 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 - -// included by json_value.cpp - -namespace Json { - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueIteratorBase -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueIteratorBase::ValueIteratorBase() - : current_(), isNull_(true) { -} - -ValueIteratorBase::ValueIteratorBase( - const Value::ObjectValues::iterator& current) - : current_(current), isNull_(false) {} - -Value& ValueIteratorBase::deref() const { - return current_->second; -} - -void ValueIteratorBase::increment() { - ++current_; -} - -void ValueIteratorBase::decrement() { - --current_; -} - -ValueIteratorBase::difference_type -ValueIteratorBase::computeDistance(const SelfType& other) const { -#ifdef JSON_USE_CPPTL_SMALLMAP - return other.current_ - current_; -#else - // Iterator for null value are initialized using the default - // constructor, which initialize current_ to the default - // std::map::iterator. As begin() and end() are two instance - // of the default std::map::iterator, they can not be compared. - // To allow this, we handle this comparison specifically. - if (isNull_ && other.isNull_) { - return 0; - } - - // Usage of std::distance is not portable (does not compile with Sun Studio 12 - // RogueWave STL, - // which is the one used by default). - // Using a portable hand-made version for non random iterator instead: - // return difference_type( std::distance( current_, other.current_ ) ); - difference_type myDistance = 0; - for (Value::ObjectValues::iterator it = current_; it != other.current_; - ++it) { - ++myDistance; - } - return myDistance; -#endif -} - -bool ValueIteratorBase::isEqual(const SelfType& other) const { - if (isNull_) { - return other.isNull_; - } - return current_ == other.current_; -} - -void ValueIteratorBase::copy(const SelfType& other) { - current_ = other.current_; - isNull_ = other.isNull_; -} - -Value ValueIteratorBase::key() const { - const Value::CZString czstring = (*current_).first; - if (czstring.data()) { - if (czstring.isStaticString()) - return Value(StaticString(czstring.data())); - return Value(czstring.data(), czstring.data() + czstring.length()); - } - return Value(czstring.index()); -} - -UInt ValueIteratorBase::index() const { - const Value::CZString czstring = (*current_).first; - if (!czstring.data()) - return czstring.index(); - return Value::UInt(-1); -} - -std::string ValueIteratorBase::name() const { - char const* key; - char const* end; - key = memberName(&end); - if (!key) return std::string(); - return std::string(key, end); -} - -char const* ValueIteratorBase::memberName() const { - const char* name = (*current_).first.data(); - return name ? name : ""; -} - -char const* ValueIteratorBase::memberName(char const** end) const { - const char* name = (*current_).first.data(); - if (!name) { - *end = NULL; - return NULL; - } - *end = name + (*current_).first.length(); - return name; -} - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueConstIterator -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueConstIterator::ValueConstIterator() {} - -ValueConstIterator::ValueConstIterator( - const Value::ObjectValues::iterator& current) - : ValueIteratorBase(current) {} - -ValueConstIterator& ValueConstIterator:: -operator=(const ValueIteratorBase& other) { - copy(other); - return *this; -} - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueIterator -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueIterator::ValueIterator() {} - -ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) - : ValueIteratorBase(current) {} - -ValueIterator::ValueIterator(const ValueConstIterator& other) - : ValueIteratorBase(other) {} - -ValueIterator::ValueIterator(const ValueIterator& other) - : ValueIteratorBase(other) {} - -ValueIterator& ValueIterator::operator=(const SelfType& other) { - copy(other); - return *this; -} - -} // namespace Json diff --git a/3rdparty/jsoncpp/src/lib_json/json_writer.cpp b/3rdparty/jsoncpp/src/lib_json/json_writer.cpp deleted file mode 100644 index 2f940c8a43f..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/json_writer.cpp +++ /dev/null @@ -1,1179 +0,0 @@ -// Copyright 2011 Baptiste Lepilleur -// 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(JSON_IS_AMALGAMATION) -#include <json/writer.h> -#include "json_tool.h" -#endif // if !defined(JSON_IS_AMALGAMATION) -#include <iomanip> -#include <memory> -#include <sstream> -#include <utility> -#include <set> -#include <cassert> -#include <cstring> -#include <cstdio> - -#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0 -#include <float.h> -#define isfinite _finite -#elif defined(__sun) && defined(__SVR4) //Solaris -#include <ieeefp.h> -#define isfinite finite -#else -#include <cmath> -#define isfinite std::isfinite -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below -#define snprintf _snprintf -#elif defined(__ANDROID__) -#define snprintf snprintf -#elif __cplusplus >= 201103L -#define snprintf std::snprintf -#endif - -#if defined(__BORLANDC__) -#include <float.h> -#define isfinite _finite -#define snprintf _snprintf -#endif - -#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 -// Disable warning about strdup being deprecated. -#pragma warning(disable : 4996) -#endif - -namespace Json { - -#if __cplusplus >= 201103L -typedef std::unique_ptr<StreamWriter> StreamWriterPtr; -#else -typedef std::auto_ptr<StreamWriter> StreamWriterPtr; -#endif - -static bool containsControlCharacter(const char* str) { - while (*str) { - if (isControlCharacter(*(str++))) - return true; - } - return false; -} - -static bool containsControlCharacter0(const char* str, unsigned len) { - char const* end = str + len; - while (end != str) { - if (isControlCharacter(*str) || 0==*str) - return true; - ++str; - } - return false; -} - -std::string valueToString(LargestInt value) { - UIntToStringBuffer buffer; - char* current = buffer + sizeof(buffer); - bool isNegative = value < 0; - if (isNegative) - value = -value; - uintToString(LargestUInt(value), current); - if (isNegative) - *--current = '-'; - assert(current >= buffer); - return current; -} - -std::string valueToString(LargestUInt value) { - UIntToStringBuffer buffer; - char* current = buffer + sizeof(buffer); - uintToString(value, current); - assert(current >= buffer); - return current; -} - -#if defined(JSON_HAS_INT64) - -std::string valueToString(Int value) { - return valueToString(LargestInt(value)); -} - -std::string valueToString(UInt value) { - return valueToString(LargestUInt(value)); -} - -#endif // # if defined(JSON_HAS_INT64) - -std::string valueToString(double value) { - // Allocate a buffer that is more than large enough to store the 16 digits of - // precision requested below. - char buffer[32]; - int len = -1; - -// Print into the buffer. We need not request the alternative representation -// that always has a decimal point because JSON doesn't distingish the -// concepts of reals and integers. -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with - // visual studio 2005 to - // avoid warning. -#if defined(WINCE) - len = _snprintf(buffer, sizeof(buffer), "%.17g", value); -#else - len = sprintf_s(buffer, sizeof(buffer), "%.17g", value); -#endif -#else - if (isfinite(value)) { - len = snprintf(buffer, sizeof(buffer), "%.17g", value); - } else { - // IEEE standard states that NaN values will not compare to themselves - if (value != value) { - len = snprintf(buffer, sizeof(buffer), "null"); - } else if (value < 0) { - len = snprintf(buffer, sizeof(buffer), "-1e+9999"); - } else { - len = snprintf(buffer, sizeof(buffer), "1e+9999"); - } - // For those, we do not need to call fixNumLoc, but it is fast. - } -#endif - assert(len >= 0); - fixNumericLocale(buffer, buffer + len); - return buffer; -} - -std::string valueToString(bool value) { return value ? "true" : "false"; } - -std::string valueToQuotedString(const char* value) { - if (value == NULL) - return ""; - // Not sure how to handle unicode... - if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && - !containsControlCharacter(value)) - return std::string("\"") + value + "\""; - // We have to walk value and escape any special characters. - // Appending to std::string is not efficient, but this should be rare. - // (Note: forward slashes are *not* rare, but I am not escaping them.) - std::string::size_type maxsize = - strlen(value) * 2 + 3; // allescaped+quotes+NULL - std::string result; - result.reserve(maxsize); // to avoid lots of mallocs - result += "\""; - for (const char* c = value; *c != 0; ++c) { - switch (*c) { - case '\"': - result += "\\\""; - break; - case '\\': - result += "\\\\"; - break; - case '\b': - result += "\\b"; - break; - case '\f': - result += "\\f"; - break; - case '\n': - result += "\\n"; - break; - case '\r': - result += "\\r"; - break; - case '\t': - result += "\\t"; - break; - // case '/': - // Even though \/ is considered a legal escape in JSON, a bare - // slash is also legal, so I see no reason to escape it. - // (I hope I am not misunderstanding something. - // blep notes: actually escaping \/ may be useful in javascript to avoid </ - // sequence. - // Should add a flag to allow this compatibility mode and prevent this - // sequence from occurring. - default: - if (isControlCharacter(*c)) { - std::ostringstream oss; - oss << "\\u" << std::hex << std::uppercase << std::setfill('0') - << std::setw(4) << static_cast<int>(*c); - result += oss.str(); - } else { - result += *c; - } - break; - } - } - result += "\""; - return result; -} - -// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp -static char const* strnpbrk(char const* s, char const* accept, size_t n) { - assert((s || !n) && accept); - - char const* const end = s + n; - for (char const* cur = s; cur < end; ++cur) { - int const c = *cur; - for (char const* a = accept; *a; ++a) { - if (*a == c) { - return cur; - } - } - } - return NULL; -} -static std::string valueToQuotedStringN(const char* value, unsigned length) { - if (value == NULL) - return ""; - // Not sure how to handle unicode... - if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL && - !containsControlCharacter0(value, length)) - return std::string("\"") + value + "\""; - // We have to walk value and escape any special characters. - // Appending to std::string is not efficient, but this should be rare. - // (Note: forward slashes are *not* rare, but I am not escaping them.) - std::string::size_type maxsize = - length * 2 + 3; // allescaped+quotes+NULL - std::string result; - result.reserve(maxsize); // to avoid lots of mallocs - result += "\""; - char const* end = value + length; - for (const char* c = value; c != end; ++c) { - switch (*c) { - case '\"': - result += "\\\""; - break; - case '\\': - result += "\\\\"; - break; - case '\b': - result += "\\b"; - break; - case '\f': - result += "\\f"; - break; - case '\n': - result += "\\n"; - break; - case '\r': - result += "\\r"; - break; - case '\t': - result += "\\t"; - break; - // case '/': - // Even though \/ is considered a legal escape in JSON, a bare - // slash is also legal, so I see no reason to escape it. - // (I hope I am not misunderstanding something.) - // blep notes: actually escaping \/ may be useful in javascript to avoid </ - // sequence. - // Should add a flag to allow this compatibility mode and prevent this - // sequence from occurring. - default: - if ((isControlCharacter(*c)) || (*c == 0)) { - std::ostringstream oss; - oss << "\\u" << std::hex << std::uppercase << std::setfill('0') - << std::setw(4) << static_cast<int>(*c); - result += oss.str(); - } else { - result += *c; - } - break; - } - } - result += "\""; - return result; -} - -// Class Writer -// ////////////////////////////////////////////////////////////////// -Writer::~Writer() {} - -// Class FastWriter -// ////////////////////////////////////////////////////////////////// - -FastWriter::FastWriter() - : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false), - omitEndingLineFeed_(false) {} - -void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; } - -void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } - -void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } - -std::string FastWriter::write(const Value& root) { - document_ = ""; - writeValue(root); - if (!omitEndingLineFeed_) - document_ += "\n"; - return document_; -} - -void FastWriter::writeValue(const Value& value) { - switch (value.type()) { - case nullValue: - if (!dropNullPlaceholders_) - document_ += "null"; - break; - case intValue: - document_ += valueToString(value.asLargestInt()); - break; - case uintValue: - document_ += valueToString(value.asLargestUInt()); - break; - case realValue: - document_ += valueToString(value.asDouble()); - break; - case stringValue: - { - // Is NULL possible for value.string_? - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str)); - break; - } - case booleanValue: - document_ += valueToString(value.asBool()); - break; - case arrayValue: { - document_ += '['; - int size = value.size(); - for (int index = 0; index < size; ++index) { - if (index > 0) - document_ += ','; - writeValue(value[index]); - } - document_ += ']'; - } break; - case objectValue: { - Value::Members members(value.getMemberNames()); - document_ += '{'; - for (Value::Members::iterator it = members.begin(); it != members.end(); - ++it) { - const std::string& name = *it; - if (it != members.begin()) - document_ += ','; - document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())); - document_ += yamlCompatiblityEnabled_ ? ": " : ":"; - writeValue(value[name]); - } - document_ += '}'; - } break; - } -} - -// Class StyledWriter -// ////////////////////////////////////////////////////////////////// - -StyledWriter::StyledWriter() - : rightMargin_(74), indentSize_(3), addChildValues_() {} - -std::string StyledWriter::write(const Value& root) { - document_ = ""; - addChildValues_ = false; - indentString_ = ""; - writeCommentBeforeValue(root); - writeValue(root); - writeCommentAfterValueOnSameLine(root); - document_ += "\n"; - return document_; -} - -void StyledWriter::writeValue(const Value& value) { - switch (value.type()) { - case nullValue: - pushValue("null"); - break; - case intValue: - pushValue(valueToString(value.asLargestInt())); - break; - case uintValue: - pushValue(valueToString(value.asLargestUInt())); - break; - case realValue: - pushValue(valueToString(value.asDouble())); - break; - case stringValue: - { - // Is NULL possible for value.string_? - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); - else pushValue(""); - break; - } - case booleanValue: - pushValue(valueToString(value.asBool())); - break; - case arrayValue: - writeArrayValue(value); - break; - case objectValue: { - Value::Members members(value.getMemberNames()); - if (members.empty()) - pushValue("{}"); - else { - writeWithIndent("{"); - indent(); - Value::Members::iterator it = members.begin(); - for (;;) { - const std::string& name = *it; - const Value& childValue = value[name]; - writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); - document_ += " : "; - writeValue(childValue); - if (++it == members.end()) { - writeCommentAfterValueOnSameLine(childValue); - break; - } - document_ += ','; - writeCommentAfterValueOnSameLine(childValue); - } - unindent(); - writeWithIndent("}"); - } - } break; - } -} - -void StyledWriter::writeArrayValue(const Value& value) { - unsigned size = value.size(); - if (size == 0) - pushValue("[]"); - else { - bool isArrayMultiLine = isMultineArray(value); - if (isArrayMultiLine) { - writeWithIndent("["); - indent(); - bool hasChildValue = !childValues_.empty(); - unsigned index = 0; - for (;;) { - const Value& childValue = value[index]; - writeCommentBeforeValue(childValue); - if (hasChildValue) - writeWithIndent(childValues_[index]); - else { - writeIndent(); - writeValue(childValue); - } - if (++index == size) { - writeCommentAfterValueOnSameLine(childValue); - break; - } - document_ += ','; - writeCommentAfterValueOnSameLine(childValue); - } - unindent(); - writeWithIndent("]"); - } else // output on a single line - { - assert(childValues_.size() == size); - document_ += "[ "; - for (unsigned index = 0; index < size; ++index) { - if (index > 0) - document_ += ", "; - document_ += childValues_[index]; - } - document_ += " ]"; - } - } -} - -bool StyledWriter::isMultineArray(const Value& value) { - int size = value.size(); - bool isMultiLine = size * 3 >= rightMargin_; - childValues_.clear(); - for (int index = 0; index < size && !isMultiLine; ++index) { - const Value& childValue = value[index]; - isMultiLine = - isMultiLine || ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); - } - if (!isMultiLine) // check if line length > max line length - { - childValues_.reserve(size); - addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' - for (int index = 0; index < size; ++index) { - if (hasCommentForValue(value[index])) { - isMultiLine = true; - } - writeValue(value[index]); - lineLength += int(childValues_[index].length()); - } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; - } - return isMultiLine; -} - -void StyledWriter::pushValue(const std::string& value) { - if (addChildValues_) - childValues_.push_back(value); - else - document_ += value; -} - -void StyledWriter::writeIndent() { - if (!document_.empty()) { - char last = document_[document_.length() - 1]; - if (last == ' ') // already indented - return; - if (last != '\n') // Comments may add new-line - document_ += '\n'; - } - document_ += indentString_; -} - -void StyledWriter::writeWithIndent(const std::string& value) { - writeIndent(); - document_ += value; -} - -void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); } - -void StyledWriter::unindent() { - assert(int(indentString_.size()) >= indentSize_); - indentString_.resize(indentString_.size() - indentSize_); -} - -void StyledWriter::writeCommentBeforeValue(const Value& root) { - if (!root.hasComment(commentBefore)) - return; - - document_ += "\n"; - writeIndent(); - const std::string& comment = root.getComment(commentBefore); - std::string::const_iterator iter = comment.begin(); - while (iter != comment.end()) { - document_ += *iter; - if (*iter == '\n' && - (iter != comment.end() && *(iter + 1) == '/')) - writeIndent(); - ++iter; - } - - // Comments are stripped of trailing newlines, so add one here - document_ += "\n"; -} - -void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { - if (root.hasComment(commentAfterOnSameLine)) - document_ += " " + root.getComment(commentAfterOnSameLine); - - if (root.hasComment(commentAfter)) { - document_ += "\n"; - document_ += root.getComment(commentAfter); - document_ += "\n"; - } -} - -bool StyledWriter::hasCommentForValue(const Value& value) { - return value.hasComment(commentBefore) || - value.hasComment(commentAfterOnSameLine) || - value.hasComment(commentAfter); -} - -// Class StyledStreamWriter -// ////////////////////////////////////////////////////////////////// - -StyledStreamWriter::StyledStreamWriter(std::string indentation) - : document_(NULL), rightMargin_(74), indentation_(indentation), - addChildValues_() {} - -void StyledStreamWriter::write(std::ostream& out, const Value& root) { - document_ = &out; - addChildValues_ = false; - indentString_ = ""; - indented_ = true; - writeCommentBeforeValue(root); - if (!indented_) writeIndent(); - indented_ = true; - writeValue(root); - writeCommentAfterValueOnSameLine(root); - *document_ << "\n"; - document_ = NULL; // Forget the stream, for safety. -} - -void StyledStreamWriter::writeValue(const Value& value) { - switch (value.type()) { - case nullValue: - pushValue("null"); - break; - case intValue: - pushValue(valueToString(value.asLargestInt())); - break; - case uintValue: - pushValue(valueToString(value.asLargestUInt())); - break; - case realValue: - pushValue(valueToString(value.asDouble())); - break; - case stringValue: - { - // Is NULL possible for value.string_? - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); - else pushValue(""); - break; - } - case booleanValue: - pushValue(valueToString(value.asBool())); - break; - case arrayValue: - writeArrayValue(value); - break; - case objectValue: { - Value::Members members(value.getMemberNames()); - if (members.empty()) - pushValue("{}"); - else { - writeWithIndent("{"); - indent(); - Value::Members::iterator it = members.begin(); - for (;;) { - const std::string& name = *it; - const Value& childValue = value[name]; - writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); - *document_ << " : "; - writeValue(childValue); - if (++it == members.end()) { - writeCommentAfterValueOnSameLine(childValue); - break; - } - *document_ << ","; - writeCommentAfterValueOnSameLine(childValue); - } - unindent(); - writeWithIndent("}"); - } - } break; - } -} - -void StyledStreamWriter::writeArrayValue(const Value& value) { - unsigned size = value.size(); - if (size == 0) - pushValue("[]"); - else { - bool isArrayMultiLine = isMultineArray(value); - if (isArrayMultiLine) { - writeWithIndent("["); - indent(); - bool hasChildValue = !childValues_.empty(); - unsigned index = 0; - for (;;) { - const Value& childValue = value[index]; - writeCommentBeforeValue(childValue); - if (hasChildValue) - writeWithIndent(childValues_[index]); - else { - if (!indented_) writeIndent(); - indented_ = true; - writeValue(childValue); - indented_ = false; - } - if (++index == size) { - writeCommentAfterValueOnSameLine(childValue); - break; - } - *document_ << ","; - writeCommentAfterValueOnSameLine(childValue); - } - unindent(); - writeWithIndent("]"); - } else // output on a single line - { - assert(childValues_.size() == size); - *document_ << "[ "; - for (unsigned index = 0; index < size; ++index) { - if (index > 0) - *document_ << ", "; - *document_ << childValues_[index]; - } - *document_ << " ]"; - } - } -} - -bool StyledStreamWriter::isMultineArray(const Value& value) { - int size = value.size(); - bool isMultiLine = size * 3 >= rightMargin_; - childValues_.clear(); - for (int index = 0; index < size && !isMultiLine; ++index) { - const Value& childValue = value[index]; - isMultiLine = - isMultiLine || ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); - } - if (!isMultiLine) // check if line length > max line length - { - childValues_.reserve(size); - addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' - for (int index = 0; index < size; ++index) { - if (hasCommentForValue(value[index])) { - isMultiLine = true; - } - writeValue(value[index]); - lineLength += int(childValues_[index].length()); - } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; - } - return isMultiLine; -} - -void StyledStreamWriter::pushValue(const std::string& value) { - if (addChildValues_) - childValues_.push_back(value); - else - *document_ << value; -} - -void StyledStreamWriter::writeIndent() { - // blep intended this to look at the so-far-written string - // to determine whether we are already indented, but - // with a stream we cannot do that. So we rely on some saved state. - // The caller checks indented_. - *document_ << '\n' << indentString_; -} - -void StyledStreamWriter::writeWithIndent(const std::string& value) { - if (!indented_) writeIndent(); - *document_ << value; - indented_ = false; -} - -void StyledStreamWriter::indent() { indentString_ += indentation_; } - -void StyledStreamWriter::unindent() { - assert(indentString_.size() >= indentation_.size()); - indentString_.resize(indentString_.size() - indentation_.size()); -} - -void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { - if (!root.hasComment(commentBefore)) - return; - - if (!indented_) writeIndent(); - const std::string& comment = root.getComment(commentBefore); - std::string::const_iterator iter = comment.begin(); - while (iter != comment.end()) { - *document_ << *iter; - if (*iter == '\n' && - (iter != comment.end() && *(iter + 1) == '/')) - // writeIndent(); // would include newline - *document_ << indentString_; - ++iter; - } - indented_ = false; -} - -void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) { - if (root.hasComment(commentAfterOnSameLine)) - *document_ << ' ' << root.getComment(commentAfterOnSameLine); - - if (root.hasComment(commentAfter)) { - writeIndent(); - *document_ << root.getComment(commentAfter); - } - indented_ = false; -} - -bool StyledStreamWriter::hasCommentForValue(const Value& value) { - return value.hasComment(commentBefore) || - value.hasComment(commentAfterOnSameLine) || - value.hasComment(commentAfter); -} - -////////////////////////// -// BuiltStyledStreamWriter - -/// Scoped enums are not available until C++11. -struct CommentStyle { - /// Decide whether to write comments. - enum Enum { - None, ///< Drop all comments. - Most, ///< Recover odd behavior of previous versions (not implemented yet). - All ///< Keep all comments. - }; -}; - -struct BuiltStyledStreamWriter : public StreamWriter -{ - BuiltStyledStreamWriter( - std::string const& indentation, - CommentStyle::Enum cs, - std::string const& colonSymbol, - std::string const& nullSymbol, - std::string const& endingLineFeedSymbol); - virtual int write(Value const& root, std::ostream* sout); -private: - void writeValue(Value const& value); - void writeArrayValue(Value const& value); - bool isMultineArray(Value const& value); - void pushValue(std::string const& value); - void writeIndent(); - void writeWithIndent(std::string const& value); - void indent(); - void unindent(); - void writeCommentBeforeValue(Value const& root); - void writeCommentAfterValueOnSameLine(Value const& root); - static bool hasCommentForValue(const Value& value); - - typedef std::vector<std::string> ChildValues; - - ChildValues childValues_; - std::string indentString_; - int rightMargin_; - std::string indentation_; - CommentStyle::Enum cs_; - std::string colonSymbol_; - std::string nullSymbol_; - std::string endingLineFeedSymbol_; - bool addChildValues_ : 1; - bool indented_ : 1; -}; -BuiltStyledStreamWriter::BuiltStyledStreamWriter( - std::string const& indentation, - CommentStyle::Enum cs, - std::string const& colonSymbol, - std::string const& nullSymbol, - std::string const& endingLineFeedSymbol) - : rightMargin_(74) - , indentation_(indentation) - , cs_(cs) - , colonSymbol_(colonSymbol) - , nullSymbol_(nullSymbol) - , endingLineFeedSymbol_(endingLineFeedSymbol) - , addChildValues_(false) - , indented_(false) -{ -} -int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout) -{ - sout_ = sout; - addChildValues_ = false; - indented_ = true; - indentString_ = ""; - writeCommentBeforeValue(root); - if (!indented_) writeIndent(); - indented_ = true; - writeValue(root); - writeCommentAfterValueOnSameLine(root); - *sout_ << endingLineFeedSymbol_; - sout_ = NULL; - return 0; -} -void BuiltStyledStreamWriter::writeValue(Value const& value) { - switch (value.type()) { - case nullValue: - pushValue(nullSymbol_); - break; - case intValue: - pushValue(valueToString(value.asLargestInt())); - break; - case uintValue: - pushValue(valueToString(value.asLargestUInt())); - break; - case realValue: - pushValue(valueToString(value.asDouble())); - break; - case stringValue: - { - // Is NULL is possible for value.string_? - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); - else pushValue(""); - break; - } - case booleanValue: - pushValue(valueToString(value.asBool())); - break; - case arrayValue: - writeArrayValue(value); - break; - case objectValue: { - Value::Members members(value.getMemberNames()); - if (members.empty()) - pushValue("{}"); - else { - writeWithIndent("{"); - indent(); - Value::Members::iterator it = members.begin(); - for (;;) { - std::string const& name = *it; - Value const& childValue = value[name]; - writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()))); - *sout_ << colonSymbol_; - writeValue(childValue); - if (++it == members.end()) { - writeCommentAfterValueOnSameLine(childValue); - break; - } - *sout_ << ","; - writeCommentAfterValueOnSameLine(childValue); - } - unindent(); - writeWithIndent("}"); - } - } break; - } -} - -void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { - unsigned size = value.size(); - if (size == 0) - pushValue("[]"); - else { - bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value); - if (isMultiLine) { - writeWithIndent("["); - indent(); - bool hasChildValue = !childValues_.empty(); - unsigned index = 0; - for (;;) { - Value const& childValue = value[index]; - writeCommentBeforeValue(childValue); - if (hasChildValue) - writeWithIndent(childValues_[index]); - else { - if (!indented_) writeIndent(); - indented_ = true; - writeValue(childValue); - indented_ = false; - } - if (++index == size) { - writeCommentAfterValueOnSameLine(childValue); - break; - } - *sout_ << ","; - writeCommentAfterValueOnSameLine(childValue); - } - unindent(); - writeWithIndent("]"); - } else // output on a single line - { - assert(childValues_.size() == size); - *sout_ << "["; - if (!indentation_.empty()) *sout_ << " "; - for (unsigned index = 0; index < size; ++index) { - if (index > 0) - *sout_ << ", "; - *sout_ << childValues_[index]; - } - if (!indentation_.empty()) *sout_ << " "; - *sout_ << "]"; - } - } -} - -bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { - int size = value.size(); - bool isMultiLine = size * 3 >= rightMargin_; - childValues_.clear(); - for (int index = 0; index < size && !isMultiLine; ++index) { - Value const& childValue = value[index]; - isMultiLine = - isMultiLine || ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); - } - if (!isMultiLine) // check if line length > max line length - { - childValues_.reserve(size); - addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' - for (int index = 0; index < size; ++index) { - if (hasCommentForValue(value[index])) { - isMultiLine = true; - } - writeValue(value[index]); - lineLength += int(childValues_[index].length()); - } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; - } - return isMultiLine; -} - -void BuiltStyledStreamWriter::pushValue(std::string const& value) { - if (addChildValues_) - childValues_.push_back(value); - else - *sout_ << value; -} - -void BuiltStyledStreamWriter::writeIndent() { - // blep intended this to look at the so-far-written string - // to determine whether we are already indented, but - // with a stream we cannot do that. So we rely on some saved state. - // The caller checks indented_. - - if (!indentation_.empty()) { - // In this case, drop newlines too. - *sout_ << '\n' << indentString_; - } -} - -void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) { - if (!indented_) writeIndent(); - *sout_ << value; - indented_ = false; -} - -void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; } - -void BuiltStyledStreamWriter::unindent() { - assert(indentString_.size() >= indentation_.size()); - indentString_.resize(indentString_.size() - indentation_.size()); -} - -void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { - if (cs_ == CommentStyle::None) return; - if (!root.hasComment(commentBefore)) - return; - - if (!indented_) writeIndent(); - const std::string& comment = root.getComment(commentBefore); - std::string::const_iterator iter = comment.begin(); - while (iter != comment.end()) { - *sout_ << *iter; - if (*iter == '\n' && - (iter != comment.end() && *(iter + 1) == '/')) - // writeIndent(); // would write extra newline - *sout_ << indentString_; - ++iter; - } - indented_ = false; -} - -void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) { - if (cs_ == CommentStyle::None) return; - if (root.hasComment(commentAfterOnSameLine)) - *sout_ << " " + root.getComment(commentAfterOnSameLine); - - if (root.hasComment(commentAfter)) { - writeIndent(); - *sout_ << root.getComment(commentAfter); - } -} - -// static -bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { - return value.hasComment(commentBefore) || - value.hasComment(commentAfterOnSameLine) || - value.hasComment(commentAfter); -} - -/////////////// -// StreamWriter - -StreamWriter::StreamWriter() - : sout_(NULL) -{ -} -StreamWriter::~StreamWriter() -{ -} -StreamWriter::Factory::~Factory() -{} -StreamWriterBuilder::StreamWriterBuilder() -{ - setDefaults(&settings_); -} -StreamWriterBuilder::~StreamWriterBuilder() -{} -StreamWriter* StreamWriterBuilder::newStreamWriter() const -{ - std::string indentation = settings_["indentation"].asString(); - std::string cs_str = settings_["commentStyle"].asString(); - bool eyc = settings_["enableYAMLCompatibility"].asBool(); - bool dnp = settings_["dropNullPlaceholders"].asBool(); - CommentStyle::Enum cs = CommentStyle::All; - if (cs_str == "All") { - cs = CommentStyle::All; - } else if (cs_str == "None") { - cs = CommentStyle::None; - } else { - throwRuntimeError("commentStyle must be 'All' or 'None'"); - } - std::string colonSymbol = " : "; - if (eyc) { - colonSymbol = ": "; - } else if (indentation.empty()) { - colonSymbol = ":"; - } - std::string nullSymbol = "null"; - if (dnp) { - nullSymbol = ""; - } - std::string endingLineFeedSymbol = ""; - return new BuiltStyledStreamWriter( - indentation, cs, - colonSymbol, nullSymbol, endingLineFeedSymbol); -} -static void getValidWriterKeys(std::set<std::string>* valid_keys) -{ - valid_keys->clear(); - valid_keys->insert("indentation"); - valid_keys->insert("commentStyle"); - valid_keys->insert("enableYAMLCompatibility"); - valid_keys->insert("dropNullPlaceholders"); -} -bool StreamWriterBuilder::validate(Json::Value* invalid) const -{ - Json::Value my_invalid; - if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL - Json::Value& inv = *invalid; - std::set<std::string> valid_keys; - getValidWriterKeys(&valid_keys); - Value::Members keys = settings_.getMemberNames(); - size_t n = keys.size(); - for (size_t i = 0; i < n; ++i) { - std::string const& key = keys[i]; - if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = settings_[key]; - } - } - return 0u == inv.size(); -} -Value& StreamWriterBuilder::operator[](std::string key) -{ - return settings_[key]; -} -// static -void StreamWriterBuilder::setDefaults(Json::Value* settings) -{ - //! [StreamWriterBuilderDefaults] - (*settings)["commentStyle"] = "All"; - (*settings)["indentation"] = "\t"; - (*settings)["enableYAMLCompatibility"] = false; - (*settings)["dropNullPlaceholders"] = false; - //! [StreamWriterBuilderDefaults] -} - -std::string writeString(StreamWriter::Factory const& builder, Value const& root) { - std::ostringstream sout; - StreamWriterPtr const writer(builder.newStreamWriter()); - writer->write(root, &sout); - return sout.str(); -} - -std::ostream& operator<<(std::ostream& sout, Value const& root) { - StreamWriterBuilder builder; - StreamWriterPtr const writer(builder.newStreamWriter()); - writer->write(root, &sout); - return sout; -} - -} // namespace Json diff --git a/3rdparty/jsoncpp/src/lib_json/sconscript b/3rdparty/jsoncpp/src/lib_json/sconscript deleted file mode 100644 index 6e7c6c8a076..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/sconscript +++ /dev/null @@ -1,8 +0,0 @@ -Import( 'env buildLibrary' ) - -buildLibrary( env, Split( """ - json_reader.cpp - json_value.cpp - json_writer.cpp - """ ), - 'json' ) diff --git a/3rdparty/jsoncpp/src/lib_json/version.h.in b/3rdparty/jsoncpp/src/lib_json/version.h.in deleted file mode 100644 index 761ca3a7b92..00000000000 --- a/3rdparty/jsoncpp/src/lib_json/version.h.in +++ /dev/null @@ -1,14 +0,0 @@ -// DO NOT EDIT. This file is generated by CMake from "version" -// and "version.h.in" files. -// Run CMake configure step to update it. -#ifndef JSON_VERSION_H_INCLUDED -# define JSON_VERSION_H_INCLUDED - -# define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@" -# define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@ -# define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ -# define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ -# define JSONCPP_VERSION_QUALIFIER -# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) - -#endif // JSON_VERSION_H_INCLUDED diff --git a/3rdparty/jsoncpp/src/test_lib_json/CMakeLists.txt b/3rdparty/jsoncpp/src/test_lib_json/CMakeLists.txt deleted file mode 100644 index f54c85f6817..00000000000 --- a/3rdparty/jsoncpp/src/test_lib_json/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# vim: et ts=4 sts=4 sw=4 tw=0 - -ADD_EXECUTABLE( jsoncpp_test - jsontest.cpp - jsontest.h - main.cpp - ) - - -IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS( -DJSON_DLL ) - TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib) -ELSE(BUILD_SHARED_LIBS) - TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib_static) -ENDIF(BUILD_SHARED_LIBS) - -# another way to solve issue #90 -#set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) - -# Run unit tests in post-build -# (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?) -IF(JSONCPP_WITH_POST_BUILD_UNITTEST) - IF(BUILD_SHARED_LIBS) - # First, copy the shared lib, for Microsoft. - # Then, run the test executable. - ADD_CUSTOM_COMMAND( TARGET jsoncpp_test - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:jsoncpp_lib> $<TARGET_FILE_DIR:jsoncpp_test> - COMMAND $<TARGET_FILE:jsoncpp_test>) - ELSE(BUILD_SHARED_LIBS) - # Just run the test executable. - ADD_CUSTOM_COMMAND( TARGET jsoncpp_test - POST_BUILD - COMMAND $<TARGET_FILE:jsoncpp_test>) - ENDIF(BUILD_SHARED_LIBS) -ENDIF(JSONCPP_WITH_POST_BUILD_UNITTEST) - -SET_TARGET_PROPERTIES(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) diff --git a/3rdparty/jsoncpp/src/test_lib_json/jsontest.cpp b/3rdparty/jsoncpp/src/test_lib_json/jsontest.cpp deleted file mode 100644 index bd9463fa589..00000000000 --- a/3rdparty/jsoncpp/src/test_lib_json/jsontest.cpp +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// 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 - -#define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC -#include "jsontest.h" -#include <stdio.h> -#include <string> - -#if defined(_MSC_VER) -// Used to install a report hook that prevent dialog on assertion and error. -#include <crtdbg.h> -#endif // if defined(_MSC_VER) - -#if defined(_WIN32) -// Used to prevent dialog on memory fault. -// Limits headers included by Windows.h -#define WIN32_LEAN_AND_MEAN -#define NOSERVICE -#define NOMCX -#define NOIME -#define NOSOUND -#define NOCOMM -#define NORPC -#define NOGDI -#define NOUSER -#define NODRIVERS -#define NOLOGERROR -#define NOPROFILER -#define NOMEMMGR -#define NOLFILEIO -#define NOOPENFILE -#define NORESOURCE -#define NOATOM -#define NOLANGUAGE -#define NOLSTRING -#define NODBCS -#define NOKEYBOARDINFO -#define NOGDICAPMASKS -#define NOCOLOR -#define NOGDIOBJ -#define NODRAWTEXT -#define NOTEXTMETRIC -#define NOSCALABLEFONT -#define NOBITMAP -#define NORASTEROPS -#define NOMETAFILE -#define NOSYSMETRICS -#define NOSYSTEMPARAMSINFO -#define NOMSG -#define NOWINSTYLES -#define NOWINOFFSETS -#define NOSHOWWINDOW -#define NODEFERWINDOWPOS -#define NOVIRTUALKEYCODES -#define NOKEYSTATES -#define NOWH -#define NOMENUS -#define NOSCROLL -#define NOCLIPBOARD -#define NOICONS -#define NOMB -#define NOSYSCOMMANDS -#define NOMDI -#define NOCTLMGR -#define NOWINMESSAGES -#include <windows.h> -#endif // if defined(_WIN32) - -namespace JsonTest { - -// class TestResult -// ////////////////////////////////////////////////////////////////// - -TestResult::TestResult() - : predicateId_(1), lastUsedPredicateId_(0), messageTarget_(0) { - // The root predicate has id 0 - rootPredicateNode_.id_ = 0; - rootPredicateNode_.next_ = 0; - predicateStackTail_ = &rootPredicateNode_; -} - -void TestResult::setTestName(const std::string& name) { name_ = name; } - -TestResult& -TestResult::addFailure(const char* file, unsigned int line, const char* expr) { - /// Walks the PredicateContext stack adding them to failures_ if not already - /// added. - unsigned int nestingLevel = 0; - PredicateContext* lastNode = rootPredicateNode_.next_; - for (; lastNode != 0; lastNode = lastNode->next_) { - if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext - { - lastUsedPredicateId_ = lastNode->id_; - addFailureInfo( - lastNode->file_, lastNode->line_, lastNode->expr_, nestingLevel); - // Link the PredicateContext to the failure for message target when - // popping the PredicateContext. - lastNode->failure_ = &(failures_.back()); - } - ++nestingLevel; - } - - // Adds the failed assertion - addFailureInfo(file, line, expr, nestingLevel); - messageTarget_ = &(failures_.back()); - return *this; -} - -void TestResult::addFailureInfo(const char* file, - unsigned int line, - const char* expr, - unsigned int nestingLevel) { - Failure failure; - failure.file_ = file; - failure.line_ = line; - if (expr) { - failure.expr_ = expr; - } - failure.nestingLevel_ = nestingLevel; - failures_.push_back(failure); -} - -TestResult& TestResult::popPredicateContext() { - PredicateContext* lastNode = &rootPredicateNode_; - while (lastNode->next_ != 0 && lastNode->next_->next_ != 0) { - lastNode = lastNode->next_; - } - // Set message target to popped failure - PredicateContext* tail = lastNode->next_; - if (tail != 0 && tail->failure_ != 0) { - messageTarget_ = tail->failure_; - } - // Remove tail from list - predicateStackTail_ = lastNode; - lastNode->next_ = 0; - return *this; -} - -bool TestResult::failed() const { return !failures_.empty(); } - -unsigned int TestResult::getAssertionNestingLevel() const { - unsigned int level = 0; - const PredicateContext* lastNode = &rootPredicateNode_; - while (lastNode->next_ != 0) { - lastNode = lastNode->next_; - ++level; - } - return level; -} - -void TestResult::printFailure(bool printTestName) const { - if (failures_.empty()) { - return; - } - - if (printTestName) { - printf("* Detail of %s test failure:\n", name_.c_str()); - } - - // Print in reverse to display the callstack in the right order - Failures::const_iterator itEnd = failures_.end(); - for (Failures::const_iterator it = failures_.begin(); it != itEnd; ++it) { - const Failure& failure = *it; - std::string indent(failure.nestingLevel_ * 2, ' '); - if (failure.file_) { - printf("%s%s(%d): ", indent.c_str(), failure.file_, failure.line_); - } - if (!failure.expr_.empty()) { - printf("%s\n", failure.expr_.c_str()); - } else if (failure.file_) { - printf("\n"); - } - if (!failure.message_.empty()) { - std::string reindented = indentText(failure.message_, indent + " "); - printf("%s\n", reindented.c_str()); - } - } -} - -std::string TestResult::indentText(const std::string& text, - const std::string& indent) { - std::string reindented; - std::string::size_type lastIndex = 0; - while (lastIndex < text.size()) { - std::string::size_type nextIndex = text.find('\n', lastIndex); - if (nextIndex == std::string::npos) { - nextIndex = text.size() - 1; - } - reindented += indent; - reindented += text.substr(lastIndex, nextIndex - lastIndex + 1); - lastIndex = nextIndex + 1; - } - return reindented; -} - -TestResult& TestResult::addToLastFailure(const std::string& message) { - if (messageTarget_ != 0) { - messageTarget_->message_ += message; - } - return *this; -} - -TestResult& TestResult::operator<<(Json::Int64 value) { - return addToLastFailure(Json::valueToString(value)); -} - -TestResult& TestResult::operator<<(Json::UInt64 value) { - return addToLastFailure(Json::valueToString(value)); -} - -TestResult& TestResult::operator<<(bool value) { - return addToLastFailure(value ? "true" : "false"); -} - -// class TestCase -// ////////////////////////////////////////////////////////////////// - -TestCase::TestCase() : result_(0) {} - -TestCase::~TestCase() {} - -void TestCase::run(TestResult& result) { - result_ = &result; - runTestCase(); -} - -// class Runner -// ////////////////////////////////////////////////////////////////// - -Runner::Runner() {} - -Runner& Runner::add(TestCaseFactory factory) { - tests_.push_back(factory); - return *this; -} - -unsigned int Runner::testCount() const { - return static_cast<unsigned int>(tests_.size()); -} - -std::string Runner::testNameAt(unsigned int index) const { - TestCase* test = tests_[index](); - std::string name = test->testName(); - delete test; - return name; -} - -void Runner::runTestAt(unsigned int index, TestResult& result) const { - TestCase* test = tests_[index](); - result.setTestName(test->testName()); - printf("Testing %s: ", test->testName()); - fflush(stdout); -#if JSON_USE_EXCEPTION - try { -#endif // if JSON_USE_EXCEPTION - test->run(result); -#if JSON_USE_EXCEPTION - } - catch (const std::exception& e) { - result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:") - << e.what(); - } -#endif // if JSON_USE_EXCEPTION - delete test; - const char* status = result.failed() ? "FAILED" : "OK"; - printf("%s\n", status); - fflush(stdout); -} - -bool Runner::runAllTest(bool printSummary) const { - unsigned int count = testCount(); - std::deque<TestResult> failures; - for (unsigned int index = 0; index < count; ++index) { - TestResult result; - runTestAt(index, result); - if (result.failed()) { - failures.push_back(result); - } - } - - if (failures.empty()) { - if (printSummary) { - printf("All %d tests passed\n", count); - } - return true; - } else { - for (unsigned int index = 0; index < failures.size(); ++index) { - TestResult& result = failures[index]; - result.printFailure(count > 1); - } - - if (printSummary) { - unsigned int failedCount = static_cast<unsigned int>(failures.size()); - unsigned int passedCount = count - failedCount; - printf("%d/%d tests passed (%d failure(s))\n", - passedCount, - count, - failedCount); - } - return false; - } -} - -bool Runner::testIndex(const std::string& testName, - unsigned int& indexOut) const { - unsigned int count = testCount(); - for (unsigned int index = 0; index < count; ++index) { - if (testNameAt(index) == testName) { - indexOut = index; - return true; - } - } - return false; -} - -void Runner::listTests() const { - unsigned int count = testCount(); - for (unsigned int index = 0; index < count; ++index) { - printf("%s\n", testNameAt(index).c_str()); - } -} - -int Runner::runCommandLine(int argc, const char* argv[]) const { - // typedef std::deque<std::string> TestNames; - Runner subrunner; - for (int index = 1; index < argc; ++index) { - std::string opt = argv[index]; - if (opt == "--list-tests") { - listTests(); - return 0; - } else if (opt == "--test-auto") { - preventDialogOnCrash(); - } else if (opt == "--test") { - ++index; - if (index < argc) { - unsigned int testNameIndex; - if (testIndex(argv[index], testNameIndex)) { - subrunner.add(tests_[testNameIndex]); - } else { - fprintf(stderr, "Test '%s' does not exist!\n", argv[index]); - return 2; - } - } else { - printUsage(argv[0]); - return 2; - } - } else { - printUsage(argv[0]); - return 2; - } - } - bool succeeded; - if (subrunner.testCount() > 0) { - succeeded = subrunner.runAllTest(subrunner.testCount() > 1); - } else { - succeeded = runAllTest(true); - } - return succeeded ? 0 : 1; -} - -#if defined(_MSC_VER) && defined(_DEBUG) -// Hook MSVCRT assertions to prevent dialog from appearing -static int -msvcrtSilentReportHook(int reportType, char* message, int* /*returnValue*/) { - // The default CRT handling of error and assertion is to display - // an error dialog to the user. - // Instead, when an error or an assertion occurs, we force the - // application to terminate using abort() after display - // the message on stderr. - if (reportType == _CRT_ERROR || reportType == _CRT_ASSERT) { - // calling abort() cause the ReportHook to be called - // The following is used to detect this case and let's the - // error handler fallback on its default behaviour ( - // display a warning message) - static volatile bool isAborting = false; - if (isAborting) { - return TRUE; - } - isAborting = true; - - fprintf(stderr, "CRT Error/Assert:\n%s\n", message); - fflush(stderr); - abort(); - } - // Let's other reportType (_CRT_WARNING) be handled as they would by default - return FALSE; -} -#endif // if defined(_MSC_VER) - -void Runner::preventDialogOnCrash() { -#if defined(_MSC_VER) && defined(_DEBUG) - // Install a hook to prevent MSVCRT error and assertion from - // popping a dialog - // This function a NO-OP in release configuration - // (which cause warning since msvcrtSilentReportHook is not referenced) - _CrtSetReportHook(&msvcrtSilentReportHook); -#endif // if defined(_MSC_VER) - -// @todo investiguate this handler (for buffer overflow) -// _set_security_error_handler - -#if defined(_WIN32) - // Prevents the system from popping a dialog for debugging if the - // application fails due to invalid memory access. - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); -#endif // if defined(_WIN32) -} - -void Runner::printUsage(const char* appName) { - printf("Usage: %s [options]\n" - "\n" - "If --test is not specified, then all the test cases be run.\n" - "\n" - "Valid options:\n" - "--list-tests: print the name of all test cases on the standard\n" - " output and exit.\n" - "--test TESTNAME: executes the test case with the specified name.\n" - " May be repeated.\n" - "--test-auto: prevent dialog prompting for debugging on crash.\n", - appName); -} - -// Assertion functions -// ////////////////////////////////////////////////////////////////// - -TestResult& checkStringEqual(TestResult& result, - const std::string& expected, - const std::string& actual, - const char* file, - unsigned int line, - const char* expr) { - if (expected != actual) { - result.addFailure(file, line, expr); - result << "Expected: '" << expected << "'\n"; - result << "Actual : '" << actual << "'"; - } - return result; -} - -} // namespace JsonTest diff --git a/3rdparty/jsoncpp/src/test_lib_json/jsontest.h b/3rdparty/jsoncpp/src/test_lib_json/jsontest.h deleted file mode 100644 index d6b7cf386a2..00000000000 --- a/3rdparty/jsoncpp/src/test_lib_json/jsontest.h +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// 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 - -#ifndef JSONTEST_H_INCLUDED -#define JSONTEST_H_INCLUDED - -#include <json/config.h> -#include <json/value.h> -#include <json/writer.h> -#include <stdio.h> -#include <deque> -#include <sstream> -#include <string> - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// Mini Unit Testing framework -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -/** \brief Unit testing framework. - * \warning: all assertions are non-aborting, test case execution will continue - * even if an assertion namespace. - * This constraint is for portability: the framework needs to compile - * on Visual Studio 6 and must not require exception usage. - */ -namespace JsonTest { - -class Failure { -public: - const char* file_; - unsigned int line_; - std::string expr_; - std::string message_; - unsigned int nestingLevel_; -}; - -/// Context used to create the assertion callstack on failure. -/// Must be a POD to allow inline initialisation without stepping -/// into the debugger. -struct PredicateContext { - typedef unsigned int Id; - Id id_; - const char* file_; - unsigned int line_; - const char* expr_; - PredicateContext* next_; - /// Related Failure, set when the PredicateContext is converted - /// into a Failure. - Failure* failure_; -}; - -class TestResult { -public: - TestResult(); - - /// \internal Implementation detail for assertion macros - /// Not encapsulated to prevent step into when debugging failed assertions - /// Incremented by one on assertion predicate entry, decreased by one - /// by addPredicateContext(). - PredicateContext::Id predicateId_; - - /// \internal Implementation detail for predicate macros - PredicateContext* predicateStackTail_; - - void setTestName(const std::string& name); - - /// Adds an assertion failure. - TestResult& - addFailure(const char* file, unsigned int line, const char* expr = 0); - - /// Removes the last PredicateContext added to the predicate stack - /// chained list. - /// Next messages will be targed at the PredicateContext that was removed. - TestResult& popPredicateContext(); - - bool failed() const; - - void printFailure(bool printTestName) const; - - // Generic operator that will work with anything ostream can deal with. - template <typename T> TestResult& operator<<(const T& value) { - std::ostringstream oss; - oss.precision(16); - oss.setf(std::ios_base::floatfield); - oss << value; - return addToLastFailure(oss.str()); - } - - // Specialized versions. - TestResult& operator<<(bool value); - // std:ostream does not support 64bits integers on all STL implementation - TestResult& operator<<(Json::Int64 value); - TestResult& operator<<(Json::UInt64 value); - -private: - TestResult& addToLastFailure(const std::string& message); - unsigned int getAssertionNestingLevel() const; - /// Adds a failure or a predicate context - void addFailureInfo(const char* file, - unsigned int line, - const char* expr, - unsigned int nestingLevel); - static std::string indentText(const std::string& text, - const std::string& indent); - - typedef std::deque<Failure> Failures; - Failures failures_; - std::string name_; - PredicateContext rootPredicateNode_; - PredicateContext::Id lastUsedPredicateId_; - /// Failure which is the target of the messages added using operator << - Failure* messageTarget_; -}; - -class TestCase { -public: - TestCase(); - - virtual ~TestCase(); - - void run(TestResult& result); - - virtual const char* testName() const = 0; - -protected: - TestResult* result_; - -private: - virtual void runTestCase() = 0; -}; - -/// Function pointer type for TestCase factory -typedef TestCase* (*TestCaseFactory)(); - -class Runner { -public: - Runner(); - - /// Adds a test to the suite - Runner& add(TestCaseFactory factory); - - /// Runs test as specified on the command-line - /// If no command-line arguments are provided, run all tests. - /// If --list-tests is provided, then print the list of all test cases - /// If --test <testname> is provided, then run test testname. - int runCommandLine(int argc, const char* argv[]) const; - - /// Runs all the test cases - bool runAllTest(bool printSummary) const; - - /// Returns the number of test case in the suite - unsigned int testCount() const; - - /// Returns the name of the test case at the specified index - std::string testNameAt(unsigned int index) const; - - /// Runs the test case at the specified index using the specified TestResult - void runTestAt(unsigned int index, TestResult& result) const; - - static void printUsage(const char* appName); - -private: // prevents copy construction and assignment - Runner(const Runner& other); - Runner& operator=(const Runner& other); - -private: - void listTests() const; - bool testIndex(const std::string& testName, unsigned int& index) const; - static void preventDialogOnCrash(); - -private: - typedef std::deque<TestCaseFactory> Factories; - Factories tests_; -}; - -template <typename T, typename U> -TestResult& checkEqual(TestResult& result, - T expected, - U actual, - const char* file, - unsigned int line, - const char* expr) { - if (static_cast<U>(expected) != actual) { - result.addFailure(file, line, expr); - result << "Expected: " << static_cast<U>(expected) << "\n"; - result << "Actual : " << actual; - } - return result; -} - -TestResult& checkStringEqual(TestResult& result, - const std::string& expected, - const std::string& actual, - const char* file, - unsigned int line, - const char* expr); - -} // namespace JsonTest - -/// \brief Asserts that the given expression is true. -/// JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y; -/// JSONTEST_ASSERT( x == y ); -#define JSONTEST_ASSERT(expr) \ - if (expr) { \ - } else \ - result_->addFailure(__FILE__, __LINE__, #expr) - -/// \brief Asserts that the given predicate is true. -/// The predicate may do other assertions and be a member function of the -/// fixture. -#define JSONTEST_ASSERT_PRED(expr) \ - { \ - JsonTest::PredicateContext _minitest_Context = { \ - result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL \ - }; \ - result_->predicateStackTail_->next_ = &_minitest_Context; \ - result_->predicateId_ += 1; \ - result_->predicateStackTail_ = &_minitest_Context; \ - (expr); \ - result_->popPredicateContext(); \ - } - -/// \brief Asserts that two values are equals. -#define JSONTEST_ASSERT_EQUAL(expected, actual) \ - JsonTest::checkEqual(*result_, \ - expected, \ - actual, \ - __FILE__, \ - __LINE__, \ - #expected " == " #actual) - -/// \brief Asserts that two values are equals. -#define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \ - JsonTest::checkStringEqual(*result_, \ - std::string(expected), \ - std::string(actual), \ - __FILE__, \ - __LINE__, \ - #expected " == " #actual) - -/// \brief Asserts that a given expression throws an exception -#define JSONTEST_ASSERT_THROWS(expr) \ - { \ - bool _threw = false; \ - try { \ - expr; \ - } \ - catch (...) { \ - _threw = true; \ - } \ - if (!_threw) \ - result_->addFailure( \ - __FILE__, __LINE__, "expected exception thrown: " #expr); \ - } - -/// \brief Begin a fixture test case. -#define JSONTEST_FIXTURE(FixtureType, name) \ - class Test##FixtureType##name : public FixtureType { \ - public: \ - static JsonTest::TestCase* factory() { \ - return new Test##FixtureType##name(); \ - } \ - \ - public: /* overidden from TestCase */ \ - virtual const char* testName() const { return #FixtureType "/" #name; } \ - virtual void runTestCase(); \ - }; \ - \ - void Test##FixtureType##name::runTestCase() - -#define JSONTEST_FIXTURE_FACTORY(FixtureType, name) \ - &Test##FixtureType##name::factory - -#define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name) \ - (runner).add(JSONTEST_FIXTURE_FACTORY(FixtureType, name)) - -#endif // ifndef JSONTEST_H_INCLUDED diff --git a/3rdparty/jsoncpp/src/test_lib_json/main.cpp b/3rdparty/jsoncpp/src/test_lib_json/main.cpp deleted file mode 100644 index 0d4284e5373..00000000000 --- a/3rdparty/jsoncpp/src/test_lib_json/main.cpp +++ /dev/null @@ -1,2406 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// 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 - -#include "jsontest.h" -#include <json/config.h> -#include <json/json.h> -#include <cstring> - -// 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 + - Json::Int64(value & 1); -} -#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - -struct ValueTest : JsonTest::TestCase { - Json::Value null_; - Json::Value emptyArray_; - Json::Value emptyObject_; - Json::Value integer_; - Json::Value unsignedInteger_; - Json::Value smallUnsignedInteger_; - Json::Value real_; - Json::Value float_; - Json::Value array1_; - Json::Value object1_; - Json::Value emptyString_; - Json::Value string1_; - Json::Value string_; - Json::Value true_; - Json::Value false_; - - ValueTest() - : emptyArray_(Json::arrayValue), emptyObject_(Json::objectValue), - integer_(123456789), unsignedInteger_(34567890u), - smallUnsignedInteger_(Json::Value::UInt(Json::Value::maxInt)), - real_(1234.56789), float_(0.00390625f), emptyString_(""), string1_("a"), - string_("sometext with space"), true_(true), false_(false) { - array1_.append(1234); - object1_["id"] = 1234; - } - - struct IsCheck { - /// Initialize all checks to \c false by default. - IsCheck(); - - bool isObject_; - bool isArray_; - bool isBool_; - bool isString_; - bool isNull_; - - bool isInt_; - bool isInt64_; - bool isUInt_; - bool isUInt64_; - bool isIntegral_; - bool isDouble_; - bool isNumeric_; - }; - - 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 std::string normalizeFloatingPointStr(const std::string& s); -}; - -std::string ValueTest::normalizeFloatingPointStr(const std::string& s) { - std::string::size_type index = s.find_last_of("eE"); - if (index != std::string::npos) { - std::string::size_type hasSign = - (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - std::string::size_type exponentStartIndex = index + 1 + hasSign; - std::string normalized = s.substr(0, exponentStartIndex); - std::string::size_type indexDigit = - s.find_first_not_of('0', exponentStartIndex); - std::string exponent = "0"; - if (indexDigit != - std::string::npos) // There is an exponent different from 0 - { - exponent = s.substr(indexDigit); - } - return normalized + exponent; - } - return s; -} - -JSONTEST_FIXTURE(ValueTest, checkNormalizeFloatingPointStr) { - JSONTEST_ASSERT_STRING_EQUAL("0.0", normalizeFloatingPointStr("0.0")); - JSONTEST_ASSERT_STRING_EQUAL("0e0", normalizeFloatingPointStr("0e0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0", normalizeFloatingPointStr("1234.0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0e0", - normalizeFloatingPointStr("1234.0e0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0e+0", - normalizeFloatingPointStr("1234.0e+0")); - JSONTEST_ASSERT_STRING_EQUAL("1234e-1", normalizeFloatingPointStr("1234e-1")); - JSONTEST_ASSERT_STRING_EQUAL("1234e10", normalizeFloatingPointStr("1234e10")); - JSONTEST_ASSERT_STRING_EQUAL("1234e10", - normalizeFloatingPointStr("1234e010")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+10", - normalizeFloatingPointStr("1234e+010")); - JSONTEST_ASSERT_STRING_EQUAL("1234e-10", - normalizeFloatingPointStr("1234e-010")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+100", - normalizeFloatingPointStr("1234e+100")); - JSONTEST_ASSERT_STRING_EQUAL("1234e-100", - normalizeFloatingPointStr("1234e-100")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+1", - normalizeFloatingPointStr("1234e+001")); -} - -JSONTEST_FIXTURE(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_FIXTURE(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 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); -} - -JSONTEST_FIXTURE(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]); - - // Access through non-const reference - JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_[index0]); - JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_[0]); - - 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(ValueTest, arrayIssue252) -{ - int count = 5; - Json::Value root; - Json::Value item; - root["array"] = Json::Value::nullRef; - 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(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::null, null_); -} - -JSONTEST_FIXTURE(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(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(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", 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", 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", - normalizeFloatingPointStr(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", - normalizeFloatingPointStr(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(uint64ToDouble(Json::UInt64(1) << 63)), - val.asFloat()); - JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("9.2233720368547758e+18", - normalizeFloatingPointStr(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). Note that kint64min *is* exactly - // representable as a double. - val = Json::Value(double(kint64min)); - - JSONTEST_ASSERT_EQUAL(Json::realValue, 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(-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(val.asString())); - - // 10^19 - const Json::UInt64 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(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(val.asString())); -#endif -} - -JSONTEST_FIXTURE(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(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(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(val.asString())); - - val = Json::Value(1.2345678901234); - JSONTEST_ASSERT_STRING_EQUAL("1.2345678901234001", - normalizeFloatingPointStr(val.asString())); - - // A 16-digit floating point number. - val = Json::Value(2199023255552000.0f); - JSONTEST_ASSERT_EQUAL(float(2199023255552000), val.asFloat()); - JSONTEST_ASSERT_STRING_EQUAL("2199023255552000", - normalizeFloatingPointStr(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(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(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() - : isObject_(false), isArray_(false), isBool_(false), isString_(false), - isNull_(false), isInt_(false), isInt64_(false), isUInt_(false), - isUInt64_(false), isIntegral_(false), isDouble_(false), - isNumeric_(false) {} - -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(ValueTest, compareNull) { - JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value(), Json::Value())); -} - -JSONTEST_FIXTURE(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(ValueTest, compareUInt) { - JSONTEST_ASSERT_PRED(checkIsLess(0u, 10u)); - JSONTEST_ASSERT_PRED(checkIsLess(0u, Json::Value::maxUInt)); - JSONTEST_ASSERT_PRED(checkIsEqual(10u, 10u)); -} - -JSONTEST_FIXTURE(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(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(ValueTest, compareBoolean) { - JSONTEST_ASSERT_PRED(checkIsLess(false, true)); - JSONTEST_ASSERT_PRED(checkIsEqual(false, false)); - JSONTEST_ASSERT_PRED(checkIsEqual(true, true)); -} - -JSONTEST_FIXTURE(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, 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(l2bArray, Json::Value(l2bArray))); -} - -JSONTEST_FIXTURE(ValueTest, compareObject) { - // object compare size then content - Json::Value emptyObject(Json::objectValue); - Json::Value l1aObject; - l1aObject["key1"] = 0; - Json::Value l1bObject; - l1aObject["key1"] = 10; - Json::Value l2aObject; - l2aObject["key1"] = 0; - l2aObject["key2"] = 0; - JSONTEST_ASSERT_PRED(checkIsLess(emptyObject, l1aObject)); - JSONTEST_ASSERT_PRED(checkIsLess(emptyObject, l2aObject)); - JSONTEST_ASSERT_PRED(checkIsLess(l1aObject, l2aObject)); - JSONTEST_ASSERT_PRED(checkIsEqual(emptyObject, Json::Value(emptyObject))); - JSONTEST_ASSERT_PRED(checkIsEqual(l1aObject, Json::Value(l1aObject))); - JSONTEST_ASSERT_PRED(checkIsEqual(l2aObject, Json::Value(l2aObject))); -} - -JSONTEST_FIXTURE(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))); -} - -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(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(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(ValueTest, StaticString) { - char mutant[] = "hello"; - Json::StaticString ss(mutant); - std::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(ValueTest, CommentBefore) { - Json::Value val; // fill val - val.setComment(std::string("// this comment should appear before"), Json::commentBefore); - Json::StreamWriterBuilder wbuilder; - wbuilder.settings_["commentStyle"] = "All"; - { - char const expected[] = "// this comment should appear before\nnull"; - std::string result = Json::writeString(wbuilder, val); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); - std::string res2 = val.toStyledString(); - std::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\""; - std::string result = Json::writeString(wbuilder, val); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); - std::string res2 = val.toStyledString(); - std::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\""; - std::string result = Json::writeString(wbuilder, val); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); - std::string res2 = val.toStyledString(); - std::string exp2 = ""; - exp2 += expected; - exp2 += "\n"; - JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); - } -} - -JSONTEST_FIXTURE(ValueTest, zeroes) { - char const cstr[] = "h\0i"; - std::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(ValueTest, zeroesInKeys) { - char const cstr[] = "h\0i"; - std::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::nullRef).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::nullRef).asString()); - } -} - -struct WriterTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) { - Json::FastWriter writer; - Json::Value nullValue; - JSONTEST_ASSERT(writer.write(nullValue) == "null\n"); - - writer.dropNullPlaceholders(); - JSONTEST_ASSERT(writer.write(nullValue) == "\n"); -} - -struct StreamWriterTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(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) == ""); -} - -JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { - std::string binary("hi", 3); // include trailing 0 - JSONTEST_ASSERT_EQUAL(3, binary.length()); - std::string expected("\"hi\\u0000\""); // unicoded zero - Json::StreamWriterBuilder b; - { - Json::Value root; - root = binary; - JSONTEST_ASSERT_STRING_EQUAL(binary, root.asString()); - std::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()); - std::string out = Json::writeString(b, root["top"]); - JSONTEST_ASSERT_STRING_EQUAL(expected, out); - } -} - -struct ReaderTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" : \"value\" }", root); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0); - JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0); -} - -JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " - "null, \"false\" : false }", - root); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0); - JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0); - JSONTEST_ASSERT(root["property"].getOffsetStart() == 15); - JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34); - JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16); - JSONTEST_ASSERT(root["property"][0].getOffsetLimit() == 23); - JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25); - JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33); - JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44); - JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 76); - JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57); - JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 60); - JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 71); - JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 75); - JSONTEST_ASSERT(root["null"].getOffsetStart() == 87); - JSONTEST_ASSERT(root["null"].getOffsetLimit() == 91); - JSONTEST_ASSERT(root["false"].getOffsetStart() == 103); - JSONTEST_ASSERT(root["false"].getOffsetLimit() == 108); - JSONTEST_ASSERT(root.getOffsetStart() == 0); - JSONTEST_ASSERT(root.getOffsetLimit() == 110); -} - -JSONTEST_FIXTURE(ReaderTest, parseWithOneError) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" :: \"value\" }", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 15\n Syntax error: value, object or array " - "expected.\n"); - std::vector<Json::Reader::StructuredError> errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 14); - JSONTEST_ASSERT(errors.at(0).offset_limit == 15); - JSONTEST_ASSERT(errors.at(0).message == - "Syntax error: value, object or array expected."); -} - -JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"pr佐藤erty\" :: \"value\" }", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 19\n Syntax error: value, object or array " - "expected.\n"); - std::vector<Json::Reader::StructuredError> errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 18); - JSONTEST_ASSERT(errors.at(0).offset_limit == 19); - JSONTEST_ASSERT(errors.at(0).message == - "Syntax error: value, object or array expected."); -} - -JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" : \"v\\alue\" }", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 16\n Bad escape sequence in string\nSee " - "Line 1, Column 20 for detail.\n"); - std::vector<Json::Reader::StructuredError> errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 15); - JSONTEST_ASSERT(errors.at(0).offset_limit == 23); - JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string"); -} - -struct CharReaderTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { - Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - Json::Value root; - char const doc[] = "{ \"property\" : \"value\" }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.size() == 0); - delete reader; -} - -JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { - Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - Json::Value root; - char const doc[] = - "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " - "null, \"false\" : false }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.size() == 0); - delete reader; -} - -JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { - Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - Json::Value root; - char const doc[] = - "{ \"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"); - delete reader; -} - -JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { - Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); - std::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"); - delete reader; -} - -JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { - Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - Json::Value root; - char const doc[] = - "{ \"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"); - delete reader; -} - -JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { - Json::CharReaderBuilder b; - Json::Value root; - char const doc[] = - "{ \"property\" : \"value\" }"; - { - b.settings_["stackLimit"] = 2; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL("value", root["property"]); - delete reader; - } - { - b.settings_["stackLimit"] = 1; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - JSONTEST_ASSERT_THROWS(reader->parse( - doc, doc + std::strlen(doc), - &root, &errs)); - delete reader; - } -} - -struct CharReaderStrictModeTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) { - Json::CharReaderBuilder b; - Json::Value root; - char const doc[] = - "{ \"property\" : \"value\", \"key\" : \"val1\", \"key\" : \"val2\" }"; - { - b.strictMode(&b.settings_); - Json::CharReader* reader(b.newCharReader()); - std::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 - delete reader; - } -} -struct CharReaderFailIfExtraTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { - // This is interpretted as a string value followed by a colon. - Json::CharReaderBuilder b; - Json::Value root; - char const doc[] = - " \"property\" : \"value\" }"; - { - b.settings_["failIfExtra"] = false; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL("property", root); - delete reader; - } - { - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - std::string errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL(errs, - "* Line 1, Column 13\n" - " Extra non-whitespace after JSON value.\n"); - JSONTEST_ASSERT_EQUAL("property", root); - delete reader; - } - { - b.settings_["failIfExtra"] = false; - b.strictMode(&b.settings_); - Json::CharReader* reader(b.newCharReader()); - std::string errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL(errs, - "* Line 1, Column 13\n" - " Extra non-whitespace after JSON value.\n"); - JSONTEST_ASSERT_EQUAL("property", root); - delete reader; - } -} -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { - // This is interpretted as an int value followed by a colon. - Json::CharReaderBuilder b; - Json::Value root; - char const doc[] = - "1:2:3"; - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - std::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()); - delete reader; -} -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) { - Json::CharReaderBuilder b; - Json::Value root; - { - char const doc[] = - "{ \"property\" : \"value\" } //trailing\n//comment\n"; - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - std::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"]); - delete reader; - } -} -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { - Json::CharReaderBuilder b; - Json::Value root; - char const doc[] = - "[ \"property\" , \"value\" ] //trailing\n//comment\n"; - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - std::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]); - delete reader; -} -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { - Json::CharReaderBuilder b; - Json::Value root; - char const doc[] = - " true /*trailing\ncomment*/"; - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - std::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()); - delete reader; -} -struct CharReaderAllowDropNullTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { - Json::CharReaderBuilder b; - b.settings_["allowDroppedNullPlaceholders"] = true; - Json::Value root; - std::string errs; - Json::CharReader* reader(b.newCharReader()); - { - char const doc[] = "{\"a\":,\"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(Json::nullValue, root.get("a", true)); - } - { - char const doc[] = "{\"a\":}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(1u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::nullValue, root.get("a", true)); - } - { - char const doc[] = "[]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL(0u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root); - } - { - char const doc[] = "[null]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL(1u, root.size()); - } - { - char const doc[] = "[,]"; - 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()); - } - { - char const doc[] = "[,,,]"; - 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()); - } - { - char const doc[] = "[null,]"; - 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()); - } - { - char const doc[] = "[,null]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL(2u, root.size()); - } - { - char const doc[] = "[,,]"; - 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()); - } - { - char const doc[] = "[null,,]"; - 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()); - } - { - char const doc[] = "[,null,]"; - 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()); - } - { - char const doc[] = "[,,null]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL(3u, root.size()); - } - { - char const doc[] = "[[],,,]"; - 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()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[0u]); - } - { - char const doc[] = "[,[],,]"; - 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()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[1u]); - } - { - char const doc[] = "[,,,[]]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL(4u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[3u]); - } - delete reader; -} - -struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { - Json::CharReaderBuilder b; - b.settings_["allowSingleQuotes"] = true; - Json::Value root; - std::string errs; - Json::CharReader* 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()); - } - delete reader; -} - -struct CharReaderAllowZeroesTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { - Json::CharReaderBuilder b; - b.settings_["allowSingleQuotes"] = true; - Json::Value root; - std::string errs; - Json::CharReader* 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()); - } - delete reader; -} - -struct BuilderTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(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 IteratorTest : JsonTest::TestCase {}; - -JSONTEST_FIXTURE(IteratorTest, distance) { - Json::Value json; - json["k1"] = "a"; - json["k2"] = "b"; - int dist = 0; - std::string str; - for (Json::ValueIterator it = json.begin(); it != json.end(); ++it) { - dist = it - json.begin(); - str = it->asString().c_str(); - } - JSONTEST_ASSERT_EQUAL(1, dist); - JSONTEST_ASSERT_STRING_EQUAL("b", str); -} - -JSONTEST_FIXTURE(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_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_EQUAL(-1, it.index()); - ++it; - JSONTEST_ASSERT(it == json.end()); -} - -JSONTEST_FIXTURE(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()); -} - -int main(int argc, const char* argv[]) { - JsonTest::Runner runner; - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, memberCount); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, objects); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrays); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayIssue252); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, null); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, strings); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, bools); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, integers); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nonIntegers); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareNull); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareInt); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareUInt); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareDouble); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareString); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareBoolean); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore); - //JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys); - - JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes); - - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithNoErrors); - JSONTEST_REGISTER_FIXTURE( - runner, ReaderTest, parseWithNoErrorsTestingOffsets); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseChineseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithDetailError); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithNoErrors); - JSONTEST_REGISTER_FIXTURE( - runner, CharReaderTest, parseWithNoErrorsTestingOffsets); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseChineseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithDetailError); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithStackLimit); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderStrictModeTest, dupKeys); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue164); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue107); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterObject); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterArray); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterBool); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowSingleQuotesTest, issue182); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowZeroesTest, issue176); - - JSONTEST_REGISTER_FIXTURE(runner, BuilderTest, settings); - - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance); - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, names); - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes); - - return runner.runCommandLine(argc, argv); -} diff --git a/3rdparty/jsoncpp/src/test_lib_json/sconscript b/3rdparty/jsoncpp/src/test_lib_json/sconscript deleted file mode 100644 index 915fd01c0a3..00000000000 --- a/3rdparty/jsoncpp/src/test_lib_json/sconscript +++ /dev/null @@ -1,10 +0,0 @@ -Import( 'env_testing buildUnitTests' ) - -buildUnitTests( env_testing, Split( """ - main.cpp - jsontest.cpp - """ ), - 'test_lib_json' ) - -# For 'check' to work, 'libs' must be built first. -env_testing.Depends('test_lib_json', '#libs') |