summaryrefslogtreecommitdiff
path: root/json
diff options
context:
space:
mode:
Diffstat (limited to 'json')
-rw-r--r--json/json-forwards.h137
-rw-r--r--json/json.h498
-rw-r--r--json/jsoncpp.cpp1705
3 files changed, 1291 insertions, 1049 deletions
diff --git a/json/json-forwards.h b/json/json-forwards.h
index a20d79d9..4dad2056 100644
--- a/json/json-forwards.h
+++ b/json/json-forwards.h
@@ -1,4 +1,4 @@
-/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).
+/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json-forwards.h"
/// This header provides forward declaration for all JsonCpp types.
@@ -11,13 +11,13 @@ The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
-released under the terms of the MIT License (see below).
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
+The JsonCpp Authors, and is released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the
@@ -32,7 +32,7 @@ described in clear, concise terms at:
The full text of the MIT License follows:
========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur
+Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -73,9 +73,9 @@ license you like.
-#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED
-# define JSON_FORWARD_AMALGATED_H_INCLUDED
-/// If defined, indicates that the source file is amalgated
+#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
+# define JSON_FORWARD_AMALGAMATED_H_INCLUDED
+/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
#define JSON_IS_AMALGAMATION
@@ -83,7 +83,7 @@ license you like.
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -91,8 +91,8 @@ license you like.
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <stddef.h>
-#include <string> //typedef String
#include <stdint.h> //typedef int64_t, uint64_t
+#include <string> //typedef String
/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
@@ -110,9 +110,9 @@ license you like.
#define JSON_USE_EXCEPTION 1
#endif
-/// If defined, indicates that the source file is amalgated
+/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
-/// Remarks: it is automatically defined in the generated amalgated header.
+/// Remarks: it is automatically defined in the generated amalgamated header.
// #define JSON_IS_AMALGAMATION
#ifdef JSON_IN_CPPTL
@@ -145,40 +145,47 @@ license you like.
// #define JSON_NO_INT64 1
#if defined(_MSC_VER) // MSVC
-# if _MSC_VER <= 1200 // MSVC 6
- // Microsoft Visual Studio 6 only support conversion from __int64 to double
- // (no conversion from unsigned __int64).
-# define JSON_USE_INT64_DOUBLE_CONVERSION 1
- // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
- // characters in the debug information)
- // All projects I've ever seen with VS6 were using this globally (not bothering
- // with pragma push/pop).
-# pragma warning(disable : 4786)
-# endif // MSVC 6
+#if _MSC_VER <= 1200 // MSVC 6
+// Microsoft Visual Studio 6 only support conversion from __int64 to double
+// (no conversion from unsigned __int64).
+#define JSON_USE_INT64_DOUBLE_CONVERSION 1
+// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
+// characters in the debug information)
+// All projects I've ever seen with VS6 were using this globally (not bothering
+// with pragma push/pop).
+#pragma warning(disable : 4786)
+#endif // MSVC 6
-# if _MSC_VER >= 1500 // MSVC 2008
- /// Indicates that the following function is deprecated.
-# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
-# endif
+#if _MSC_VER >= 1500 // MSVC 2008
+ /// Indicates that the following function is deprecated.
+#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
+#endif
#endif // defined(_MSC_VER)
-// In c++11 the override keyword allows you to explicity define that a function
+// In c++11 the override keyword allows you to explicitly define that a function
// is intended to override the base-class version. This makes the code more
-// managable and fixes a set of common hard-to-find bugs.
-
+// manageable and fixes a set of common hard-to-find bugs.
#if __cplusplus >= 201103L
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OVERRIDE override
+#define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OP_EXPLICIT explicit
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT throw()
+#define JSONCPP_OVERRIDE override
+#define JSONCPP_NOEXCEPT throw()
+#if _MSC_VER >= 1800 // MSVC 2013
+#define JSONCPP_OP_EXPLICIT explicit
+#else
+#define JSONCPP_OP_EXPLICIT
+#endif
#elif defined(_MSC_VER) && _MSC_VER >= 1900
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OVERRIDE override
+#define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OP_EXPLICIT explicit
#else
-# define JSONCPP_OVERRIDE
-# define JSONCPP_NOEXCEPT throw()
+#define JSONCPP_OVERRIDE
+#define JSONCPP_NOEXCEPT throw()
+#define JSONCPP_OP_EXPLICIT
#endif
#ifndef JSON_HAS_RVALUE_REFERENCES
@@ -190,12 +197,12 @@ license you like.
#ifdef __clang__
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // has_feature
+#endif // has_feature
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // GXX_EXPERIMENTAL
+#endif // GXX_EXPERIMENTAL
#endif // __clang__ || __GNUC__
@@ -206,12 +213,15 @@ license you like.
#endif
#ifdef __clang__
+#if __has_extension(attribute_deprecated_with_message)
+#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
+#endif
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
-# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
-# endif // GNUC version
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
+#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
+#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
+#endif // GNUC version
#endif // __clang__ || __GNUC__
#if !defined(JSONCPP_DEPRECATED)
@@ -219,16 +229,16 @@ license you like.
#endif // if !defined(JSONCPP_DEPRECATED)
#if __GNUC__ >= 6
-# define JSON_USE_INT64_DOUBLE_CONVERSION 1
+#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
#if !defined(JSON_IS_AMALGAMATION)
-# include "version.h"
+#include "version.h"
-# if JSONCPP_USING_SECURE_MEMORY
-# include "allocator.h" //typedef Allocator
-# endif
+#if JSONCPP_USING_SECURE_MEMORY
+#include "allocator.h" //typedef Allocator
+#endif
#endif // if !defined(JSON_IS_AMALGAMATION)
@@ -245,27 +255,30 @@ typedef unsigned int LargestUInt;
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else // if defined(_MSC_VER) // Other platforms, use long long
-
typedef int64_t Int64;
typedef uint64_t UInt64;
-
-#endif // if defined(_MSC_VER)
+#endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
#if JSONCPP_USING_SECURE_MEMORY
-#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>
-#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_ISTREAM std::istream
+#define JSONCPP_STRING \
+ std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
+#define JSONCPP_OSTRINGSTREAM \
+ std::basic_ostringstream<char, std::char_traits<char>, \
+ Json::SecureAllocator<char> >
+#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char> >
+#define JSONCPP_ISTRINGSTREAM \
+ std::basic_istringstream<char, std::char_traits<char>, \
+ Json::SecureAllocator<char> >
+#define JSONCPP_ISTREAM std::istream
#else
-#define JSONCPP_STRING std::string
+#define JSONCPP_STRING std::string
#define JSONCPP_OSTRINGSTREAM std::ostringstream
-#define JSONCPP_OSTREAM std::ostream
+#define JSONCPP_OSTREAM std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
-#define JSONCPP_ISTREAM std::istream
+#define JSONCPP_ISTREAM std::istream
#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json
@@ -284,7 +297,7 @@ typedef UInt64 LargestUInt;
// Beginning of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -330,4 +343,4 @@ class ValueConstIterator;
-#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED
+#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
diff --git a/json/json.h b/json/json.h
index 1561a120..51a38e65 100644
--- a/json/json.h
+++ b/json/json.h
@@ -1,4 +1,4 @@
-/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).
+/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json.h"
// //////////////////////////////////////////////////////////////////////
@@ -10,13 +10,13 @@ The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
-released under the terms of the MIT License (see below).
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
+The JsonCpp Authors, and is released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the
@@ -31,7 +31,7 @@ described in clear, concise terms at:
The full text of the MIT License follows:
========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur
+Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -72,9 +72,9 @@ license you like.
-#ifndef JSON_AMALGATED_H_INCLUDED
-# define JSON_AMALGATED_H_INCLUDED
-/// If defined, indicates that the source file is amalgated
+#ifndef JSON_AMALGAMATED_H_INCLUDED
+# define JSON_AMALGAMATED_H_INCLUDED
+/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
#define JSON_IS_AMALGAMATION
@@ -85,15 +85,16 @@ license you like.
// DO NOT EDIT. This file (and "version") is generated by CMake.
// Run CMake configure step to update it.
#ifndef JSON_VERSION_H_INCLUDED
-# define JSON_VERSION_H_INCLUDED
+#define JSON_VERSION_H_INCLUDED
-# define JSONCPP_VERSION_STRING "1.8.0"
-# define JSONCPP_VERSION_MAJOR 1
-# define JSONCPP_VERSION_MINOR 8
-# define JSONCPP_VERSION_PATCH 0
-
-# define JSONCPP_VERSION_QUALIFIER
-# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
+#define JSONCPP_VERSION_STRING "1.8.4"
+#define JSONCPP_VERSION_MAJOR 1
+#define JSONCPP_VERSION_MINOR 8
+#define JSONCPP_VERSION_PATCH 4
+#define JSONCPP_VERSION_QUALIFIER
+#define JSONCPP_VERSION_HEXA \
+ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
+ (JSONCPP_VERSION_PATCH << 8))
#ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY
@@ -117,7 +118,7 @@ license you like.
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -125,9 +126,8 @@ license you like.
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <stddef.h>
-
-#include <string> //typedef String
#include <stdint.h> //typedef int64_t, uint64_t
+#include <string> //typedef String
/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
@@ -145,9 +145,9 @@ license you like.
#define JSON_USE_EXCEPTION 1
#endif
-/// If defined, indicates that the source file is amalgated
+/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
-/// Remarks: it is automatically defined in the generated amalgated header.
+/// Remarks: it is automatically defined in the generated amalgamated header.
// #define JSON_IS_AMALGAMATION
#ifdef JSON_IN_CPPTL
@@ -180,40 +180,47 @@ license you like.
// #define JSON_NO_INT64 1
#if defined(_MSC_VER) // MSVC
-# if _MSC_VER <= 1200 // MSVC 6
- // Microsoft Visual Studio 6 only support conversion from __int64 to double
- // (no conversion from unsigned __int64).
-# define JSON_USE_INT64_DOUBLE_CONVERSION 1
- // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
- // characters in the debug information)
- // All projects I've ever seen with VS6 were using this globally (not bothering
- // with pragma push/pop).
-# pragma warning(disable : 4786)
-# endif // MSVC 6
+#if _MSC_VER <= 1200 // MSVC 6
+// Microsoft Visual Studio 6 only support conversion from __int64 to double
+// (no conversion from unsigned __int64).
+#define JSON_USE_INT64_DOUBLE_CONVERSION 1
+// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
+// characters in the debug information)
+// All projects I've ever seen with VS6 were using this globally (not bothering
+// with pragma push/pop).
+#pragma warning(disable : 4786)
+#endif // MSVC 6
-# if _MSC_VER >= 1500 // MSVC 2008
- /// Indicates that the following function is deprecated.
-# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
-# endif
+#if _MSC_VER >= 1500 // MSVC 2008
+ /// Indicates that the following function is deprecated.
+#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
+#endif
#endif // defined(_MSC_VER)
-// In c++11 the override keyword allows you to explicity define that a function
+// In c++11 the override keyword allows you to explicitly define that a function
// is intended to override the base-class version. This makes the code more
-// managable and fixes a set of common hard-to-find bugs.
-
+// manageable and fixes a set of common hard-to-find bugs.
#if __cplusplus >= 201103L
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OVERRIDE override
+#define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OP_EXPLICIT explicit
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT throw()
+#define JSONCPP_OVERRIDE override
+#define JSONCPP_NOEXCEPT throw()
+#if _MSC_VER >= 1800 // MSVC 2013
+#define JSONCPP_OP_EXPLICIT explicit
+#else
+#define JSONCPP_OP_EXPLICIT
+#endif
#elif defined(_MSC_VER) && _MSC_VER >= 1900
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OVERRIDE override
+#define JSONCPP_NOEXCEPT noexcept
+#define JSONCPP_OP_EXPLICIT explicit
#else
-# define JSONCPP_OVERRIDE
-# define JSONCPP_NOEXCEPT throw()
+#define JSONCPP_OVERRIDE
+#define JSONCPP_NOEXCEPT throw()
+#define JSONCPP_OP_EXPLICIT
#endif
#ifndef JSON_HAS_RVALUE_REFERENCES
@@ -225,12 +232,12 @@ license you like.
#ifdef __clang__
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // has_feature
+#endif // has_feature
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // GXX_EXPERIMENTAL
+#endif // GXX_EXPERIMENTAL
#endif // __clang__ || __GNUC__
@@ -241,12 +248,15 @@ license you like.
#endif
#ifdef __clang__
+#if __has_extension(attribute_deprecated_with_message)
+#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
+#endif
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
-# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
-# endif // GNUC version
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
+#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
+#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
+#endif // GNUC version
#endif // __clang__ || __GNUC__
#if !defined(JSONCPP_DEPRECATED)
@@ -254,16 +264,16 @@ license you like.
#endif // if !defined(JSONCPP_DEPRECATED)
#if __GNUC__ >= 6
-# define JSON_USE_INT64_DOUBLE_CONVERSION 1
+#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
#if !defined(JSON_IS_AMALGAMATION)
-# include "version.h"
+#include "version.h"
-# if JSONCPP_USING_SECURE_MEMORY
-# include "allocator.h" //typedef Allocator
-# endif
+#if JSONCPP_USING_SECURE_MEMORY
+#include "allocator.h" //typedef Allocator
+#endif
#endif // if !defined(JSON_IS_AMALGAMATION)
@@ -280,27 +290,30 @@ typedef unsigned int LargestUInt;
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else // if defined(_MSC_VER) // Other platforms, use long long
-
typedef int64_t Int64;
typedef uint64_t UInt64;
-
-#endif // if defined(_MSC_VER)
+#endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
#if JSONCPP_USING_SECURE_MEMORY
-#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>
-#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_ISTREAM std::istream
+#define JSONCPP_STRING \
+ std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
+#define JSONCPP_OSTRINGSTREAM \
+ std::basic_ostringstream<char, std::char_traits<char>, \
+ Json::SecureAllocator<char> >
+#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char> >
+#define JSONCPP_ISTRINGSTREAM \
+ std::basic_istringstream<char, std::char_traits<char>, \
+ Json::SecureAllocator<char> >
+#define JSONCPP_ISTREAM std::istream
#else
-#define JSONCPP_STRING std::string
+#define JSONCPP_STRING std::string
#define JSONCPP_OSTRINGSTREAM std::ostringstream
-#define JSONCPP_OSTREAM std::ostream
+#define JSONCPP_OSTREAM std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
-#define JSONCPP_ISTREAM std::istream
+#define JSONCPP_ISTREAM std::istream
#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json
@@ -319,7 +332,7 @@ typedef UInt64 LargestUInt;
// Beginning of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -370,7 +383,7 @@ class ValueConstIterator;
// Beginning of content of file: include/json/features.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -445,7 +458,7 @@ public:
// Beginning of content of file: include/json/value.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -456,9 +469,9 @@ public:
#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <exception>
#include <string>
#include <vector>
-#include <exception>
#ifndef JSON_USE_CPPTL_SMALLMAP
#include <map>
@@ -469,17 +482,17 @@ public:
#include <cpptl/forwards.h>
#endif
-//Conditional NORETURN attribute on the throw functions would:
-// a) suppress false positives from static code analysis
+// Conditional NORETURN attribute on the throw functions would:
+// a) suppress false positives from static code analysis
// b) possibly improve optimization opportunities.
#if !defined(JSONCPP_NORETURN)
-# if defined(_MSC_VER)
-# define JSONCPP_NORETURN __declspec(noreturn)
-# elif defined(__GNUC__)
-# define JSONCPP_NORETURN __attribute__ ((__noreturn__))
-# else
-# define JSONCPP_NORETURN
-# endif
+#if defined(_MSC_VER)
+#define JSONCPP_NORETURN __declspec(noreturn)
+#elif defined(__GNUC__)
+#define JSONCPP_NORETURN __attribute__((__noreturn__))
+#else
+#define JSONCPP_NORETURN
+#endif
#endif
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
@@ -502,7 +515,6 @@ namespace Json {
class JSON_API Exception : public std::exception {
public:
Exception(JSONCPP_STRING const& msg);
-
~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
@@ -513,7 +525,7 @@ protected:
/** Exceptions which the user cannot easily avoid.
*
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
- *
+ *
* \remark derived from Json::Exception
*/
class JSON_API RuntimeError : public Exception {
@@ -524,7 +536,7 @@ public:
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
*
* These are precondition-violations (user bugs) and internal errors (our bugs).
- *
+ *
* \remark derived from Json::Exception
*/
class JSON_API LogicError : public Exception {
@@ -558,6 +570,13 @@ enum CommentPlacement {
numberOfCommentPlacement
};
+/** \brief Type of precision for formatting of real values.
+ */
+enum PrecisionType {
+ significantDigits = 0, ///< we set max number of significant digits in string
+ decimalPlaces ///< we set max number of digits after "." in string
+};
+
//# ifdef JSON_USE_CPPTL
// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
@@ -565,7 +584,7 @@ enum CommentPlacement {
/** \brief Lightweight wrapper to tag static string.
*
- * Value constructor and objectValue member assignement takes advantage of the
+ * Value constructor and objectValue member assignment takes advantage of the
* StaticString and avoid the cost of string duplication when storing the
* string or the member name.
*
@@ -625,6 +644,7 @@ private:
*/
class JSON_API Value {
friend class ValueIteratorBase;
+
public:
typedef std::vector<JSONCPP_STRING> Members;
typedef ValueIterator iterator;
@@ -639,9 +659,13 @@ public:
typedef Json::LargestUInt LargestUInt;
typedef Json::ArrayIndex ArrayIndex;
- static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
- static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
+ // Required for boost integration, e. g. BOOST_TEST
+ typedef std::string value_type;
+ static const Value& null; ///< We regret this reference to a global instance;
+ ///< prefer the simpler Value().
+ static const Value& nullRef; ///< just a kludge for binary-compatibility; same
+ ///< as null
static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
/// Minimum signed integer value that can be stored in a Json::Value.
@@ -667,15 +691,21 @@ public:
static const UInt64 maxUInt64;
#endif // defined(JSON_HAS_INT64)
+ /// Default precision for real value for string representation.
+ static const UInt defaultRealPrecision;
+
+// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
+// when using gcc and clang backend compilers. CZString
+// cannot be defined as private. See issue #486
+#ifdef __NVCC__
+public:
+#else
private:
+#endif
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
class CZString {
public:
- enum DuplicationPolicy {
- noDuplication = 0,
- duplicate,
- duplicateOnCopy
- };
+ enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other);
@@ -683,11 +713,16 @@ private:
CZString(CZString&& other);
#endif
~CZString();
- CZString& operator=(CZString other);
+ CZString& operator=(const CZString& other);
+
+#if JSON_HAS_RVALUE_REFERENCES
+ CZString& operator=(CZString&& other);
+#endif
+
bool operator<(CZString const& other) const;
bool operator==(CZString const& other) const;
ArrayIndex index() const;
- //const char* c_str() const; ///< \deprecated
+ // const char* c_str() const; ///< \deprecated
char const* data() const;
unsigned length() const;
bool isStaticString() const;
@@ -696,11 +731,11 @@ private:
void swap(CZString& other);
struct StringStorage {
- unsigned policy_: 2;
- unsigned length_: 30; // 1GB max
+ unsigned policy_ : 2;
+ unsigned length_ : 30; // 1GB max
};
- char const* cstr_; // actually, a prefixed string, unless policy is noDup
+ char const* cstr_; // actually, a prefixed string, unless policy is noDup
union {
ArrayIndex index_;
StringStorage storage_;
@@ -757,7 +792,8 @@ Json::Value obj_value(Json::objectValue); // {}
* \endcode
*/
Value(const StaticString& value);
- Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too.
+ Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded
+ ///< zeroes too.
#ifdef JSON_USE_CPPTL
Value(const CppTL::ConstString& value);
#endif
@@ -771,13 +807,20 @@ Json::Value obj_value(Json::objectValue); // {}
~Value();
/// Deep copy, then swap(other).
- /// \note Over-write existing comments. To preserve comments, use #swapPayload().
+ /// \note Over-write existing comments. To preserve comments, use
+ /// #swapPayload().
Value& operator=(Value other);
+
/// Swap everything.
void swap(Value& other);
/// Swap values but leave comments and source offsets in place.
void swapPayload(Value& other);
+ /// copy everything.
+ void copy(const Value& other);
+ /// copy values but leave comments and source offsets in place.
+ void copyPayload(const Value& other);
+
ValueType type() const;
/// Compare payload only, not comments etc.
@@ -791,14 +834,14 @@ Json::Value obj_value(Json::objectValue); // {}
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
#if JSONCPP_USING_SECURE_MEMORY
- unsigned getCStringLength() const; //Allows you to understand the length of the CString
+ unsigned getCStringLength() const; // Allows you to understand the length of
+ // the CString
#endif
JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
/** Get raw char* of string-value.
* \return false if !string. (Seg-fault if str or end are NULL.)
*/
- bool getString(
- char const** begin, char const** end) const;
+ bool getString(char const** begin, char const** end) const;
#ifdef JSON_USE_CPPTL
CppTL::ConstString asConstString() const;
#endif
@@ -836,20 +879,20 @@ Json::Value obj_value(Json::objectValue); // {}
/// otherwise, false.
bool empty() const;
- /// Return isNull()
- bool operator!() const;
+ /// Return !isNull()
+ JSONCPP_OP_EXPLICIT operator bool() const;
/// Remove all object members and array elements.
/// \pre type() is arrayValue, objectValue, or nullValue
/// \post type() is unchanged
void clear();
- /// Resize the array to size elements.
+ /// Resize the array to newSize elements.
/// New elements are initialized to null.
/// May only be called on nullValue or arrayValue.
/// \pre type() is arrayValue or nullValue
/// \post type() is arrayValue
- void resize(ArrayIndex size);
+ void resize(ArrayIndex newSize);
/// Access an array element (zero based index ).
/// If the array contains less than index element, then null value are
@@ -888,6 +931,10 @@ Json::Value obj_value(Json::objectValue); // {}
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value& append(const Value& value);
+#if JSON_HAS_RVALUE_REFERENCES
+ Value& append(Value&& value);
+#endif
+
/// Access an object value by name, create a null member if it does not exist.
/// \note Because of our implementation, keys are limited to 2^30 -1 chars.
/// Exceeding that will cause an exception.
@@ -905,7 +952,8 @@ Json::Value obj_value(Json::objectValue); // {}
/** \brief Access an object value by name, create a null member if it does not
exist.
- * If the object has no entry for that name, then the member name used to store
+ * If the object has no entry for that name, then the member name used to
+ store
* the new entry is not duplicated.
* Example of use:
* \code
@@ -928,7 +976,8 @@ Json::Value obj_value(Json::objectValue); // {}
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \note key may contain embedded nulls.
- Value get(const char* begin, const char* end, const Value& defaultValue) const;
+ Value
+ get(const char* begin, const char* end, const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \param key may contain embedded nulls.
@@ -953,11 +1002,11 @@ Json::Value obj_value(Json::objectValue); // {}
/// \pre type() is objectValue or nullValue
/// \post type() is unchanged
/// \deprecated
- Value removeMember(const char* key);
+ void removeMember(const char* key);
/// Same as removeMember(const char*)
/// \param key may contain embedded nulls.
/// \deprecated
- Value removeMember(const JSONCPP_STRING& key);
+ void removeMember(const JSONCPP_STRING& key);
/// Same as removeMember(const char* begin, const char* end, Value* removed),
/// but 'key' is null-terminated.
bool removeMember(const char* key, Value* removed);
@@ -974,9 +1023,9 @@ Json::Value obj_value(Json::objectValue); // {}
O(n) expensive operations.
Update 'removed' iff removed.
- \return true iff removed (no exceptions)
+ \return true if removed (no exceptions)
*/
- bool removeIndex(ArrayIndex i, Value* removed);
+ bool removeIndex(ArrayIndex index, Value* removed);
/// Return true if the object has a member named key.
/// \note 'key' must be null-terminated.
@@ -1031,6 +1080,9 @@ Json::Value obj_value(Json::objectValue); // {}
private:
void initBasic(ValueType type, bool allocated = false);
+ void dupPayload(const Value& other);
+ void releasePayload();
+ void dupMeta(const Value& other);
Value& resolveReference(const char* key);
Value& resolveReference(const char* key, const char* end);
@@ -1058,12 +1110,14 @@ private:
LargestUInt uint_;
double real_;
bool bool_;
- char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
+ char* string_; // actually ptr to unsigned, followed by str, unless
+ // !allocated_
ObjectValues* map_;
} value_;
ValueType type_ : 8;
- unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
- // If not allocated_, string_ must be null-terminated.
+ unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is
+ // useless. If not allocated_, string_ must be
+ // null-terminated.
CommentInfo* comments_;
// [start, limit) byte offsets in the source JSON text from which this Value
@@ -1085,11 +1139,7 @@ public:
PathArgument(const JSONCPP_STRING& key);
private:
- enum Kind {
- kindNone = 0,
- kindIndex,
- kindKey
- };
+ enum Kind { kindNone = 0, kindIndex, kindKey };
JSONCPP_STRING key_;
ArrayIndex index_;
Kind kind_;
@@ -1130,7 +1180,7 @@ private:
const InArgs& in,
InArgs::const_iterator& itInArg,
PathArgument::Kind kind);
- void invalidPath(const JSONCPP_STRING& path, int location);
+ static void invalidPath(const JSONCPP_STRING& path, int location);
Args args_;
};
@@ -1157,7 +1207,8 @@ public:
/// Value.
Value key() const;
- /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
+ /// Return the index of the referenced Value, or -1 if it is not an
+ /// arrayValue.
UInt index() const;
/// Return the member name of the referenced Value, or "" if it is not an
@@ -1167,7 +1218,8 @@ public:
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
- /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
+ /// \deprecated This cannot be used for UTF-8 strings, since there can be
+ /// embedded nulls.
JSONCPP_DEPRECATED("Use `key = name();` instead.")
char const* memberName() const;
/// Return the member name of the referenced Value, or NULL if it is not an
@@ -1208,8 +1260,8 @@ class JSON_API ValueConstIterator : public ValueIteratorBase {
public:
typedef const Value value_type;
- //typedef unsigned int size_t;
- //typedef int difference_type;
+ // typedef unsigned int size_t;
+ // typedef int difference_type;
typedef const Value& reference;
typedef const Value* pointer;
typedef ValueConstIterator SelfType;
@@ -1218,9 +1270,10 @@ public:
ValueConstIterator(ValueIterator const& other);
private:
-/*! \internal Use by Value to create an iterator.
- */
+ /*! \internal Use by Value to create an iterator.
+ */
explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
+
public:
SelfType& operator=(const ValueIteratorBase& other);
@@ -1269,9 +1322,10 @@ public:
ValueIterator(const ValueIterator& other);
private:
-/*! \internal Use by Value to create an iterator.
- */
+ /*! \internal Use by Value to create an iterator.
+ */
explicit ValueIterator(const Value::ObjectValues::iterator& current);
+
public:
SelfType& operator=(const SelfType& other);
@@ -1302,14 +1356,9 @@ public:
pointer operator->() const { return &deref(); }
};
-} // namespace Json
-
+inline void swap(Value& a, Value& b) { a.swap(b); }
-namespace std {
-/// Specialize std::swap() for Json::Value.
-template<>
-inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
-}
+} // namespace Json
#pragma pack(pop)
@@ -1332,7 +1381,7 @@ inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
// Beginning of content of file: include/json/reader.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -1346,9 +1395,9 @@ inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <deque>
#include <iosfwd>
+#include <istream>
#include <stack>
#include <string>
-#include <istream>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
@@ -1386,11 +1435,13 @@ public:
/** \brief Constructs a Reader allowing all features
* for parsing.
*/
+ JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
Reader();
/** \brief Constructs a Reader allowing the specified feature set
* for parsing.
*/
+ JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
Reader(const Features& features);
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
@@ -1483,7 +1534,9 @@ public:
* \return \c true if the error was successfully added, \c false if either
* Value offset exceeds the document size.
*/
- bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
+ bool pushError(const Value& value,
+ const JSONCPP_STRING& message,
+ const Value& extra);
/** \brief Return whether there are any errors.
* \return \c true if there are no errors to report \c false if
@@ -1550,7 +1603,8 @@ private:
Location& current,
Location end,
unsigned int& unicode);
- bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
+ bool
+ addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
@@ -1564,6 +1618,9 @@ private:
void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);
+ static bool containsNewLine(Location begin, Location end);
+ static JSONCPP_STRING normalizeEOL(Location begin, Location end);
+
typedef std::stack<Value*> Nodes;
Nodes nodes_;
Errors errors_;
@@ -1576,7 +1633,7 @@ private:
JSONCPP_STRING commentsBefore_;
Features features_;
bool collectComments_;
-}; // Reader
+}; // Reader
/** Interface for reading JSON from a char array.
*/
@@ -1585,7 +1642,8 @@ public:
virtual ~CharReader() {}
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
document.
- * The document must be a UTF-8 encoded string containing the document to read.
+ * The document must be a UTF-8 encoded string containing the document to
+ read.
*
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
document to read.
@@ -1600,9 +1658,10 @@ public:
* \return \c true if the document was successfully parsed, \c false if an
error occurred.
*/
- virtual bool parse(
- char const* beginDoc, char const* endDoc,
- Value* root, JSONCPP_STRING* errs) = 0;
+ virtual bool parse(char const* beginDoc,
+ char const* endDoc,
+ Value* root,
+ JSONCPP_STRING* errs) = 0;
class JSON_API Factory {
public:
@@ -1611,8 +1670,8 @@ public:
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
virtual CharReader* newCharReader() const = 0;
- }; // Factory
-}; // CharReader
+ }; // Factory
+}; // CharReader
/** \brief Build a CharReader implementation.
@@ -1642,7 +1701,8 @@ public:
- `"strictRoot": false or true`
- true if root must be either an array or an object value
- `"allowDroppedNullPlaceholders": false or true`
- - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
+ - true if dropped null placeholders are allowed. (See
+ StreamWriterBuilder.)
- `"allowNumericKeys": false or true`
- true if numeric object keys are allowed.
- `"allowSingleQuotes": false or true`
@@ -1656,9 +1716,10 @@ public:
- If true, `parse()` returns false when extra non-whitespace trails
the JSON value in the input string.
- `"rejectDupKeys": false or true`
- - If true, `parse()` returns false when a key is duplicated within an object.
+ - If true, `parse()` returns false when a key is duplicated within an
+ object.
- `"allowSpecialFloats": false or true`
- - If true, special float values (NaNs and infinities) are allowed
+ - If true, special float values (NaNs and infinities) are allowed
and their values are lossfree restorable.
You can examine 'settings_` yourself
@@ -1697,13 +1758,13 @@ public:
};
/** Consume entire stream and use its begin/end.
- * Someday we might have a real StreamReader, but for now this
- * is convenient.
- */
-bool JSON_API parseFromStream(
- CharReader::Factory const&,
- JSONCPP_ISTREAM&,
- Value* root, std::string* errs);
+ * Someday we might have a real StreamReader, but for now this
+ * is convenient.
+ */
+bool JSON_API parseFromStream(CharReader::Factory const&,
+ JSONCPP_ISTREAM&,
+ Value* root,
+ std::string* errs);
/** \brief Read from 'sin' into 'root'.
@@ -1754,7 +1815,7 @@ JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
// Beginning of content of file: include/json/writer.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -1765,18 +1826,17 @@ JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
#if !defined(JSON_IS_AMALGAMATION)
#include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <vector>
-#include <string>
#include <ostream>
+#include <string>
+#include <vector>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
#pragma pack(push, 8)
namespace Json {
@@ -1798,15 +1858,15 @@ Usage:
*/
class JSON_API StreamWriter {
protected:
- JSONCPP_OSTREAM* sout_; // not owned; will not delete
+ JSONCPP_OSTREAM* sout_; // not owned; will not delete
public:
StreamWriter();
virtual ~StreamWriter();
/** Write Value into document as configured in sub-class.
Do not take ownership of sout, but maintain a reference during function.
\pre sout != NULL
- \return zero on success (For now, we always return zero, so check the stream instead.)
- \throw std::exception possibly, depending on configuration
+ \return zero on success (For now, we always return zero, so check the
+ stream instead.) \throw std::exception possibly, depending on configuration
*/
virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
@@ -1819,14 +1879,14 @@ public:
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
virtual StreamWriter* newStreamWriter() const = 0;
- }; // Factory
-}; // StreamWriter
+ }; // Factory
+}; // StreamWriter
/** \brief Write into stringstream, then return string, for convenience.
* A StreamWriter will be created from the factory, used, and then deleted.
*/
-JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
-
+JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory,
+ Value const& root);
/** \brief Build a StreamWriter implementation.
@@ -1850,18 +1910,23 @@ public:
/** Configuration of this builder.
Available settings (case-sensitive):
- "commentStyle": "None" or "All"
- - "indentation": "<anything>"
+ - "indentation": "<anything>".
+ - Setting this to an empty string also omits newline characters.
- "enableYAMLCompatibility": false or true
- slightly change the whitespace around colons
- "dropNullPlaceholders": false or true
- Drop the "null" string from the writer's output for nullValues.
Strictly speaking, this is not valid JSON. But when the output is being
- fed to a browser's Javascript, it makes for smaller output and the
+ fed to a browser's JavaScript, it makes for smaller output and the
browser can handle the output just fine.
- "useSpecialFloats": false or true
- If true, outputs non-finite floating point values in the following way:
- NaN values as "NaN", positive infinity as "Infinity", and negative infinity
- as "-Infinity".
+ NaN values as "NaN", positive infinity as "Infinity", and negative
+ infinity as "-Infinity".
+ - "precision": int
+ - Number of precision digits for formatting of real values.
+ - "precisionType": "significant"(default) or "decimal"
+ - Type of precision for formatting of real values.
You can examine 'settings_` yourself
to see the defaults. You can also write and read them just like any
@@ -1897,7 +1962,7 @@ public:
/** \brief Abstract class for writers.
* \deprecated Use StreamWriter. (And really, this is an implementation detail.)
*/
-class JSON_API Writer {
+class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer {
public:
virtual ~Writer();
@@ -1909,12 +1974,16 @@ public:
*
* The JSON document is written in a single line. It is not intended for 'human'
*consumption,
- * but may be usefull to support feature such as RPC where bandwith is limited.
+ * but may be useful to support feature such as RPC where bandwidth is limited.
* \sa Reader, Value
* \deprecated Use StreamWriterBuilder.
*/
-class JSON_API FastWriter : public Writer {
-
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996) // Deriving from deprecated class
+#endif
+class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter
+ : public Writer {
public:
FastWriter();
~FastWriter() JSONCPP_OVERRIDE {}
@@ -1923,7 +1992,7 @@ public:
/** \brief Drop the "null" string from the writer's output for nullValues.
* Strictly speaking, this is not valid JSON. But when the output is being
- * fed to a browser's Javascript, it makes for smaller output and the
+ * fed to a browser's JavaScript, it makes for smaller output and the
* browser can handle the output just fine.
*/
void dropNullPlaceholders();
@@ -1937,10 +2006,13 @@ private:
void writeValue(const Value& value);
JSONCPP_STRING document_;
- bool yamlCompatiblityEnabled_;
+ bool yamlCompatibilityEnabled_;
bool dropNullPlaceholders_;
bool omitEndingLineFeed_;
};
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
*human friendly way.
@@ -1966,7 +2038,12 @@ private:
* \sa Reader, Value, Value::setComment()
* \deprecated Use StreamWriterBuilder.
*/
-class JSON_API StyledWriter : public Writer {
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996) // Deriving from deprecated class
+#endif
+class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
+ StyledWriter : public Writer {
public:
StyledWriter();
~StyledWriter() JSONCPP_OVERRIDE {}
@@ -1981,7 +2058,7 @@ public: // overridden from Writer
private:
void writeValue(const Value& value);
void writeArrayValue(const Value& value);
- bool isMultineArray(const Value& value);
+ bool isMultilineArray(const Value& value);
void pushValue(const JSONCPP_STRING& value);
void writeIndent();
void writeWithIndent(const JSONCPP_STRING& value);
@@ -1989,7 +2066,7 @@ private:
void unindent();
void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root);
- bool hasCommentForValue(const Value& value);
+ static bool hasCommentForValue(const Value& value);
static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
typedef std::vector<JSONCPP_STRING> ChildValues;
@@ -2001,6 +2078,9 @@ private:
unsigned int indentSize_;
bool addChildValues_;
};
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
human friendly way,
@@ -2024,13 +2104,20 @@ private:
* If the Value have comments then they are outputed according to their
#CommentPlacement.
*
- * \param indentation Each level will be indented by this amount extra.
* \sa Reader, Value, Value::setComment()
* \deprecated Use StreamWriterBuilder.
*/
-class JSON_API StyledStreamWriter {
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996) // Deriving from deprecated class
+#endif
+class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
+ StyledStreamWriter {
public:
- StyledStreamWriter(JSONCPP_STRING indentation = "\t");
+ /**
+ * \param indentation Each level will be indented by this amount extra.
+ */
+ StyledStreamWriter(const JSONCPP_STRING& indentation = "\t");
~StyledStreamWriter() {}
public:
@@ -2045,7 +2132,7 @@ public:
private:
void writeValue(const Value& value);
void writeArrayValue(const Value& value);
- bool isMultineArray(const Value& value);
+ bool isMultilineArray(const Value& value);
void pushValue(const JSONCPP_STRING& value);
void writeIndent();
void writeWithIndent(const JSONCPP_STRING& value);
@@ -2053,7 +2140,7 @@ private:
void unindent();
void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root);
- bool hasCommentForValue(const Value& value);
+ static bool hasCommentForValue(const Value& value);
static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
typedef std::vector<JSONCPP_STRING> ChildValues;
@@ -2066,6 +2153,9 @@ private:
bool addChildValues_ : 1;
bool indented_ : 1;
};
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
#if defined(JSON_HAS_INT64)
JSONCPP_STRING JSON_API valueToString(Int value);
@@ -2073,7 +2163,10 @@ JSONCPP_STRING JSON_API valueToString(UInt value);
#endif // if defined(JSON_HAS_INT64)
JSONCPP_STRING JSON_API valueToString(LargestInt value);
JSONCPP_STRING JSON_API valueToString(LargestUInt value);
-JSONCPP_STRING JSON_API valueToString(double value);
+JSONCPP_STRING JSON_API
+valueToString(double value,
+ unsigned int precision = Value::defaultRealPrecision,
+ PrecisionType precisionType = PrecisionType::significantDigits);
JSONCPP_STRING JSON_API valueToString(bool value);
JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
@@ -2104,7 +2197,7 @@ JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
// Beginning of content of file: include/json/assertions.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -2112,8 +2205,8 @@ JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
-#include <stdlib.h>
#include <sstream>
+#include <stdlib.h>
#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
@@ -2126,30 +2219,35 @@ JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
#if JSON_USE_EXCEPTION
// @todo <= add detail about condition in exception
-# define JSON_ASSERT(condition) \
- {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
+#define JSON_ASSERT(condition) \
+ { \
+ if (!(condition)) { \
+ Json::throwLogicError("assert json failed"); \
+ } \
+ }
-# define JSON_FAIL_MESSAGE(message) \
+#define JSON_FAIL_MESSAGE(message) \
{ \
- JSONCPP_OSTRINGSTREAM oss; oss << message; \
+ JSONCPP_OSTRINGSTREAM oss; \
+ oss << message; \
Json::throwLogicError(oss.str()); \
abort(); \
}
#else // JSON_USE_EXCEPTION
-# define JSON_ASSERT(condition) assert(condition)
+#define JSON_ASSERT(condition) assert(condition)
// The call to assert() will show the failure message in debug builds. In
// release builds we abort, for a core-dump or debugger.
-# define JSON_FAIL_MESSAGE(message) \
+#define JSON_FAIL_MESSAGE(message) \
{ \
- JSONCPP_OSTRINGSTREAM oss; oss << message; \
+ JSONCPP_OSTRINGSTREAM oss; \
+ oss << message; \
assert(false && oss.str().c_str()); \
abort(); \
}
-
#endif
#define JSON_ASSERT_MESSAGE(condition, message) \
@@ -2167,4 +2265,4 @@ JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
-#endif //ifndef JSON_AMALGATED_H_INCLUDED
+#endif //ifndef JSON_AMALGAMATED_H_INCLUDED
diff --git a/json/jsoncpp.cpp b/json/jsoncpp.cpp
index 7634ed4f..c2a949d3 100644
--- a/json/jsoncpp.cpp
+++ b/json/jsoncpp.cpp
@@ -1,4 +1,4 @@
-/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
+/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json.h"
// //////////////////////////////////////////////////////////////////////
@@ -10,13 +10,13 @@ The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
-released under the terms of the MIT License (see below).
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
+The JsonCpp Authors, and is released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the
@@ -31,7 +31,7 @@ described in clear, concise terms at:
The full text of the MIT License follows:
========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur
+Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -84,7 +84,7 @@ license you like.
// Beginning of content of file: src/lib_json/json_tool.h
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -92,6 +92,9 @@ license you like.
#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
+#ifndef JSON_CONFIG_H_INCLUDED
+#include <json/config.h>
+#endif
// Also support old flag NO_LOCALE_SUPPORT
#ifdef NO_LOCALE_SUPPORT
@@ -109,7 +112,7 @@ license you like.
*/
namespace Json {
-static char getDecimalPoint() {
+static inline char getDecimalPoint() {
#ifdef JSONCPP_NO_LOCALE_SUPPORT
return '\0';
#else
@@ -147,9 +150,6 @@ static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
return result;
}
-/// Returns true if ch is a control character (in range [1,31]).
-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.
@@ -160,7 +160,7 @@ enum {
typedef char UIntToStringBuffer[uintToStringBufferSize];
/** Converts an unsigned integer to string.
- * @param value Unsigned interger to convert to string
+ * @param value Unsigned integer to convert to string
* @param current Input/Output string buffer.
* Must have at least uintToStringBufferSize chars free.
*/
@@ -177,28 +177,45 @@ static inline void uintToString(LargestUInt value, char*& current) {
* 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) {
+template <typename Iter> Iter fixNumericLocale(Iter begin, Iter end) {
+ for (; begin != end; ++begin) {
if (*begin == ',') {
*begin = '.';
}
- ++begin;
}
+ return begin;
}
-static inline void fixNumericLocaleInput(char* begin, char* end) {
+template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
char decimalPoint = getDecimalPoint();
- if (decimalPoint != '\0' && decimalPoint != '.') {
- while (begin < end) {
- if (*begin == '.') {
- *begin = decimalPoint;
- }
- ++begin;
+ if (decimalPoint == '\0' || decimalPoint == '.') {
+ return;
+ }
+ for (; begin != end; ++begin) {
+ if (*begin == '.') {
+ *begin = decimalPoint;
+ }
+ }
+}
+
+/**
+ * Return iterator that would be the new end of the range [begin,end), if we
+ * were to delete zeros in the end of string, but not the last zero before '.'.
+ */
+template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
+ for (; begin != end; --end) {
+ if (*(end - 1) != '0') {
+ return end;
+ }
+ // Don't delete the last zero before the decimal point.
+ if (begin != (end - 1) && *(end - 2) == '.') {
+ return end;
}
}
+ return end;
}
-} // namespace Json {
+} // namespace Json
#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
@@ -215,46 +232,46 @@ static inline void fixNumericLocaleInput(char* begin, char* end) {
// Beginning of content of file: src/lib_json/json_reader.cpp
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2011 Baptiste Lepilleur
+// Copyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors
// Copyright (C) 2016 InfoTeCS JSC. All rights reserved.
// 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_tool.h"
#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 <limits>
#include <memory>
#include <set>
-#include <limits>
+#include <sstream>
+#include <utility>
-#if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
-#define snprintf sprintf_s
-#elif _MSC_VER >= 1900 // VC++ 14.0 and above
+#if __cplusplus >= 201103L
+#include <cstdio>
+
+#if !defined(snprintf)
#define snprintf std::snprintf
+#endif
+
+#if !defined(sscanf)
+#define sscanf std::sscanf
+#endif
#else
+#include <stdio.h>
+
+#if defined(_MSC_VER)
+#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
+#if !defined(snprintf)
#define snprintf _snprintf
#endif
-#elif defined(__ANDROID__) || defined(__QNXNTO__)
-#define snprintf snprintf
-#elif __cplusplus >= 201103L
-#if !defined(__MINGW32__) && !defined(__CYGWIN__)
-#define snprintf std::snprintf
-#endif
#endif
-
-#if defined(__QNXNTO__)
-#define sscanf std::sscanf
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
@@ -262,19 +279,21 @@ static inline void fixNumericLocaleInput(char* begin, char* end) {
#pragma warning(disable : 4996)
#endif
-// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit
+// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile
+// time to change the stack limit
#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)
#define JSONCPP_DEPRECATED_STACK_LIMIT 1000
#endif
-static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()
+static size_t const stackLimit_g =
+ JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()
namespace Json {
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
typedef std::unique_ptr<CharReader> CharReaderPtr;
#else
-typedef std::auto_ptr<CharReader> CharReaderPtr;
+typedef std::auto_ptr<CharReader> CharReaderPtr;
#endif
// Implementation of class Features
@@ -298,7 +317,7 @@ Features Features::strictMode() {
// Implementation of class Reader
// ////////////////////////////////
-static bool containsNewLine(Reader::Location begin, Reader::Location end) {
+bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) {
for (; begin < end; ++begin)
if (*begin == '\n' || *begin == '\r')
return true;
@@ -318,10 +337,10 @@ Reader::Reader(const Features& features)
lastValue_(), commentsBefore_(), features_(features), collectComments_() {
}
-bool
-Reader::parse(const std::string& document, Value& root, bool collectComments) {
- JSONCPP_STRING documentCopy(document.data(), document.data() + document.capacity());
- std::swap(documentCopy, document_);
+bool Reader::parse(const std::string& document,
+ Value& root,
+ bool collectComments) {
+ document_.assign(document.begin(), document.end());
const char* begin = document_.c_str();
const char* end = begin + document_.length();
return parse(begin, end, root, collectComments);
@@ -354,7 +373,7 @@ bool Reader::parse(const char* beginDoc,
current_ = begin_;
lastValueEnd_ = 0;
lastValue_ = 0;
- commentsBefore_ = "";
+ commentsBefore_.clear();
errors_.clear();
while (!nodes_.empty())
nodes_.pop();
@@ -383,9 +402,11 @@ bool Reader::parse(const char* beginDoc,
bool Reader::readValue() {
// readValue() may call itself only if it calls readObject() or ReadArray().
- // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue().
- // parse() executes one nodes_.push(), so > instead of >=.
- if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
+ // These methods execute nodes_.push() just before and nodes_.pop)() just
+ // after calling readValue(). parse() executes one nodes_.push(), so > instead
+ // of >=.
+ if (nodes_.size() > stackLimit_g)
+ throwRuntimeError("Exceeded stackLimit in readValue().");
Token token;
skipCommentTokens(token);
@@ -393,7 +414,7 @@ bool Reader::readValue() {
if (collectComments_ && !commentsBefore_.empty()) {
currentValue().setComment(commentsBefore_, commentBefore);
- commentsBefore_ = "";
+ commentsBefore_.clear();
}
switch (token.type_) {
@@ -411,30 +432,24 @@ bool Reader::readValue() {
case tokenString:
successful = decodeString(token);
break;
- case tokenTrue:
- {
+ case tokenTrue: {
Value v(true);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenFalse:
- {
+ } break;
+ case tokenFalse: {
Value v(false);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNull:
- {
+ } break;
+ case tokenNull: {
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
+ } break;
case tokenArraySeparator:
case tokenObjectEnd:
case tokenArrayEnd:
@@ -587,7 +602,8 @@ bool Reader::readComment() {
return true;
}
-static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end) {
+JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin,
+ Reader::Location end) {
JSONCPP_STRING normalized;
normalized.reserve(static_cast<size_t>(end - begin));
Reader::Location current = begin;
@@ -595,8 +611,8 @@ static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end)
char c = *current++;
if (c == '\r') {
if (current != end && *current == '\n')
- // convert dos EOL
- ++current;
+ // convert dos EOL
+ ++current;
// convert Mac EOL
normalized += '\n';
} else {
@@ -606,8 +622,9 @@ static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end)
return normalized;
}
-void
-Reader::addComment(Location begin, Location end, CommentPlacement placement) {
+void Reader::addComment(Location begin,
+ Location end,
+ CommentPlacement placement) {
assert(collectComments_);
const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
if (placement == commentAfterOnSameLine) {
@@ -644,7 +661,7 @@ bool Reader::readCppStyleComment() {
}
void Reader::readNumber() {
- const char *p = current_;
+ const char* p = current_;
char c = '0'; // stopgap for already consumed character
// integral part
while (c >= '0' && c <= '9')
@@ -691,7 +708,7 @@ bool Reader::readObject(Token& tokenStart) {
break;
if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
return true;
- name = "";
+ name.clear();
if (tokenName.type_ == tokenString) {
if (!decodeString(tokenName, name))
return recoverFromError(tokenObjectEnd);
@@ -706,8 +723,8 @@ bool Reader::readObject(Token& tokenStart) {
Token colon;
if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
- return addErrorAndRecover(
- "Missing ':' after object member name", colon, tokenObjectEnd);
+ return addErrorAndRecover("Missing ':' after object member name", colon,
+ tokenObjectEnd);
}
Value& value = currentValue()[name];
nodes_.push(&value);
@@ -720,8 +737,8 @@ bool Reader::readObject(Token& tokenStart) {
if (!readToken(comma) ||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
comma.type_ != tokenComment)) {
- return addErrorAndRecover(
- "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
+ return addErrorAndRecover("Missing ',' or '}' in object declaration",
+ comma, tokenObjectEnd);
}
bool finalizeTokenOk = true;
while (comma.type_ == tokenComment && finalizeTokenOk)
@@ -729,8 +746,8 @@ bool Reader::readObject(Token& tokenStart) {
if (comma.type_ == tokenObjectEnd)
return true;
}
- return addErrorAndRecover(
- "Missing '}' or object member name", tokenName, tokenObjectEnd);
+ return addErrorAndRecover("Missing '}' or object member name", tokenName,
+ tokenObjectEnd);
}
bool Reader::readArray(Token& tokenStart) {
@@ -762,8 +779,8 @@ bool Reader::readArray(Token& tokenStart) {
bool badTokenType =
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
if (!ok || badTokenType) {
- return addErrorAndRecover(
- "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
+ return addErrorAndRecover("Missing ',' or ']' in array declaration",
+ token, tokenArrayEnd);
}
if (token.type_ == tokenArrayEnd)
break;
@@ -789,7 +806,8 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
bool isNegative = *current == '-';
if (isNegative)
++current;
- // TODO: Help the compiler do the div and mod at compile time or get rid of them.
+ // TODO: Help the compiler do the div and mod at compile time or get rid of
+ // them.
Value::LargestUInt maxIntegerValue =
isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
: Value::maxLargestUInt;
@@ -921,8 +939,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
if (end - current < 6)
return addError(
"additional six characters expected to parse unicode surrogate pair.",
- token,
- current);
+ token, current);
unsigned int surrogatePair;
if (*(current++) == '\\' && *(current++) == 'u') {
if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
@@ -932,8 +949,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
} else
return addError("expecting another \\u token to begin the second half of "
"a unicode surrogate pair",
- token,
- current);
+ token, current);
}
return true;
}
@@ -944,8 +960,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
unsigned int& ret_unicode) {
if (end - current < 4)
return addError(
- "Bad unicode escape sequence in string: four digits expected.",
- token,
+ "Bad unicode escape sequence in string: four digits expected.", token,
current);
int unicode = 0;
for (int index = 0; index < 4; ++index) {
@@ -960,15 +975,15 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
else
return addError(
"Bad unicode escape sequence in string: hexadecimal digit expected.",
- token,
- current);
+ token, current);
}
ret_unicode = static_cast<unsigned int>(unicode);
return true;
}
-bool
-Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
+bool Reader::addError(const JSONCPP_STRING& message,
+ Token& token,
+ Location extra) {
ErrorInfo info;
info.token_ = token;
info.message_ = message;
@@ -1044,8 +1059,7 @@ JSONCPP_STRING Reader::getFormatedErrorMessages() const {
JSONCPP_STRING Reader::getFormattedErrorMessages() const {
JSONCPP_STRING formattedMessage;
for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
+ itError != errors_.end(); ++itError) {
const ErrorInfo& error = *itError;
formattedMessage +=
"* " + getLocationLineAndColumn(error.token_.start_) + "\n";
@@ -1060,8 +1074,7 @@ JSONCPP_STRING Reader::getFormattedErrorMessages() const {
std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
std::vector<Reader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
+ itError != errors_.end(); ++itError) {
const ErrorInfo& error = *itError;
Reader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
@@ -1074,8 +1087,7 @@ std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
ptrdiff_t const length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length)
+ if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
@@ -1089,11 +1101,12 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
return true;
}
-bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
+bool Reader::pushError(const Value& value,
+ const JSONCPP_STRING& message,
+ const Value& extra) {
ptrdiff_t const length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length
- || extra.getOffsetLimit() > length)
+ if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
+ extra.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
@@ -1107,9 +1120,7 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const
return true;
}
-bool Reader::good() const {
- return !errors_.size();
-}
+bool Reader::good() const { return !errors_.size(); }
// exact copy of Features
class OurFeatures {
@@ -1124,7 +1135,7 @@ public:
bool rejectDupKeys_;
bool allowSpecialFloats_;
int stackLimit_;
-}; // OurFeatures
+}; // OurFeatures
// exact copy of Implementation of class Features
// ////////////////////////////////
@@ -1153,12 +1164,14 @@ public:
JSONCPP_STRING getFormattedErrorMessages() const;
std::vector<StructuredError> getStructuredErrors() const;
bool pushError(const Value& value, const JSONCPP_STRING& message);
- bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
+ bool pushError(const Value& value,
+ const JSONCPP_STRING& message,
+ const Value& extra);
bool good() const;
private:
- OurReader(OurReader const&); // no impl
- void operator=(OurReader const&); // no impl
+ OurReader(OurReader const&); // no impl
+ void operator=(OurReader const&); // no impl
enum TokenType {
tokenEndOfStream = 0,
@@ -1222,7 +1235,8 @@ private:
Location& current,
Location end,
unsigned int& unicode);
- bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
+ bool
+ addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
@@ -1236,6 +1250,9 @@ private:
void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);
+ static JSONCPP_STRING normalizeEOL(Location begin, Location end);
+ static bool containsNewLine(Location begin, Location end);
+
typedef std::stack<Value*> Nodes;
Nodes nodes_;
Errors errors_;
@@ -1249,20 +1266,27 @@ private:
OurFeatures const features_;
bool collectComments_;
-}; // OurReader
+}; // OurReader
// complete copy of Read impl, for OurReader
+bool OurReader::containsNewLine(OurReader::Location begin,
+ OurReader::Location end) {
+ for (; begin < end; ++begin)
+ if (*begin == '\n' || *begin == '\r')
+ return true;
+ return false;
+}
+
OurReader::OurReader(OurFeatures const& features)
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
- lastValue_(), commentsBefore_(),
- features_(features), collectComments_() {
+ lastValue_(), commentsBefore_(), features_(features), collectComments_() {
}
bool OurReader::parse(const char* beginDoc,
- const char* endDoc,
- Value& root,
- bool collectComments) {
+ const char* endDoc,
+ Value& root,
+ bool collectComments) {
if (!features_.allowComments_) {
collectComments = false;
}
@@ -1273,7 +1297,7 @@ bool OurReader::parse(const char* beginDoc,
current_ = begin_;
lastValueEnd_ = 0;
lastValue_ = 0;
- commentsBefore_ = "";
+ commentsBefore_.clear();
errors_.clear();
while (!nodes_.empty())
nodes_.pop();
@@ -1283,7 +1307,8 @@ bool OurReader::parse(const char* beginDoc,
Token token;
skipCommentTokens(token);
if (features_.failIfExtra_) {
- if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream) {
+ if ((features_.strictRoot_ || token.type_ != tokenError) &&
+ token.type_ != tokenEndOfStream) {
addError("Extra non-whitespace after JSON value.", token);
return false;
}
@@ -1308,14 +1333,15 @@ bool OurReader::parse(const char* beginDoc,
bool OurReader::readValue() {
// To preserve the old behaviour we cast size_t to int.
- if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
+ if (static_cast<int>(nodes_.size()) > features_.stackLimit_)
+ throwRuntimeError("Exceeded stackLimit in readValue().");
Token token;
skipCommentTokens(token);
bool successful = true;
if (collectComments_ && !commentsBefore_.empty()) {
currentValue().setComment(commentsBefore_, commentBefore);
- commentsBefore_ = "";
+ commentsBefore_.clear();
}
switch (token.type_) {
@@ -1333,54 +1359,42 @@ bool OurReader::readValue() {
case tokenString:
successful = decodeString(token);
break;
- case tokenTrue:
- {
+ case tokenTrue: {
Value v(true);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenFalse:
- {
+ } break;
+ case tokenFalse: {
Value v(false);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNull:
- {
+ } break;
+ case tokenNull: {
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNaN:
- {
+ } break;
+ case tokenNaN: {
Value v(std::numeric_limits<double>::quiet_NaN());
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenPosInf:
- {
+ } break;
+ case tokenPosInf: {
Value v(std::numeric_limits<double>::infinity());
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNegInf:
- {
+ } break;
+ case tokenNegInf: {
Value v(-std::numeric_limits<double>::infinity());
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
+ } break;
case tokenArraySeparator:
case tokenObjectEnd:
case tokenArrayEnd:
@@ -1442,10 +1456,10 @@ bool OurReader::readToken(Token& token) {
break;
case '\'':
if (features_.allowSingleQuotes_) {
- token.type_ = tokenString;
- ok = readStringSingleQuote();
- break;
- } // else continue
+ token.type_ = tokenString;
+ ok = readStringSingleQuote();
+ break;
+ } // else fall through
case '/':
token.type_ = tokenComment;
ok = readComment();
@@ -1562,8 +1576,29 @@ bool OurReader::readComment() {
return true;
}
-void
-OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
+JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin,
+ OurReader::Location end) {
+ JSONCPP_STRING normalized;
+ normalized.reserve(static_cast<size_t>(end - begin));
+ OurReader::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 OurReader::addComment(Location begin,
+ Location end,
+ CommentPlacement placement) {
assert(collectComments_);
const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
if (placement == commentAfterOnSameLine) {
@@ -1600,7 +1635,7 @@ bool OurReader::readCppStyleComment() {
}
bool OurReader::readNumber(bool checkInf) {
- const char *p = current_;
+ const char* p = current_;
if (checkInf && p != end_ && *p == 'I') {
current_ = ++p;
return false;
@@ -1637,7 +1672,6 @@ bool OurReader::readString() {
return c == '"';
}
-
bool OurReader::readStringSingleQuote() {
Char c = 0;
while (current_ != end_) {
@@ -1664,7 +1698,7 @@ bool OurReader::readObject(Token& tokenStart) {
break;
if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
return true;
- name = "";
+ name.clear();
if (tokenName.type_ == tokenString) {
if (!decodeString(tokenName, name))
return recoverFromError(tokenObjectEnd);
@@ -1679,14 +1713,14 @@ bool OurReader::readObject(Token& tokenStart) {
Token colon;
if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
- return addErrorAndRecover(
- "Missing ':' after object member name", colon, tokenObjectEnd);
+ return addErrorAndRecover("Missing ':' after object member name", colon,
+ tokenObjectEnd);
}
- if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
+ if (name.length() >= (1U << 30))
+ throwRuntimeError("keylength >= 2^30");
if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
JSONCPP_STRING msg = "Duplicate key: '" + name + "'";
- return addErrorAndRecover(
- msg, tokenName, tokenObjectEnd);
+ return addErrorAndRecover(msg, tokenName, tokenObjectEnd);
}
Value& value = currentValue()[name];
nodes_.push(&value);
@@ -1699,8 +1733,8 @@ bool OurReader::readObject(Token& tokenStart) {
if (!readToken(comma) ||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
comma.type_ != tokenComment)) {
- return addErrorAndRecover(
- "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
+ return addErrorAndRecover("Missing ',' or '}' in object declaration",
+ comma, tokenObjectEnd);
}
bool finalizeTokenOk = true;
while (comma.type_ == tokenComment && finalizeTokenOk)
@@ -1708,8 +1742,8 @@ bool OurReader::readObject(Token& tokenStart) {
if (comma.type_ == tokenObjectEnd)
return true;
}
- return addErrorAndRecover(
- "Missing '}' or object member name", tokenName, tokenObjectEnd);
+ return addErrorAndRecover("Missing '}' or object member name", tokenName,
+ tokenObjectEnd);
}
bool OurReader::readArray(Token& tokenStart) {
@@ -1741,8 +1775,8 @@ bool OurReader::readArray(Token& tokenStart) {
bool badTokenType =
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
if (!ok || badTokenType) {
- return addErrorAndRecover(
- "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
+ return addErrorAndRecover("Missing ',' or ']' in array declaration",
+ token, tokenArrayEnd);
}
if (token.type_ == tokenArrayEnd)
break;
@@ -1768,7 +1802,8 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
bool isNegative = *current == '-';
if (isNegative)
++current;
- // TODO: Help the compiler do the div and mod at compile time or get rid of them.
+ // 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;
@@ -1913,9 +1948,9 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) {
}
bool OurReader::decodeUnicodeCodePoint(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode) {
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
return false;
@@ -1924,8 +1959,7 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
if (end - current < 6)
return addError(
"additional six characters expected to parse unicode surrogate pair.",
- token,
- current);
+ token, current);
unsigned int surrogatePair;
if (*(current++) == '\\' && *(current++) == 'u') {
if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
@@ -1935,20 +1969,18 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
} else
return addError("expecting another \\u token to begin the second half of "
"a unicode surrogate pair",
- token,
- current);
+ token, current);
}
return true;
}
bool OurReader::decodeUnicodeEscapeSequence(Token& token,
- Location& current,
- Location end,
- unsigned int& ret_unicode) {
+ Location& current,
+ Location end,
+ unsigned int& ret_unicode) {
if (end - current < 4)
return addError(
- "Bad unicode escape sequence in string: four digits expected.",
- token,
+ "Bad unicode escape sequence in string: four digits expected.", token,
current);
int unicode = 0;
for (int index = 0; index < 4; ++index) {
@@ -1963,15 +1995,15 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token,
else
return addError(
"Bad unicode escape sequence in string: hexadecimal digit expected.",
- token,
- current);
+ token, current);
}
ret_unicode = static_cast<unsigned int>(unicode);
return true;
}
-bool
-OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
+bool OurReader::addError(const JSONCPP_STRING& message,
+ Token& token,
+ Location extra) {
ErrorInfo info;
info.token_ = token;
info.message_ = message;
@@ -1994,8 +2026,8 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) {
}
bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message,
- Token& token,
- TokenType skipUntilToken) {
+ Token& token,
+ TokenType skipUntilToken) {
addError(message, token);
return recoverFromError(skipUntilToken);
}
@@ -2009,8 +2041,8 @@ OurReader::Char OurReader::getNextChar() {
}
void OurReader::getLocationLineAndColumn(Location location,
- int& line,
- int& column) const {
+ int& line,
+ int& column) const {
Location current = begin_;
Location lastLineStart = current;
line = 0;
@@ -2042,8 +2074,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const {
JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
JSONCPP_STRING formattedMessage;
for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
+ itError != errors_.end(); ++itError) {
const ErrorInfo& error = *itError;
formattedMessage +=
"* " + getLocationLineAndColumn(error.token_.start_) + "\n";
@@ -2058,8 +2089,7 @@ JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
std::vector<OurReader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
+ itError != errors_.end(); ++itError) {
const ErrorInfo& error = *itError;
OurReader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
@@ -2072,8 +2102,7 @@ std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
ptrdiff_t length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length)
+ if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
@@ -2087,11 +2116,12 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
return true;
}
-bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
+bool OurReader::pushError(const Value& value,
+ const JSONCPP_STRING& message,
+ const Value& extra) {
ptrdiff_t length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length
- || extra.getOffsetLimit() > length)
+ if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
+ extra.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
@@ -2105,24 +2135,19 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, con
return true;
}
-bool OurReader::good() const {
- return !errors_.size();
-}
-
+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)
- {}
- bool parse(
- char const* beginDoc, char const* endDoc,
- Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
+ OurCharReader(bool collectComments, OurFeatures const& features)
+ : collectComments_(collectComments), reader_(features) {}
+ bool parse(char const* beginDoc,
+ char const* endDoc,
+ Value* root,
+ JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
if (errs) {
*errs = reader_.getFormattedErrorMessages();
@@ -2131,19 +2156,15 @@ public:
}
};
-CharReaderBuilder::CharReaderBuilder()
-{
- setDefaults(&settings_);
-}
-CharReaderBuilder::~CharReaderBuilder()
-{}
-CharReader* CharReaderBuilder::newCharReader() const
-{
+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.allowDroppedNullPlaceholders_ =
+ settings_["allowDroppedNullPlaceholders"].asBool();
features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
features.stackLimit_ = settings_["stackLimit"].asInt();
@@ -2152,8 +2173,7 @@ CharReader* CharReaderBuilder::newCharReader() const
features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
return new OurCharReader(collectComments, features);
}
-static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
-{
+static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) {
valid_keys->clear();
valid_keys->insert("collectComments");
valid_keys->insert("allowComments");
@@ -2166,10 +2186,10 @@ static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
valid_keys->insert("rejectDupKeys");
valid_keys->insert("allowSpecialFloats");
}
-bool CharReaderBuilder::validate(Json::Value* invalid) const
-{
+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
+ if (!invalid)
+ invalid = &my_invalid; // so we do not need to test for NULL
Json::Value& inv = *invalid;
std::set<JSONCPP_STRING> valid_keys;
getValidReaderKeys(&valid_keys);
@@ -2183,14 +2203,12 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const
}
return 0u == inv.size();
}
-Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
-{
+Value& CharReaderBuilder::operator[](JSONCPP_STRING key) {
return settings_[key];
}
// static
-void CharReaderBuilder::strictMode(Json::Value* settings)
-{
-//! [CharReaderBuilderStrictMode]
+void CharReaderBuilder::strictMode(Json::Value* settings) {
+ //! [CharReaderBuilderStrictMode]
(*settings)["allowComments"] = false;
(*settings)["strictRoot"] = true;
(*settings)["allowDroppedNullPlaceholders"] = false;
@@ -2200,12 +2218,11 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
(*settings)["failIfExtra"] = true;
(*settings)["rejectDupKeys"] = true;
(*settings)["allowSpecialFloats"] = false;
-//! [CharReaderBuilderStrictMode]
+ //! [CharReaderBuilderStrictMode]
}
// static
-void CharReaderBuilder::setDefaults(Json::Value* settings)
-{
-//! [CharReaderBuilderDefaults]
+void CharReaderBuilder::setDefaults(Json::Value* settings) {
+ //! [CharReaderBuilderDefaults]
(*settings)["collectComments"] = true;
(*settings)["allowComments"] = true;
(*settings)["strictRoot"] = false;
@@ -2216,16 +2233,16 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
(*settings)["failIfExtra"] = false;
(*settings)["rejectDupKeys"] = false;
(*settings)["allowSpecialFloats"] = false;
-//! [CharReaderBuilderDefaults]
+ //! [CharReaderBuilderDefaults]
}
//////////////////////////////////
// global functions
-bool parseFromStream(
- CharReader::Factory const& fact, JSONCPP_ISTREAM& sin,
- Value* root, JSONCPP_STRING* errs)
-{
+bool parseFromStream(CharReader::Factory const& fact,
+ JSONCPP_ISTREAM& sin,
+ Value* root,
+ JSONCPP_STRING* errs) {
JSONCPP_OSTRINGSTREAM ssin;
ssin << sin.rdbuf();
JSONCPP_STRING doc = ssin.str();
@@ -2241,10 +2258,6 @@ JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
JSONCPP_STRING errs;
bool ok = parseFromStream(b, sin, &root, &errs);
if (!ok) {
- fprintf(stderr,
- "Error from reader: %s",
- errs.c_str());
-
throwRuntimeError(errs);
}
return sin;
@@ -2265,7 +2278,7 @@ JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
// Beginning of content of file: src/lib_json/json_valueiterator.inl
// //////////////////////////////////////////////////////////////////////
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -2446,7 +2459,7 @@ ValueIterator& ValueIterator::operator=(const SelfType& other) {
// Beginning of content of file: src/lib_json/json_value.cpp
// //////////////////////////////////////////////////////////////////////
-// Copyright 2011 Baptiste Lepilleur
+// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -2456,16 +2469,21 @@ ValueIterator& ValueIterator::operator=(const SelfType& other) {
#include <json/value.h>
#include <json/writer.h>
#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <cassert>
+#include <cstring>
#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()
+#include <cstddef> // size_t
+
+// Disable warning C4702 : unreachable code
+#if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above
+#pragma warning(disable : 4702)
+#endif
#define JSON_ASSERT_UNREACHABLE assert(false)
@@ -2479,20 +2497,19 @@ namespace Json {
#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;
+// 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;
// static
-Value const& Value::nullSingleton()
-{
- static Value const nullStatic;
- return nullStatic;
+Value const& Value::nullSingleton() {
+ static Value const nullStatic;
+ return nullStatic;
}
-// for backwards compatibility, we'll leave these global references around, but DO NOT
-// use them in JSONCPP library code any more!
+// for backwards compatibility, we'll leave these global references around, but
+// DO NOT use them in JSONCPP library code any more!
Value const& Value::null = Value::nullSingleton();
Value const& Value::nullRef = Value::nullSingleton();
@@ -2512,17 +2529,20 @@ const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
+const UInt Value::defaultRealPrecision = 17;
+
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
template <typename T, typename U>
static inline bool InRange(double d, T min, U max) {
// The casts can lose precision, but we are looking only for
// an approximate range. Might fail on edge cases though. ~cdunn
- //return d >= static_cast<double>(min) && d <= static_cast<double>(max);
+ // return d >= static_cast<double>(min) && d <= static_cast<double>(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 + static_cast<double>(Int64(value & 1));
+ return static_cast<double>(Int64(value / 2)) * 2.0 +
+ static_cast<double>(Int64(value & 1));
}
template <typename T> static inline double integerToDouble(T value) {
@@ -2542,9 +2562,7 @@ static inline bool InRange(double d, T min, U max) {
* computed using strlen(value).
* @return Pointer on the duplicate instance of string.
*/
-static inline char* duplicateStringValue(const char* value,
- size_t length)
-{
+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 >= static_cast<size_t>(Value::maxInt))
@@ -2552,9 +2570,8 @@ static inline char* duplicateStringValue(const char* value,
char* newString = static_cast<char*>(malloc(length + 1));
if (newString == NULL) {
- throwRuntimeError(
- "in Json::Value::duplicateStringValue(): "
- "Failed to allocate string value buffer");
+ throwRuntimeError("in Json::Value::duplicateStringValue(): "
+ "Failed to allocate string value buffer");
}
memcpy(newString, value, length);
newString[length] = 0;
@@ -2563,31 +2580,30 @@ static inline char* duplicateStringValue(const char* value,
/* Record the length as a prefix.
*/
-static inline char* duplicateAndPrefixStringValue(
- const char* value,
- unsigned int length)
-{
+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 <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U,
+ JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) -
+ sizeof(unsigned) - 1U,
"in Json::Value::duplicateAndPrefixStringValue(): "
"length too big for prefixing");
unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
char* newString = static_cast<char*>(malloc(actualLength));
if (newString == 0) {
- throwRuntimeError(
- "in Json::Value::duplicateAndPrefixStringValue(): "
- "Failed to allocate string value buffer");
+ 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
+ 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)
-{
+inline static void decodePrefixedString(bool isPrefixed,
+ char const* prefixed,
+ unsigned* length,
+ char const** value) {
if (!isPrefixed) {
*length = static_cast<unsigned>(strlen(prefixed));
*value = prefixed;
@@ -2596,7 +2612,8 @@ inline static void decodePrefixedString(
*value = prefixed + sizeof(unsigned);
}
}
-/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
+/** Free the string duplicated by
+ * duplicateStringValue()/duplicateAndPrefixStringValue().
*/
#if JSONCPP_USING_SECURE_MEMORY
static inline void releasePrefixedStringValue(char* value) {
@@ -2609,17 +2626,13 @@ static inline void releasePrefixedStringValue(char* value) {
}
static inline void releaseStringValue(char* value, unsigned length) {
// length==0 => we allocated the strings memory
- size_t size = (length==0) ? strlen(value) : length;
+ size_t size = (length == 0) ? strlen(value) : length;
memset(value, 0, size);
free(value);
}
-#else // !JSONCPP_USING_SECURE_MEMORY
-static inline void releasePrefixedStringValue(char* value) {
- free(value);
-}
-static inline void releaseStringValue(char* value, unsigned) {
- free(value);
-}
+#else // !JSONCPP_USING_SECURE_MEMORY
+static inline void releasePrefixedStringValue(char* value) { free(value); }
+static inline void releaseStringValue(char* value, unsigned) { free(value); }
#endif // JSONCPP_USING_SECURE_MEMORY
} // namespace Json
@@ -2638,27 +2651,15 @@ static inline void releaseStringValue(char* value, unsigned) {
namespace Json {
-Exception::Exception(JSONCPP_STRING const& msg)
- : msg_(msg)
-{}
-Exception::~Exception() JSONCPP_NOEXCEPT
-{}
-char const* Exception::what() const JSONCPP_NOEXCEPT
-{
- return msg_.c_str();
-}
-RuntimeError::RuntimeError(JSONCPP_STRING const& msg)
- : Exception(msg)
-{}
-LogicError::LogicError(JSONCPP_STRING const& msg)
- : Exception(msg)
-{}
-JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
-{
+Exception::Exception(JSONCPP_STRING const& msg) : msg_(msg) {}
+Exception::~Exception() JSONCPP_NOEXCEPT {}
+char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); }
+RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) {}
+LogicError::LogicError(JSONCPP_STRING const& msg) : Exception(msg) {}
+JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) {
throw RuntimeError(msg);
}
-JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
-{
+JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) {
throw LogicError(msg);
}
@@ -2670,8 +2671,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
-Value::CommentInfo::CommentInfo() : comment_(0)
-{}
+Value::CommentInfo::CommentInfo() : comment_(0) {}
Value::CommentInfo::~CommentInfo() {
if (comment_)
@@ -2704,7 +2704,9 @@ void Value::CommentInfo::setComment(const char* text, size_t len) {
Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
-Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
+Value::CZString::CZString(char const* str,
+ unsigned ulength,
+ DuplicationPolicy allocate)
: cstr_(str) {
// allocate != duplicate
storage_.policy_ = allocate & 0x3;
@@ -2713,25 +2715,34 @@ Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy a
Value::CZString::CZString(const CZString& other) {
cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
- ? duplicateStringValue(other.cstr_, other.storage_.length_)
- : other.cstr_);
- storage_.policy_ = static_cast<unsigned>(other.cstr_
- ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
- ? noDuplication : duplicate)
- : static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U;
+ ? duplicateStringValue(other.cstr_, other.storage_.length_)
+ : other.cstr_);
+ storage_.policy_ =
+ static_cast<unsigned>(
+ other.cstr_
+ ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
+ noDuplication
+ ? noDuplication
+ : duplicate)
+ : static_cast<DuplicationPolicy>(other.storage_.policy_)) &
+ 3U;
storage_.length_ = other.storage_.length_;
}
#if JSON_HAS_RVALUE_REFERENCES
Value::CZString::CZString(CZString&& other)
- : cstr_(other.cstr_), index_(other.index_) {
+ : cstr_(other.cstr_), index_(other.index_) {
other.cstr_ = nullptr;
}
#endif
Value::CZString::~CZString() {
if (cstr_ && storage_.policy_ == duplicate) {
- releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary
+ releaseStringValue(const_cast<char*>(cstr_),
+ storage_.length_ + 1u); // +1 for null terminating
+ // character for sake of
+ // completeness but not actually
+ // necessary
}
}
@@ -2740,32 +2751,47 @@ void Value::CZString::swap(CZString& other) {
std::swap(index_, other.index_);
}
-Value::CZString& Value::CZString::operator=(CZString other) {
- swap(other);
+Value::CZString& Value::CZString::operator=(const CZString& other) {
+ cstr_ = other.cstr_;
+ index_ = other.index_;
+ return *this;
+}
+
+#if JSON_HAS_RVALUE_REFERENCES
+Value::CZString& Value::CZString::operator=(CZString&& other) {
+ cstr_ = other.cstr_;
+ index_ = other.index_;
+ other.cstr_ = nullptr;
return *this;
}
+#endif
bool Value::CZString::operator<(const CZString& other) const {
- if (!cstr_) return index_ < other.index_;
- //return strcmp(cstr_, other.cstr_) < 0;
+ 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<unsigned>(this_len, other_len);
JSON_ASSERT(this->cstr_ && other.cstr_);
int comp = memcmp(this->cstr_, other.cstr_, min_len);
- if (comp < 0) return true;
- if (comp > 0) return false;
+ 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;
+ 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;
+ if (this_len != other_len)
+ return false;
JSON_ASSERT(this->cstr_ && other.cstr_);
int comp = memcmp(this->cstr_, other.cstr_, this_len);
return comp == 0;
@@ -2773,10 +2799,12 @@ bool Value::CZString::operator==(const CZString& other) const {
ArrayIndex Value::CZString::index() const { return index_; }
-//const char* Value::CZString::c_str() const { return cstr_; }
+// 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; }
+bool Value::CZString::isStaticString() const {
+ return storage_.policy_ == noDuplication;
+}
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -2846,20 +2874,21 @@ Value::Value(double value) {
Value::Value(const char* value) {
initBasic(stringValue, true);
- JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
- value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
+ JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
+ 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_.string_ = duplicateAndPrefixStringValue(
+ beginValue, static_cast<unsigned>(endValue - beginValue));
}
Value::Value(const JSONCPP_STRING& value) {
initBasic(stringValue, true);
- value_.string_ =
- duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
+ value_.string_ = duplicateAndPrefixStringValue(
+ value.data(), static_cast<unsigned>(value.length()));
}
Value::Value(const StaticString& value) {
@@ -2870,7 +2899,8 @@ Value::Value(const StaticString& value) {
#ifdef JSON_USE_CPPTL
Value::Value(const CppTL::ConstString& value) {
initBasic(stringValue, true);
- value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
+ value_.string_ = duplicateAndPrefixStringValue(
+ value, static_cast<unsigned>(value.length()));
}
#endif
@@ -2879,48 +2909,9 @@ Value::Value(bool value) {
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(const Value& other) {
+ dupPayload(other);
+ dupMeta(other);
}
#if JSON_HAS_RVALUE_REFERENCES
@@ -2932,24 +2923,7 @@ Value::Value(Value&& other) {
#endif
Value::~Value() {
- switch (type_) {
- case nullValue:
- case intValue:
- case uintValue:
- case realValue:
- case booleanValue:
- break;
- case stringValue:
- if (allocated_)
- releasePrefixedStringValue(value_.string_);
- break;
- case arrayValue:
- case objectValue:
- delete value_.map_;
- break;
- default:
- JSON_ASSERT_UNREACHABLE;
- }
+ releasePayload();
delete[] comments_;
@@ -2971,6 +2945,11 @@ void Value::swapPayload(Value& other) {
other.allocated_ = temp2 & 0x1;
}
+void Value::copyPayload(const Value& other) {
+ releasePayload();
+ dupPayload(other);
+}
+
void Value::swap(Value& other) {
swapPayload(other);
std::swap(comments_, other.comments_);
@@ -2978,6 +2957,12 @@ void Value::swap(Value& other) {
std::swap(limit_, other.limit_);
}
+void Value::copy(const Value& other) {
+ copyPayload(other);
+ delete[] comments_;
+ dupMeta(other);
+}
+
ValueType Value::type() const { return type_; }
int Value::compare(const Value& other) const {
@@ -3003,23 +2988,28 @@ bool Value::operator<(const Value& other) const {
return value_.real_ < other.value_.real_;
case booleanValue:
return value_.bool_ < other.value_.bool_;
- case stringValue:
- {
+ case stringValue: {
if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
- if (other.value_.string_) return true;
- else return false;
+ 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);
+ 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<unsigned>(this_len, other_len);
JSON_ASSERT(this_str && other_str);
int comp = memcmp(this_str, other_str, min_len);
- if (comp < 0) return true;
- if (comp > 0) return false;
+ if (comp < 0)
+ return true;
+ if (comp > 0)
+ return false;
return (this_len < other_len);
}
case arrayValue:
@@ -3060,8 +3050,7 @@ bool Value::operator==(const Value& other) const {
return value_.real_ == other.value_.real_;
case booleanValue:
return value_.bool_ == other.value_.bool_;
- case stringValue:
- {
+ case stringValue: {
if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
return (value_.string_ == other.value_.string_);
}
@@ -3069,9 +3058,12 @@ bool Value::operator==(const Value& other) const {
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;
+ 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;
JSON_ASSERT(this_str && other_str);
int comp = memcmp(this_str, other_str, this_len);
return comp == 0;
@@ -3091,28 +3083,34 @@ 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;
+ if (value_.string_ == 0)
+ return 0;
unsigned this_len;
char const* this_str;
- decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
+ &this_str);
return this_str;
}
#if JSONCPP_USING_SECURE_MEMORY
unsigned Value::getCStringLength() const {
JSON_ASSERT_MESSAGE(type_ == stringValue,
- "in Json::Value::asCString(): requires stringValue");
- if (value_.string_ == 0) return 0;
+ "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);
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
+ &this_str);
return this_len;
}
#endif
bool Value::getString(char const** str, char const** cend) const {
- if (type_ != stringValue) return false;
- if (value_.string_ == 0) return false;
+ if (type_ != stringValue)
+ return false;
+ if (value_.string_ == 0)
+ return false;
unsigned length;
decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
*cend = *str + length;
@@ -3123,12 +3121,13 @@ JSONCPP_STRING Value::asString() const {
switch (type_) {
case nullValue:
return "";
- case stringValue:
- {
- if (value_.string_ == 0) 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);
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
+ &this_str);
return JSONCPP_STRING(this_str, this_len);
}
case booleanValue:
@@ -3148,8 +3147,7 @@ JSONCPP_STRING Value::asString() const {
CppTL::ConstString Value::asConstString() const {
unsigned len;
char const* str;
- decodePrefixedString(allocated_, value_.string_,
- &len, &str);
+ decodePrefixedString(allocated_, value_.string_, &len, &str);
return CppTL::ConstString(str, len);
}
#endif
@@ -3328,7 +3326,7 @@ bool Value::isConvertibleTo(ValueType other) const {
case nullValue:
return (isNumeric() && asDouble() == 0.0) ||
(type_ == booleanValue && value_.bool_ == false) ||
- (type_ == stringValue && asString() == "") ||
+ (type_ == stringValue && asString().empty()) ||
(type_ == arrayValue && value_.map_->size() == 0) ||
(type_ == objectValue && value_.map_->size() == 0) ||
type_ == nullValue;
@@ -3387,7 +3385,7 @@ bool Value::empty() const {
return false;
}
-bool Value::operator!() const { return isNull(); }
+Value::operator bool() const { return !isNull(); }
void Value::clear() {
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
@@ -3414,7 +3412,7 @@ void Value::resize(ArrayIndex newSize) {
if (newSize == 0)
clear();
else if (newSize > oldSize)
- (*this)[newSize - 1];
+ this->operator[](newSize - 1);
else {
for (ArrayIndex index = newSize; index < oldSize; ++index) {
value_.map_->erase(index);
@@ -3474,6 +3472,74 @@ void Value::initBasic(ValueType vtype, bool allocated) {
limit_ = 0;
}
+void Value::dupPayload(const Value& other) {
+ type_ = other.type_;
+ allocated_ = false;
+ 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_;
+ }
+ break;
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues(*other.value_.map_);
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+}
+
+void Value::releasePayload() {
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ break;
+ case stringValue:
+ if (allocated_)
+ releasePrefixedStringValue(value_.string_);
+ break;
+ case arrayValue:
+ case objectValue:
+ delete value_.map_;
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+}
+
+void Value::dupMeta(const Value& other) {
+ 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_));
+ }
+ } else {
+ comments_ = 0;
+ }
+ start_ = other.start_;
+ limit_ = other.limit_;
+}
+
// 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.
@@ -3483,8 +3549,8 @@ Value& Value::resolveReference(const char* key) {
"in Json::Value::resolveReference(): requires objectValue");
if (type_ == nullValue)
*this = Value(objectValue);
- CZString actualKey(
- key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
+ 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;
@@ -3496,15 +3562,14 @@ Value& Value::resolveReference(const char* key) {
}
// @param key is not null-terminated.
-Value& Value::resolveReference(char const* key, char const* cend)
-{
+Value& Value::resolveReference(char const* key, char const* cend) {
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>(cend-key), CZString::duplicateOnCopy);
+ CZString actualKey(key, static_cast<unsigned>(cend - key),
+ CZString::duplicateOnCopy);
ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
if (it != value_.map_->end() && (*it).first == actualKey)
return (*it).second;
@@ -3522,27 +3587,29 @@ Value Value::get(ArrayIndex index, const Value& defaultValue) const {
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
-Value const* Value::find(char const* key, char const* cend) 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>(cend-key), CZString::noDuplication);
+Value const* Value::find(char const* key, char const* cend) 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>(cend - key),
+ CZString::noDuplication);
ObjectValues::const_iterator it = value_.map_->find(actualKey);
- if (it == value_.map_->end()) return NULL;
+ if (it == value_.map_->end())
+ return NULL;
return &(*it).second;
}
-const Value& Value::operator[](const char* key) const
-{
+const Value& Value::operator[](const char* key) const {
Value const* found = find(key, key + strlen(key));
- if (!found) return nullSingleton();
+ if (!found)
+ return nullSingleton();
return *found;
}
-Value const& Value::operator[](JSONCPP_STRING const& key) const
-{
+Value const& Value::operator[](JSONCPP_STRING const& key) const {
Value const* found = find(key.data(), key.data() + key.length());
- if (!found) return nullSingleton();
+ if (!found)
+ return nullSingleton();
return *found;
}
@@ -3562,66 +3629,70 @@ Value& Value::operator[](const StaticString& key) {
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& Value::operator[](CppTL::ConstString const& key) const {
Value const* found = find(key.c_str(), key.end_c_str());
- if (!found) return nullSingleton();
+ if (!found)
+ return nullSingleton();
return *found;
}
#endif
Value& Value::append(const Value& value) { return (*this)[size()] = value; }
-Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
-{
+#if JSON_HAS_RVALUE_REFERENCES
+Value& Value::append(Value&& value) {
+ return (*this)[size()] = std::move(value);
+}
+#endif
+
+Value Value::get(char const* key,
+ char const* cend,
+ Value const& defaultValue) const {
Value const* found = find(key, cend);
return !found ? defaultValue : *found;
}
-Value Value::get(char const* key, Value const& defaultValue) const
-{
+Value Value::get(char const* key, Value const& defaultValue) const {
return get(key, key + strlen(key), defaultValue);
}
-Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const
-{
+Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const {
return get(key.data(), key.data() + key.length(), defaultValue);
}
-
-bool Value::removeMember(const char* key, const char* cend, Value* removed)
-{
+bool Value::removeMember(const char* key, const char* cend, Value* removed) {
if (type_ != objectValue) {
return false;
}
- CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
+ CZString actualKey(key, static_cast<unsigned>(cend - key),
+ CZString::noDuplication);
ObjectValues::iterator it = value_.map_->find(actualKey);
if (it == value_.map_->end())
return false;
- *removed = it->second;
+ if (removed)
+#if JSON_HAS_RVALUE_REFERENCES
+ *removed = std::move(it->second);
+#else
+ *removed = it->second;
+#endif
value_.map_->erase(it);
return true;
}
-bool Value::removeMember(const char* key, Value* removed)
-{
+bool Value::removeMember(const char* key, Value* removed) {
return removeMember(key, key + strlen(key), removed);
}
-bool Value::removeMember(JSONCPP_STRING const& key, Value* removed)
-{
+bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) {
return removeMember(key.data(), key.data() + key.length(), removed);
}
-Value Value::removeMember(const char* key)
-{
+void Value::removeMember(const char* key) {
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
"in Json::Value::removeMember(): requires objectValue");
if (type_ == nullValue)
- return nullSingleton();
+ return;
- Value removed; // null
- removeMember(key, key + strlen(key), &removed);
- return removed; // still null if removeMember() did nothing
+ CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
+ value_.map_->erase(actualKey);
}
-Value Value::removeMember(const JSONCPP_STRING& key)
-{
- return removeMember(key.c_str());
+void Value::removeMember(const JSONCPP_STRING& key) {
+ removeMember(key.c_str());
}
bool Value::removeIndex(ArrayIndex index, Value* removed) {
@@ -3636,7 +3707,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) {
*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){
+ for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
CZString keey(i);
(*value_.map_)[keey] = (*this)[i + 1];
}
@@ -3654,17 +3725,14 @@ Value Value::get(const CppTL::ConstString& key,
}
#endif
-bool Value::isMember(char const* key, char const* cend) const
-{
+bool Value::isMember(char const* key, char const* cend) const {
Value const* value = find(key, cend);
return NULL != value;
}
-bool Value::isMember(char const* key) const
-{
+bool Value::isMember(char const* key) const {
return isMember(key, key + strlen(key));
}
-bool Value::isMember(JSONCPP_STRING const& key) const
-{
+bool Value::isMember(JSONCPP_STRING const& key) const {
return isMember(key.data(), key.data() + key.length());
}
@@ -3685,8 +3753,7 @@ Value::Members Value::getMemberNames() const {
ObjectValues::const_iterator it = value_.map_->begin();
ObjectValues::const_iterator itEnd = value_.map_->end();
for (; it != itEnd; ++it) {
- members.push_back(JSONCPP_STRING((*it).first.data(),
- (*it).first.length()));
+ members.push_back(JSONCPP_STRING((*it).first.data(), (*it).first.length()));
}
return members;
}
@@ -3808,14 +3875,30 @@ bool Value::isUInt64() const {
}
bool Value::isIntegral() const {
+ switch (type_) {
+ case intValue:
+ case uintValue:
+ return true;
+ case realValue:
#if defined(JSON_HAS_INT64)
- return isInt64() || isUInt64();
+ // 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_ >= double(minInt64) &&
+ value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
#else
- return isInt() || isUInt();
-#endif
+ return value_.real_ >= minInt && value_.real_ <= maxUInt &&
+ IsIntegral(value_.real_);
+#endif // JSON_HAS_INT64
+ default:
+ break;
+ }
+ return false;
}
-bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; }
+bool Value::isDouble() const {
+ return type_ == intValue || type_ == uintValue || type_ == realValue;
+}
bool Value::isNumeric() const { return isDouble(); }
@@ -3825,10 +3908,12 @@ 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) {
+void Value::setComment(const char* comment,
+ size_t len,
+ CommentPlacement placement) {
if (!comments_)
comments_ = new CommentInfo[numberOfCommentPlacement];
- if ((len > 0) && (comment[len-1] == '\n')) {
+ if ((len > 0) && (comment[len - 1] == '\n')) {
// Always discard trailing newline, to aid indentation.
len -= 1;
}
@@ -3839,7 +3924,8 @@ void Value::setComment(const char* comment, CommentPlacement placement) {
setComment(comment, strlen(comment), placement);
}
-void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) {
+void Value::setComment(const JSONCPP_STRING& comment,
+ CommentPlacement placement) {
setComment(comment.c_str(), comment.length(), placement);
}
@@ -3862,8 +3948,13 @@ ptrdiff_t Value::getOffsetStart() const { return start_; }
ptrdiff_t Value::getOffsetLimit() const { return limit_; }
JSONCPP_STRING Value::toStyledString() const {
- StyledWriter writer;
- return writer.write(*this);
+ StreamWriterBuilder builder;
+
+ JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : "";
+ out += Json::writeString(builder, *this);
+ out += "\n";
+
+ return out;
}
Value::const_iterator Value::begin() const {
@@ -3942,6 +4033,7 @@ Path::Path(const JSONCPP_STRING& path,
const PathArgument& a4,
const PathArgument& a5) {
InArgs in;
+ in.reserve(5);
in.push_back(&a1);
in.push_back(&a2);
in.push_back(&a3);
@@ -4077,74 +4169,83 @@ Value& Path::make(Value& root) const {
// Beginning of content of file: src/lib_json/json_writer.cpp
// //////////////////////////////////////////////////////////////////////
-// Copyright 2011 Baptiste Lepilleur
+// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#if !defined(JSON_IS_AMALGAMATION)
-#include <json/writer.h>
#include "json_tool.h"
+#include <json/writer.h>
#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <cassert>
+#include <cstring>
#include <iomanip>
#include <memory>
+#include <set>
#include <sstream>
#include <utility>
-#include <set>
-#include <cassert>
-#include <cstring>
+
+#if __cplusplus >= 201103L
+#include <cmath>
#include <cstdio>
-#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
+#if !defined(isnan)
+#define isnan std::isnan
+#endif
+
+#if !defined(isfinite)
+#define isfinite std::isfinite
+#endif
+
+#if !defined(snprintf)
+#define snprintf std::snprintf
+#endif
+#else
+#include <math.h>
+#include <stdio.h>
+
+#if defined(_MSC_VER)
+#if !defined(isnan)
+#include <float.h>
+#define isnan _isnan
+#endif
+
+#if !defined(isfinite)
#include <float.h>
#define isfinite _finite
-#elif defined(__sun) && defined(__SVR4) //Solaris
+#endif
+
+#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
+#if !defined(snprintf)
+#define snprintf _snprintf
+#endif
+#endif
+
+#if defined(__sun) && defined(__SVR4) // Solaris
#if !defined(isfinite)
#include <ieeefp.h>
#define isfinite finite
#endif
-#elif defined(_AIX)
-#if !defined(isfinite)
-#include <math.h>
-#define isfinite finite
#endif
-#elif defined(__hpux)
+
+#if defined(__hpux)
#if !defined(isfinite)
#if defined(__ia64) && !defined(finite)
-#define isfinite(x) ((sizeof(x) == sizeof(float) ? \
- _Isfinitef(x) : _IsFinite(x)))
-#else
-#include <math.h>
-#define isfinite finite
+#define isfinite(x) \
+ ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x)))
#endif
#endif
-#else
-#include <cmath>
-#if !(defined(__QNXNTO__)) // QNX already defines isfinite
-#define isfinite std::isfinite
-#endif
#endif
-#if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
-#define snprintf sprintf_s
-#elif _MSC_VER >= 1900 // VC++ 14.0 and above
-#define snprintf std::snprintf
-#else
-#define snprintf _snprintf
-#endif
-#elif defined(__ANDROID__) || defined(__QNXNTO__)
-#define snprintf snprintf
-#elif __cplusplus >= 201103L
-#if !defined(__MINGW32__) && !defined(__CYGWIN__)
-#define snprintf std::snprintf
-#endif
+#if !defined(isnan)
+// IEEE standard states that NaN values will not compare to themselves
+#define isnan(x) (x != x)
#endif
-#if defined(__BORLANDC__)
-#include <float.h>
-#define isfinite _finite
-#define snprintf _snprintf
+#if !defined(isfinite)
+#define isfinite finite
+#endif
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
@@ -4157,27 +4258,9 @@ namespace Json {
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
#else
-typedef std::auto_ptr<StreamWriter> StreamWriterPtr;
+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;
-}
-
JSONCPP_STRING valueToString(LargestInt value) {
UIntToStringBuffer buffer;
char* current = buffer + sizeof(buffer);
@@ -4215,136 +4298,161 @@ JSONCPP_STRING valueToString(UInt value) {
#endif // # if defined(JSON_HAS_INT64)
namespace {
-JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) {
- // Allocate a buffer that is more than large enough to store the 16 digits of
- // precision requested below.
- char buffer[36];
- int len = -1;
-
- char formatString[6];
- sprintf(formatString, "%%.%dg", precision);
-
+JSONCPP_STRING valueToString(double value,
+ bool useSpecialFloats,
+ unsigned int precision,
+ PrecisionType precisionType) {
// Print into the buffer. We need not request the alternative representation
- // that always has a decimal point because JSON doesn't distingish the
+ // that always has a decimal point because JSON doesn't distinguish the
// concepts of reals and integers.
- if (isfinite(value)) {
- len = snprintf(buffer, sizeof(buffer), formatString, value);
-
- // try to ensure we preserve the fact that this was given to us as a double on input
- if (!strstr(buffer, ".") && !strstr(buffer, "e")) {
- strcat(buffer, ".0");
- }
+ if (!isfinite(value)) {
+ static const char* const reps[2][3] = { { "NaN", "-Infinity", "Infinity" },
+ { "null", "-1e+9999", "1e+9999" } };
+ return reps[useSpecialFloats ? 0 : 1]
+ [isnan(value) ? 0 : (value < 0) ? 1 : 2];
+ }
- } else {
- // IEEE standard states that NaN values will not compare to themselves
- if (value != value) {
- len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null");
- } else if (value < 0) {
- len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999");
- } else {
- len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
+ JSONCPP_STRING buffer(size_t(36), '\0');
+ while (true) {
+ int len = snprintf(
+ &*buffer.begin(), buffer.size(),
+ (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
+ precision, value);
+ assert(len >= 0);
+ size_t wouldPrint = static_cast<size_t>(len);
+ if (wouldPrint >= buffer.size()) {
+ buffer.resize(wouldPrint + 1);
+ continue;
}
- // For those, we do not need to call fixNumLoc, but it is fast.
+ buffer.resize(wouldPrint);
+ break;
+ }
+
+ buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
+
+ // strip the zero padding from the right
+ if (precisionType == PrecisionType::decimalPlaces) {
+ buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
+ }
+
+ // try to ensure we preserve the fact that this was given to us as a double on
+ // input
+ if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
+ buffer += ".0";
}
- assert(len >= 0);
- fixNumericLocale(buffer, buffer + len);
return buffer;
}
-}
+} // namespace
-JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); }
+JSONCPP_STRING valueToString(double value,
+ unsigned int precision,
+ PrecisionType precisionType) {
+ return valueToString(value, false, precision, precisionType);
+}
JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; }
-JSONCPP_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 JSONCPP_STRING("\"") + value + "\"";
- // We have to walk value and escape any special characters.
- // Appending to JSONCPP_STRING is not efficient, but this should be rare.
- // (Note: forward slashes are *not* rare, but I am not escaping them.)
- JSONCPP_STRING::size_type maxsize =
- strlen(value) * 2 + 3; // allescaped+quotes+NULL
- JSONCPP_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)) {
- JSONCPP_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;
- }
+static bool isAnyCharRequiredQuoting(char const* s, size_t n) {
+ assert(s || !n);
+
+ char const* const end = s + n;
+ for (char const* cur = s; cur < end; ++cur) {
+ if (*cur == '\\' || *cur == '\"' || *cur < ' ' ||
+ static_cast<unsigned char>(*cur) < 0x80)
+ return true;
}
- result += "\"";
- return result;
+ return false;
}
-// 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);
+static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
+ const unsigned int REPLACEMENT_CHARACTER = 0xFFFD;
- 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;
- }
- }
+ unsigned int firstByte = static_cast<unsigned char>(*s);
+
+ if (firstByte < 0x80)
+ return firstByte;
+
+ if (firstByte < 0xE0) {
+ if (e - s < 2)
+ return REPLACEMENT_CHARACTER;
+
+ unsigned int calculated =
+ ((firstByte & 0x1F) << 6) | (static_cast<unsigned int>(s[1]) & 0x3F);
+ s += 1;
+ // oversized encoded characters are invalid
+ return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
+ }
+
+ if (firstByte < 0xF0) {
+ if (e - s < 3)
+ return REPLACEMENT_CHARACTER;
+
+ unsigned int calculated = ((firstByte & 0x0F) << 12) |
+ ((static_cast<unsigned int>(s[1]) & 0x3F) << 6) |
+ (static_cast<unsigned int>(s[2]) & 0x3F);
+ s += 2;
+ // surrogates aren't valid codepoints itself
+ // shouldn't be UTF-8 encoded
+ if (calculated >= 0xD800 && calculated <= 0xDFFF)
+ return REPLACEMENT_CHARACTER;
+ // oversized encoded characters are invalid
+ return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated;
}
- return NULL;
+
+ if (firstByte < 0xF8) {
+ if (e - s < 4)
+ return REPLACEMENT_CHARACTER;
+
+ unsigned int calculated = ((firstByte & 0x07) << 18) |
+ ((static_cast<unsigned int>(s[1]) & 0x3F) << 12) |
+ ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) |
+ (static_cast<unsigned int>(s[3]) & 0x3F);
+ s += 3;
+ // oversized encoded characters are invalid
+ return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
+ }
+
+ return REPLACEMENT_CHARACTER;
}
+
+static const char hex2[] = "000102030405060708090a0b0c0d0e0f"
+ "101112131415161718191a1b1c1d1e1f"
+ "202122232425262728292a2b2c2d2e2f"
+ "303132333435363738393a3b3c3d3e3f"
+ "404142434445464748494a4b4c4d4e4f"
+ "505152535455565758595a5b5c5d5e5f"
+ "606162636465666768696a6b6c6d6e6f"
+ "707172737475767778797a7b7c7d7e7f"
+ "808182838485868788898a8b8c8d8e8f"
+ "909192939495969798999a9b9c9d9e9f"
+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
+ "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
+ "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
+
+static JSONCPP_STRING toHex16Bit(unsigned int x) {
+ const unsigned int hi = (x >> 8) & 0xff;
+ const unsigned int lo = x & 0xff;
+ JSONCPP_STRING result(4, ' ');
+ result[0] = hex2[2 * hi];
+ result[1] = hex2[2 * hi + 1];
+ result[2] = hex2[2 * lo];
+ result[3] = hex2[2 * lo + 1];
+ return result;
+}
+
static JSONCPP_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))
+
+ if (!isAnyCharRequiredQuoting(value, length))
return JSONCPP_STRING("\"") + value + "\"";
// We have to walk value and escape any special characters.
// Appending to JSONCPP_STRING is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
- JSONCPP_STRING::size_type maxsize =
- length * 2 + 3; // allescaped+quotes+NULL
+ JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL
JSONCPP_STRING result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
@@ -4380,22 +4488,34 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
// sequence.
// Should add a flag to allow this compatibility mode and prevent this
// sequence from occurring.
- default:
- if ((isControlCharacter(*c)) || (*c == 0)) {
- JSONCPP_OSTRINGSTREAM oss;
- oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
- << std::setw(4) << static_cast<int>(*c);
- result += oss.str();
- } else {
- result += *c;
+ default: {
+ unsigned int cp = utf8ToCodepoint(c, end);
+ // don't escape non-control characters
+ // (short escape sequence are applied above)
+ if (cp < 0x80 && cp >= 0x20)
+ result += static_cast<char>(cp);
+ else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
+ result += "\\u";
+ result += toHex16Bit(cp);
+ } else { // codepoint is not in Basic Multilingual Plane
+ // convert to surrogate pair first
+ cp -= 0x10000;
+ result += "\\u";
+ result += toHex16Bit((cp >> 10) + 0xD800);
+ result += "\\u";
+ result += toHex16Bit((cp & 0x3FF) + 0xDC00);
}
- break;
+ } break;
}
}
result += "\"";
return result;
}
+JSONCPP_STRING valueToQuotedString(const char* value) {
+ return valueToQuotedStringN(value, static_cast<unsigned int>(strlen(value)));
+}
+
// Class Writer
// //////////////////////////////////////////////////////////////////
Writer::~Writer() {}
@@ -4404,17 +4524,17 @@ Writer::~Writer() {}
// //////////////////////////////////////////////////////////////////
FastWriter::FastWriter()
- : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
+ : yamlCompatibilityEnabled_(false), dropNullPlaceholders_(false),
omitEndingLineFeed_(false) {}
-void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
+void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; }
void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
JSONCPP_STRING FastWriter::write(const Value& root) {
- document_ = "";
+ document_.clear();
writeValue(root);
if (!omitEndingLineFeed_)
document_ += "\n";
@@ -4436,13 +4556,13 @@ void FastWriter::writeValue(const Value& value) {
case realValue:
document_ += valueToString(value.asDouble());
break;
- case stringValue:
- {
+ case stringValue: {
// Is NULL possible for value.string_? No.
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
- if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
+ if (ok)
+ document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str));
break;
}
case booleanValue:
@@ -4466,8 +4586,9 @@ void FastWriter::writeValue(const Value& value) {
const JSONCPP_STRING& name = *it;
if (it != members.begin())
document_ += ',';
- document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
- document_ += yamlCompatiblityEnabled_ ? ": " : ":";
+ document_ += valueToQuotedStringN(name.data(),
+ static_cast<unsigned>(name.length()));
+ document_ += yamlCompatibilityEnabled_ ? ": " : ":";
writeValue(value[name]);
}
document_ += '}';
@@ -4482,9 +4603,9 @@ StyledWriter::StyledWriter()
: rightMargin_(74), indentSize_(3), addChildValues_() {}
JSONCPP_STRING StyledWriter::write(const Value& root) {
- document_ = "";
+ document_.clear();
addChildValues_ = false;
- indentString_ = "";
+ indentString_.clear();
writeCommentBeforeValue(root);
writeValue(root);
writeCommentAfterValueOnSameLine(root);
@@ -4506,14 +4627,15 @@ void StyledWriter::writeValue(const Value& value) {
case realValue:
pushValue(valueToString(value.asDouble()));
break;
- case stringValue:
- {
+ case stringValue: {
// Is NULL possible for value.string_? No.
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
- if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
- else pushValue("");
+ if (ok)
+ pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
+ else
+ pushValue("");
break;
}
case booleanValue:
@@ -4556,7 +4678,7 @@ void StyledWriter::writeArrayValue(const Value& value) {
if (size == 0)
pushValue("[]");
else {
- bool isArrayMultiLine = isMultineArray(value);
+ bool isArrayMultiLine = isMultilineArray(value);
if (isArrayMultiLine) {
writeWithIndent("[");
indent();
@@ -4594,14 +4716,14 @@ void StyledWriter::writeArrayValue(const Value& value) {
}
}
-bool StyledWriter::isMultineArray(const Value& value) {
+bool StyledWriter::isMultilineArray(const Value& value) {
ArrayIndex const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
const Value& childValue = value[index];
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
- childValue.size() > 0);
+ childValue.size() > 0);
}
if (!isMultiLine) // check if line length > max line length
{
@@ -4644,7 +4766,9 @@ void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) {
document_ += value;
}
-void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); }
+void StyledWriter::indent() {
+ indentString_ += JSONCPP_STRING(indentSize_, ' ');
+}
void StyledWriter::unindent() {
assert(indentString_.size() >= indentSize_);
@@ -4661,8 +4785,7 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) {
JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) {
document_ += *iter;
- if (*iter == '\n' &&
- (iter != comment.end() && *(iter + 1) == '/'))
+ if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
writeIndent();
++iter;
}
@@ -4691,17 +4814,18 @@ bool StyledWriter::hasCommentForValue(const Value& value) {
// Class StyledStreamWriter
// //////////////////////////////////////////////////////////////////
-StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
+StyledStreamWriter::StyledStreamWriter(const JSONCPP_STRING& indentation)
: document_(NULL), rightMargin_(74), indentation_(indentation),
- addChildValues_() {}
+ addChildValues_(), indented_(false) {}
void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
document_ = &out;
addChildValues_ = false;
- indentString_ = "";
+ indentString_.clear();
indented_ = true;
writeCommentBeforeValue(root);
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
indented_ = true;
writeValue(root);
writeCommentAfterValueOnSameLine(root);
@@ -4723,14 +4847,15 @@ void StyledStreamWriter::writeValue(const Value& value) {
case realValue:
pushValue(valueToString(value.asDouble()));
break;
- case stringValue:
- {
+ case stringValue: {
// Is NULL possible for value.string_? No.
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
- if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
- else pushValue("");
+ if (ok)
+ pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
+ else
+ pushValue("");
break;
}
case booleanValue:
@@ -4773,7 +4898,7 @@ void StyledStreamWriter::writeArrayValue(const Value& value) {
if (size == 0)
pushValue("[]");
else {
- bool isArrayMultiLine = isMultineArray(value);
+ bool isArrayMultiLine = isMultilineArray(value);
if (isArrayMultiLine) {
writeWithIndent("[");
indent();
@@ -4785,7 +4910,8 @@ void StyledStreamWriter::writeArrayValue(const Value& value) {
if (hasChildValue)
writeWithIndent(childValues_[index]);
else {
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
indented_ = true;
writeValue(childValue);
indented_ = false;
@@ -4813,14 +4939,14 @@ void StyledStreamWriter::writeArrayValue(const Value& value) {
}
}
-bool StyledStreamWriter::isMultineArray(const Value& value) {
+bool StyledStreamWriter::isMultilineArray(const Value& value) {
ArrayIndex const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
const Value& childValue = value[index];
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
- childValue.size() > 0);
+ childValue.size() > 0);
}
if (!isMultiLine) // check if line length > max line length
{
@@ -4856,7 +4982,8 @@ void StyledStreamWriter::writeIndent() {
}
void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) {
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
*document_ << value;
indented_ = false;
}
@@ -4872,13 +4999,13 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
if (!root.hasComment(commentBefore))
return;
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) {
*document_ << *iter;
- if (*iter == '\n' &&
- (iter != comment.end() && *(iter + 1) == '/'))
+ if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
// writeIndent(); // would include newline
*document_ << indentString_;
++iter;
@@ -4910,27 +5037,27 @@ bool StyledStreamWriter::hasCommentForValue(const Value& value) {
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.
+ None, ///< Drop all comments.
+ Most, ///< Recover odd behavior of previous versions (not implemented yet).
+ All ///< Keep all comments.
};
};
-struct BuiltStyledStreamWriter : public StreamWriter
-{
- BuiltStyledStreamWriter(
- JSONCPP_STRING const& indentation,
- CommentStyle::Enum cs,
- JSONCPP_STRING const& colonSymbol,
- JSONCPP_STRING const& nullSymbol,
- JSONCPP_STRING const& endingLineFeedSymbol,
- bool useSpecialFloats,
- unsigned int precision);
+struct BuiltStyledStreamWriter : public StreamWriter {
+ BuiltStyledStreamWriter(JSONCPP_STRING const& indentation,
+ CommentStyle::Enum cs,
+ JSONCPP_STRING const& colonSymbol,
+ JSONCPP_STRING const& nullSymbol,
+ JSONCPP_STRING const& endingLineFeedSymbol,
+ bool useSpecialFloats,
+ unsigned int precision,
+ PrecisionType precisionType);
int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
+
private:
void writeValue(Value const& value);
void writeArrayValue(Value const& value);
- bool isMultineArray(Value const& value);
+ bool isMultilineArray(Value const& value);
void pushValue(JSONCPP_STRING const& value);
void writeIndent();
void writeWithIndent(JSONCPP_STRING const& value);
@@ -4954,35 +5081,30 @@ private:
bool indented_ : 1;
bool useSpecialFloats_ : 1;
unsigned int precision_;
+ PrecisionType precisionType_;
};
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
- JSONCPP_STRING const& indentation,
- CommentStyle::Enum cs,
- JSONCPP_STRING const& colonSymbol,
- JSONCPP_STRING const& nullSymbol,
- JSONCPP_STRING const& endingLineFeedSymbol,
- bool useSpecialFloats,
- unsigned int precision)
- : rightMargin_(74)
- , indentation_(indentation)
- , cs_(cs)
- , colonSymbol_(colonSymbol)
- , nullSymbol_(nullSymbol)
- , endingLineFeedSymbol_(endingLineFeedSymbol)
- , addChildValues_(false)
- , indented_(false)
- , useSpecialFloats_(useSpecialFloats)
- , precision_(precision)
-{
-}
-int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
-{
+ JSONCPP_STRING const& indentation,
+ CommentStyle::Enum cs,
+ JSONCPP_STRING const& colonSymbol,
+ JSONCPP_STRING const& nullSymbol,
+ JSONCPP_STRING const& endingLineFeedSymbol,
+ bool useSpecialFloats,
+ unsigned int precision,
+ PrecisionType precisionType)
+ : rightMargin_(74), indentation_(indentation), cs_(cs),
+ colonSymbol_(colonSymbol), nullSymbol_(nullSymbol),
+ endingLineFeedSymbol_(endingLineFeedSymbol), addChildValues_(false),
+ indented_(false), useSpecialFloats_(useSpecialFloats),
+ precision_(precision), precisionType_(precisionType) {}
+int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) {
sout_ = sout;
addChildValues_ = false;
indented_ = true;
- indentString_ = "";
+ indentString_.clear();
writeCommentBeforeValue(root);
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
indented_ = true;
writeValue(root);
writeCommentAfterValueOnSameLine(root);
@@ -5002,16 +5124,18 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
pushValue(valueToString(value.asLargestUInt()));
break;
case realValue:
- pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));
+ pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_,
+ precisionType_));
break;
- case stringValue:
- {
+ case stringValue: {
// Is NULL is possible for value.string_? No.
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
- if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
- else pushValue("");
+ if (ok)
+ pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
+ else
+ pushValue("");
break;
}
case booleanValue:
@@ -5032,7 +5156,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
JSONCPP_STRING const& name = *it;
Value const& childValue = value[name];
writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
+ writeWithIndent(valueToQuotedStringN(
+ name.data(), static_cast<unsigned>(name.length())));
*sout_ << colonSymbol_;
writeValue(childValue);
if (++it == members.end()) {
@@ -5054,7 +5179,7 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
if (size == 0)
pushValue("[]");
else {
- bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
+ bool isMultiLine = (cs_ == CommentStyle::All) || isMultilineArray(value);
if (isMultiLine) {
writeWithIndent("[");
indent();
@@ -5066,7 +5191,8 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
if (hasChildValue)
writeWithIndent(childValues_[index]);
else {
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
indented_ = true;
writeValue(childValue);
indented_ = false;
@@ -5084,26 +5210,28 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
{
assert(childValues_.size() == size);
*sout_ << "[";
- if (!indentation_.empty()) *sout_ << " ";
+ if (!indentation_.empty())
+ *sout_ << " ";
for (unsigned index = 0; index < size; ++index) {
if (index > 0)
*sout_ << ((!indentation_.empty()) ? ", " : ",");
*sout_ << childValues_[index];
}
- if (!indentation_.empty()) *sout_ << " ";
+ if (!indentation_.empty())
+ *sout_ << " ";
*sout_ << "]";
}
}
}
-bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
+bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) {
ArrayIndex const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
Value const& childValue = value[index];
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
- childValue.size() > 0);
+ childValue.size() > 0);
}
if (!isMultiLine) // check if line length > max line length
{
@@ -5143,7 +5271,8 @@ void BuiltStyledStreamWriter::writeIndent() {
}
void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) {
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
*sout_ << value;
indented_ = false;
}
@@ -5156,17 +5285,18 @@ void BuiltStyledStreamWriter::unindent() {
}
void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
- if (cs_ == CommentStyle::None) return;
+ if (cs_ == CommentStyle::None)
+ return;
if (!root.hasComment(commentBefore))
return;
- if (!indented_) writeIndent();
+ if (!indented_)
+ writeIndent();
const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) {
*sout_ << *iter;
- if (*iter == '\n' &&
- (iter != comment.end() && *(iter + 1) == '/'))
+ if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
// writeIndent(); // would write extra newline
*sout_ << indentString_;
++iter;
@@ -5174,8 +5304,10 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
indented_ = false;
}
-void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
- if (cs_ == CommentStyle::None) return;
+void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
+ Value const& root) {
+ if (cs_ == CommentStyle::None)
+ return;
if (root.hasComment(commentAfterOnSameLine))
*sout_ << " " + root.getComment(commentAfterOnSameLine);
@@ -5195,28 +5327,18 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
///////////////
// StreamWriter
-StreamWriter::StreamWriter()
- : sout_(NULL)
-{
-}
-StreamWriter::~StreamWriter()
-{
-}
-StreamWriter::Factory::~Factory()
-{}
-StreamWriterBuilder::StreamWriterBuilder()
-{
- setDefaults(&settings_);
-}
-StreamWriterBuilder::~StreamWriterBuilder()
-{}
-StreamWriter* StreamWriterBuilder::newStreamWriter() const
-{
+StreamWriter::StreamWriter() : sout_(NULL) {}
+StreamWriter::~StreamWriter() {}
+StreamWriter::Factory::~Factory() {}
+StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); }
+StreamWriterBuilder::~StreamWriterBuilder() {}
+StreamWriter* StreamWriterBuilder::newStreamWriter() const {
JSONCPP_STRING indentation = settings_["indentation"].asString();
JSONCPP_STRING cs_str = settings_["commentStyle"].asString();
+ JSONCPP_STRING pt_str = settings_["precisionType"].asString();
bool eyc = settings_["enableYAMLCompatibility"].asBool();
bool dnp = settings_["dropNullPlaceholders"].asBool();
- bool usf = settings_["useSpecialFloats"].asBool();
+ bool usf = settings_["useSpecialFloats"].asBool();
unsigned int pre = settings_["precision"].asUInt();
CommentStyle::Enum cs = CommentStyle::All;
if (cs_str == "All") {
@@ -5226,6 +5348,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
} else {
throwRuntimeError("commentStyle must be 'All' or 'None'");
}
+ PrecisionType precisionType(significantDigits);
+ if (pt_str == "significant") {
+ precisionType = PrecisionType::significantDigits;
+ } else if (pt_str == "decimal") {
+ precisionType = PrecisionType::decimalPlaces;
+ } else {
+ throwRuntimeError("precisionType must be 'significant' or 'decimal'");
+ }
JSONCPP_STRING colonSymbol = " : ";
if (eyc) {
colonSymbol = ": ";
@@ -5234,16 +5364,16 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
}
JSONCPP_STRING nullSymbol = "null";
if (dnp) {
- nullSymbol = "";
+ nullSymbol.clear();
}
- if (pre > 17) pre = 17;
- JSONCPP_STRING endingLineFeedSymbol = "";
- return new BuiltStyledStreamWriter(
- indentation, cs,
- colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
+ if (pre > 17)
+ pre = 17;
+ JSONCPP_STRING endingLineFeedSymbol;
+ return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol,
+ endingLineFeedSymbol, usf, pre,
+ precisionType);
}
-static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
-{
+static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys) {
valid_keys->clear();
valid_keys->insert("indentation");
valid_keys->insert("commentStyle");
@@ -5251,11 +5381,12 @@ static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
valid_keys->insert("dropNullPlaceholders");
valid_keys->insert("useSpecialFloats");
valid_keys->insert("precision");
+ valid_keys->insert("precisionType");
}
-bool StreamWriterBuilder::validate(Json::Value* invalid) const
-{
+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
+ if (!invalid)
+ invalid = &my_invalid; // so we do not need to test for NULL
Json::Value& inv = *invalid;
std::set<JSONCPP_STRING> valid_keys;
getValidWriterKeys(&valid_keys);
@@ -5269,13 +5400,11 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const
}
return 0u == inv.size();
}
-Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
-{
+Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) {
return settings_[key];
}
// static
-void StreamWriterBuilder::setDefaults(Json::Value* settings)
-{
+void StreamWriterBuilder::setDefaults(Json::Value* settings) {
//! [StreamWriterBuilderDefaults]
(*settings)["commentStyle"] = "All";
(*settings)["indentation"] = "\t";
@@ -5283,10 +5412,12 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
(*settings)["dropNullPlaceholders"] = false;
(*settings)["useSpecialFloats"] = false;
(*settings)["precision"] = 17;
+ (*settings)["precisionType"] = "significant";
//! [StreamWriterBuilderDefaults]
}
-JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) {
+JSONCPP_STRING writeString(StreamWriter::Factory const& builder,
+ Value const& root) {
JSONCPP_OSTRINGSTREAM sout;
StreamWriterPtr const writer(builder.newStreamWriter());
writer->write(root, &sout);