Compare commits

..

108 Commits
0.y.z ... 1.7.0

Author SHA1 Message Date
Christopher Dunn
c018d9fc3a Merge pull request #442 from open-source-parsers/JSONCPP_STRING
Secure allocator available for wiping memory.

Resolves #437.
Resolves #152.
2016-03-19 19:30:30 -05:00
dawesc
ae564653c4 -DJSONCPP_USE_SECURE_MEMORY=1 for cmake
Add allocator.h to amalgamated header
Test JSONCPP_USE_SECURE_MEMORY in Travis
2016-03-19 19:21:15 -05:00
dawesc
f8674c63b1 allocator.h 2016-03-19 14:37:30 -05:00
dawesc
b50a124fa6 .gitignore for eclipse 2016-03-19 14:37:30 -05:00
Christopher Dunn
59e327f50b Merge pull request #445 from ya1gaurav/patch-36
Added NORETURN for throw functions.
2016-03-17 20:54:26 -05:00
Gaurav
0b597b4b48 Added NORETURN for throw functions.
Fix in definition also.
2016-03-16 11:17:21 +05:30
Gaurav
d97ea5bf8d Added NORETURN for throw functions.
Resolve Issue - https://github.com/open-source-parsers/jsoncpp/issues/389
2016-03-16 11:15:09 +05:30
Christopher Dunn
e29b671ed5 Merge pull request #444 from ya1gaurav/patch-35
Supporting GCC 6.0

Resolves #411.
2016-03-15 19:23:17 -05:00
Gaurav
fbe1cf3916 Supporting GCC 6.0
Fixes test with GCC-6.0
2016-03-15 18:33:34 +05:30
Gaurav
cf86c473a5 Supporting GCC 6.0
This patch is also needed to build success for GCC 6.0.
Refer issue - https://github.com/open-source-parsers/jsoncpp/issues/411
2016-03-15 18:31:44 +05:30
Christopher Dawes
75570d7068 Fixing up for #define instead of typedef in secure allocators 2016-03-14 19:15:17 -05:00
Christopher Dunn
5da29e2707 Another shot at #411 2016-03-14 18:35:53 -05:00
Christopher Dunn
c80faa400c Merge pull request #438 from ya1gaurav/patch-34
MinGW support while building as DLL

Fixed #434.
2016-03-12 14:40:19 -06:00
Gaurav
8aabf93cc1 MinGW support while building as DLL
__MINGW32__ is appropriate to support for MinGW
2016-03-08 17:34:22 +05:30
Gaurav
3e51598176 MinGW support while building as DLL
This is PR for https://github.com/open-source-parsers/jsoncpp/issues/434
It will fix reported build error.
2016-03-08 17:17:42 +05:30
Christopher Dunn
1b5e61d008 Merge pull request #435 from cdunn2001/JSONCPP_STRING
JSONCPP_STRING etc.
2016-03-06 12:43:47 -06:00
Christopher Dunn
b84e0c159d JSONCPP_ISTREAM 2016-03-06 11:56:39 -06:00
Christopher Dunn
1e990640a9 JSONCPP_ISTRINGSTREAM 2016-03-06 11:56:39 -06:00
Christopher Dunn
38bb491400 JSONCPP_OSTRINGSTREAM 2016-03-06 11:56:38 -06:00
Christopher Dunn
724ba29bd3 JSONCPP_OSTREAM 2016-03-06 11:56:38 -06:00
Christopher Dunn
de5b792168 JSONCPP_STRING 2016-03-06 11:56:38 -06:00
Christopher Dunn
1b8e3b7f4d Merge pull request #432 from ya1gaurav/patch-33
Avoid passing Null to memcmp

hopefully resolves #404
2016-03-02 14:27:03 -06:00
Gaurav
4878913143 Avoid passing Null to memcmp
As per discussion in - https://github.com/open-source-parsers/jsoncpp/issues/404
Null should not be pass to memcmp, it may show undesired behaviour, so avoid doing that using assertion.
Also, changed one direct "assert" to JSON_ASSERT - it will be decided if exceptions are used or not.
2016-03-01 14:13:28 +05:30
Christopher Dunn
d179e24c14 Merge pull request #429 from tmaciejewski/remove_c_style_casting
remove C-style casting
2016-02-29 23:20:07 -06:00
Tomasz Maciejewski
ccd70540e3 remove C-style casting 2016-02-28 12:56:04 +01:00
Christopher Dunn
b4d2b65841 Merge pull request #418 from Techwolfy/master
std::snprintf fix for Cygwin
2016-02-10 21:17:31 -06:00
Techwolf
7e46bf76e8 std::snprintf fix for Cygwin 2016-02-10 17:09:32 -08:00
Christopher Dunn
da0c50f7b2 Merge pull request #416 from cdunn2001/fix-gcc6-errors
Fix gcc6 errors
2016-02-07 11:40:50 -06:00
Christopher Dunn
02bc3d77de This *might* fix the last gcc-6 error.
See https://github.com/open-source-parsers/jsoncpp/issues/411#issuecomment-180974558

I was unable to produce a warning in Clang, so I am not certain. But based on a [SO answer](http://stackoverflow.com/questions/25480059/gcc-conversion-warning-when-assigning-to-a-bitfield), I think I've fixed the following:
```
/tmp/jsoncpp/src/lib_json/json_value.cpp: In copy constructor 'Json::Value::CZString::CZString(const Json::Value::CZString&)':
/tmp/jsoncpp/src/lib_json/json_value.cpp:235:18: error: conversion to 'unsigned char:2' from 'unsigned int' may alter its value [-Werror=conversion]
   storage_.policy_ = (other.cstr_
                      ~~~~~~~~~~~~
                  ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      ? noDuplication : duplicate)
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  : static_cast<DuplicationPolicy>(other.storage_.policy_));
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2016-02-07 11:28:50 -06:00
Christopher Dunn
6b562c850d Drop -Wno-sign-conversion suppression 2016-02-07 11:19:04 -06:00
Christopher Dunn
2713f4f456 Fix a sign-compare 2016-02-07 11:17:28 -06:00
Christopher Dunn
83bc9c7cf6 Errors for sign-compare, since gcc6 is stricter 2016-02-07 11:12:25 -06:00
Christopher Dunn
95f120f68e For gcc>=6 JSON_USE_INT64_DOUBLE_CONVERSION 2016-02-07 11:09:41 -06:00
Christopher Dunn
9a4b1e39bf 1.7.0 < 1.6.5 2016-02-06 10:27:39 -06:00
Christopher Dunn
2c872ec997 Merge pull request #406 from magnific0/master
std::snprintf not part of std for MinGW32 using c++11
2016-02-06 10:21:45 -06:00
Christopher Dunn
b860cc38e8 Merge pull request #414 from cdunn2001/conversion-errors
Fix conversion warnings/errors
2016-02-06 10:19:23 -06:00
Christopher Dunn
fef4b75796 More conversion fixes for gcc 2016-02-06 10:10:49 -06:00
Christopher Dunn
779d8a33fc Try to find ptrdiff_t for GNUC 4.9.2
https://travis-ci.org/open-source-parsers/jsoncpp/jobs/107452667
2016-02-06 09:49:29 -06:00
Christopher Dunn
d4513fcf45 Fix conversion warnings/errors
See #411.
  http://paste.debian.net/378673/
2016-02-06 09:25:20 -06:00
Christopher Dunn
baefec773c In case cmake is run in root-dir 2016-02-06 08:29:12 -06:00
Christopher Dunn
bc72070f43 Merge pull request #393 from ds283/cmake-binary-dir
Change ${CMAKE_BINARY_DIR} to ${CMAKE_CURRENT_BINARY_DIR}
2016-02-04 15:05:02 -06:00
Jacco
bc9b445fee std::snprintf fix for MinGW32 c++11 2016-01-25 11:39:36 +01:00
Jacco
2646ac5fa5 std::snprintf fix for MinGW32 c++11 2016-01-25 11:38:49 +01:00
ds283
2cca1cd239 Change ${CMAKE_BINARY_DIR} to ${CMAKE_CURRENT_BINARY_DIR}
- if building as a submodule of another repository, installation of pkg-config files can fail because they may not be in the top-level binary directory

- changing ${CMAKE_BINARY_DIR} to ${CMAKE_CURRENT_BINARY_DIR} allow CMake to find the files for installation
2015-12-05 12:18:12 +00:00
Christopher Dunn
9234cbbc90 Merge pull request #387 from joerg-krause/cmake-option-strict-iso
Disable -pedantic conditionally; add -pedantic-errors and -Werror conditionally
2015-10-30 01:16:49 -05:00
Jörg Krause
7c93031c9b Enable -Werror with JSONCPP_WITH_WARNING_AS_ERROR
Commit 912d55094d disabled '-Werror'. Enable it
if jsoncpp is build with JSONCPP_WITH_WARNING_AS_ERROR=ON.
2015-10-29 09:21:01 +01:00
Jörg Krause
48bfe91062 Add option JSONCPP_WITH_STRICT_ISO
'-pedantic' issues all warnings demanded by strict ISO C/C++; rejecting
extensions that do not follow ISO C/C++. Without this option, certain GNU
extensions and traditional C/C++ features are supported as well.

With this option enabled building jsoncpp fails with the musl toolchain on
x86 because of an incompatible posix_memalign declaration [1]. Without
'-pedantic' there is no error anymore and jsoncpp builds fine.

Add an option JSONCPP_WITH_STRICT_ISO to disable compilation with '-pedantic'
with GCC. If jsoncpp is build with the JSONCPP_WITH_WARNING_AS_ERROR option
'-pedantic-errors' is used instead.

[1] https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01425.html
2015-10-29 09:16:21 +01:00
Christopher Dunn
0cce773019 Merge pull request #384 from EvinceMoi/master
json_reader throwRuntimeError return error details
2015-10-27 15:48:05 -05:00
Evince
6b10ce8c0d json_reader throwRuntimeError return error details instead of hard-coded message
Signed-off-by: Evince <baneyue@gmail.com>
2015-10-28 00:22:46 +08:00
Christopher Dunn
34bdbb58b4 Merge pull request #267 from cdunn2001/moveSemantics
move ctors
2015-10-21 01:13:59 -05:00
Christopher Dunn
527965cbde Minor
adjustments, based on comments in PR.
2015-10-19 23:49:07 -05:00
Motti
2b00891a86 move ctors
* Add move constructor to Value::CZString
* Add unit test for Value move constructor
* Allow includer to specify in advance the value for
JSON_HAS_RVALUE_REFERENCES
2015-10-19 23:42:52 -05:00
Christopher Dunn
a4ce2829dc Some indentation
in anticipation of another change.
2015-10-19 23:40:47 -05:00
Christopher Dunn
69e7f1c858 Merge pull request #382 from cdunn2001/ccache
Support ccache
2015-10-19 22:50:41 -05:00
Christopher Dunn
d1a2b94d5b Support ccache
http://stackoverflow.com/a/24305849/263998
2015-10-19 12:10:58 -05:00
Christopher Dunn
772f634548 Merge pull request #381 from bknecht/precision
Resolves #284
2015-10-15 16:15:15 -05:00
Benjamin Knecht
9fd1ca8d68 Add test code for precision 2015-10-15 18:32:24 +02:00
Benjamin Knecht
38022157b2 making precision unsigned int
adding precision as settings value for StreamBuilder
2015-10-15 18:00:42 +02:00
Benjamin Knecht
039a6e3b61 Create format string with sprintf.
For now use hardcoded precision '17' for now
2015-10-15 17:28:56 +02:00
Christopher Dunn
9c17e61bd0 Merge pull request #379 from cdunn2001/issue-377
Iterator conversions
2015-10-10 17:20:37 -05:00
ycqiu
c8a8cfcd4b fix
In value.h, ValueConstIterator can convert to ValueIterator, I think that is a bug. the correct way is ValueIterator can convert to ValueConstIterator.
2015-10-10 17:17:20 -05:00
ycqiu
4994c77d09 add test code
does not compile
2015-10-10 16:22:14 -05:00
Christopher Dunn
beae99924f Merge pull request #373 from antonindrawan/QNX_support
Compiles jsoncpp with QNX 6.6
2015-10-04 14:54:09 -05:00
Christopher Dunn
8b9940fd24 Merge pull request #375 from Dani-Hub/issue-374-remove-defaulted-ctor
Remove defaulted default constructor
2015-10-03 16:03:27 -05:00
drgler
b96d90efbd Remove defaulted default constructor 2015-10-03 19:40:23 +02:00
Anton Indrawan
e375b8c89e Compiles jsoncpp with QNX 6.6 2015-10-03 11:48:19 +02:00
Christopher Dunn
49393ead06 Merge pull request #371 from mathstuf/more-platform-support
json_writer: improve isfinite support on *nix
2015-10-03 03:58:20 -05:00
Ben Boeckel
8df11d518b json_writer: improve isfinite support on *nix
Based on a patches to CMake by:

Ådne Hovda <ahovda@openit.com>:

    commit 7b1cdb00279908cacabada92f8a53e4986465423

    jsoncpp: Provide 'isfinite' implementation on older AIX and HP-UX

    Newer AIX and HP-UX platforms provide 'isfinite' as a <math.h> macro.
    Older versions do not, so add the definition if it is not provided.

Michael Scott <michael.scott@gbgplc.com>:

    commit 9217b678b305d7df7471ba476a81bf28961fdfa3

    jsoncpp: Provide 'isfinite' impl on more HP-UX versions (#15576)

    Some versions of HP-UX do not define 'isfinite' or 'finite' in math.h
    for Itanium when preprocessing with C++, so we have to add the
    definition ourselves instead to map to the internal version.

Joerg Sonnenberger <joerg@bec.de>:

    commit 75644dafe54c21902f14cfe58cb8338b553b69d8

    jsoncpp: Fix compilation as C99 on Solaris

    In C99 mode, Solaris variants may already define isfinite, so check for
    the existence first.
2015-10-01 13:27:19 -04:00
Christopher Dunn
8e400e9be7 Merge pull request #368 from mathstuf/export-factory-inner-class
reader: export CharReader::Factory
2015-09-28 17:06:34 -05:00
Christopher Dunn
dc5aa4ad7f Fix VS warnings
These don't really need to be const.

resolves #369
2015-09-28 17:05:57 -05:00
Ben Boeckel
80def66fa5 reader: export CharReader::Factory 2015-09-28 15:45:11 -04:00
Christopher Dunn
6992831c1c Merge pull request #367 from Dani-Hub/issue-350-unique_ptr-2
__cplusplus value should not be used to decide for std::unique_ptr

resolves #350
2015-09-28 11:27:29 -05:00
drgler
7e4875a239 __cplusplus value should not be used to decide for std::unique_ptr #350:
In addition to the C++ language version define __cplusplus also check _CPPLIB_VER for better Dinkumware support.
2015-09-27 14:03:35 +02:00
Christopher Dunn
979cbec237 Fully init OurReader
See #363, similar to #364.
2015-09-23 09:44:58 -05:00
Christopher Dunn
2e625dd9af Merge pull request #364 from ya1gaurav/patch-28
Have default ctor for OurFeatures
2015-09-23 09:41:17 -05:00
Gaurav
83ea25e5e2 Make OurFeatures ctor as default.
Please review suggested changes.
2015-09-23 09:42:26 +05:30
Christopher Dunn
5721f1ca57 Merge pull request #366 from ya1gaurav/patch-30
parseCommandLine also throws
2015-09-22 05:09:33 -05:00
Christopher Dunn
9942f6a1c7 Merge pull request #365 from ya1gaurav/patch-29
Remove conditional check for isMultiLine
2015-09-22 05:08:56 -05:00
Gaurav
6c14548293 parseCommandLine also throws
Catching exceptions thrown by parseCommandLine (std::bad_alloc & std::length_error) also.
2015-09-22 13:53:19 +05:30
Gaurav
6ee0bff822 Remove conditional check for isMultiLine
At all 3 places isMultiLine is checked in for loop :
for (int index = 0; index < size && !isMultiLine; ++index) {
It means !isMultiLine is always true (otherwise do not enter loop), so || condition does not depend on isMultiLine, so removed that.
2015-09-22 09:48:54 +05:30
Gaurav
e3b35992f8 Add default value of stackLimit couple of places
stackLimit default value is missing at two places.Adding them.
2015-09-21 18:05:15 +05:30
Christopher Dunn
cc5cdb565c Merge pull request #348 from cdunn2001/override-keyword
C++11: override keyword
2015-09-05 12:12:37 -05:00
Gaurav
aadd0b1b63 C++11: override keyword
Source : http://en.cppreference.com/w/cpp/language/override
2015-09-05 12:03:38 -05:00
Christopher Dunn
3ee15b7bcc Merge pull request #339 from Dani-Hub/master
Floating-point NaN or Infinity values should be allowed as a feature …
2015-09-05 11:59:54 -05:00
drgler
68509e6161 Fix number reading in the presence of Infinity: Only check for infinity if we have a leading sign character. 2015-09-05 14:49:33 +02:00
drgler
4cea1f6f6c Adjust whitespace formatting 2015-09-05 14:48:29 +02:00
Daniel Krügler
6f9ed421d0 Merge pull request #2 from BillyDonahue/billy_danihub_fix
Billy danihub fix
2015-09-05 13:38:04 +02:00
Billy Donahue
7f7bbeff76 don't need out field of TestData 2015-09-05 04:22:18 -04:00
Billy Donahue
bfffe8cec7 prettier test 2015-09-05 04:07:56 -04:00
Billy Donahue
73154fb546 expanded Infinity test 2015-09-05 03:48:38 -04:00
drgler
63c747218b Floating-point NaN or Infinity values should be allowed as a feature #209
Introduce 'allowSpecialFloats' for readers and 'useSpecialFloats' for writers, use consistent macro snprintf definition for writers and readers, provide new unit tests for #209
2015-09-03 22:50:03 +02:00
drgler
2084563efb Floating-point NaN or Infinity values should be allowed as a feature #209
Introduce 'allowSpecialFloats' for readers and 'useSpecialFloats' for writers, use consistent macro snprintf definition for writers and readers, provide new unit tests for #209
2015-09-03 22:19:22 +02:00
Christopher Dunn
6329975e6d Merge pull request #337 from AMDmi3/patch-1
Specify float constant as float
2015-08-21 20:45:37 -05:00
Dmitry Marakasov
7acfd599f0 Specify float constant as float
Otherwise, on some 32 bit platforms this may not fit into long and compilation will fail:

    src/test_lib_json/main.cpp:1260: error: integer constant is too large for 'long' type
2015-08-21 21:19:26 +03:00
Robert Dailey
63a961a752 Clean up cmake END* (again)
(I missed a couple. ~cd)
2015-08-14 14:47:46 -07:00
Christopher Dunn
cb2378fa41 Merge pull request #332 from cdunn2001/END
Clean up cmake END*
2015-08-14 14:40:42 -07:00
Robert Dailey
37aaaec70e Clean up cmake END*
* Clean up closing statements for if conditions, functions, macros,
  and other entities. Newer versions of CMake do not require you to
  redundantly respecify the parameters to the opening arguments.
2015-08-14 14:31:08 -07:00
Christopher Dunn
585446e6b3 Merge pull request #327 from cdunn2001/more-gitattributes
More gitattributes
2015-08-09 16:38:21 -07:00
Christopher Dunn
7f4be39e9f add .gitattributes
helps #325
2015-08-09 16:25:36 -07:00
Christopher Dunn
47595e922b normalized some windows VS stuff 2015-08-09 16:23:50 -07:00
Christopher Dunn
9f7dbcb19b Merge pull request #326 from rcdailey/git-attributes
Introduce .gitattributes file and normalize line endings
2015-08-09 16:23:20 -07:00
Robert Dailey
c1996256d6 Normalize line endings
This commit contains nothing but line ending normalization
changes. These changes were performed after the introduction
of .gitattributes into the repository.
2015-08-09 18:02:52 -05:00
Robert Dailey
25e4adc4e1 Add .gitattributes file 2015-08-09 18:02:37 -05:00
Aaron Jacobs
cc2c15c3eb Remove undefined behavior from a left shift of a negative value.
Fixed by shifting a positive value, then negating the result.

(Credit: Richard Trieu)
2015-08-03 10:58:29 +10:00
Christopher Dunn
912d55094d Merge pull request #323 from joerg-krause/master
Remove -Werror
2015-08-02 15:48:38 -05:00
Jörg Krause
d7b84f69c5 Remove Werror
-Werror shouldn't be used in released code since it can cause random build
failures on moderate warnings. It also depends on the used toolchain since
different toolchains may or may not print the same warnings.
2015-07-30 23:56:28 +02:00
Christopher Dunn
9dad198af6 Merge pull request #320 from shields/negation-overflow
Fix cases where the most negative signed integer was negated, causing undefined behavior.
2015-07-28 11:35:52 -05:00
Michael Shields
7f06e9dc28 Fix cases where the most negative signed integer was negated, causing
undefined behavior.
2015-07-27 16:35:19 -07:00
25 changed files with 1276 additions and 584 deletions

16
.gitignore vendored
View File

@@ -34,3 +34,19 @@ CTestTestFile.cmake
cmake_install.cmake
pkg-config/jsoncpp.pc
jsoncpp_lib_static.dir/
# In case someone runs cmake in the root-dir:
/CMakeCache.txt
/Makefile
/include/Makefile
/src/Makefile
/src/jsontestrunner/Makefile
/src/jsontestrunner/jsontestrunner_exe
/src/lib_json/Makefile
/src/test_lib_json/Makefile
/src/test_lib_json/jsoncpp_test
# eclipse project files
.project
.cproject
/.settings/

View File

@@ -8,22 +8,23 @@
install:
# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available.
#- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.6" CC="gcc-4.6"; fi
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
# /usr/bin/clang is our version already, and clang-X.Y does not exist.
#- if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.0" CC="clang-3.0"; fi
#- if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.7" CC="clang-3.7"; fi
- echo ${PATH}
- ls /usr/local
- export PATH=/usr/bin:${PATH}
- ls /usr/local/bin
- export PATH=/usr/local/bin:/usr/bin:${PATH}
- echo ${CXX}
- ${CXX} --version
- which valgrind
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.6
- g++-4.6
- gcc-4.9
- g++-4.9
- clang
- valgrind
os:

View File

@@ -7,13 +7,12 @@ ENABLE_TESTING()
OPTION(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON)
OPTION(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON)
OPTION(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF)
OPTION(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON)
OPTION(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON)
OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" OFF)
OPTION(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF)
OPTION(BUILD_STATIC_LIBS "Build jsoncpp_lib static library." ON)
include(GNUInstallDirs)
# Ensures that CMAKE_BUILD_TYPE is visible in cmake-gui on Unix
IF(NOT WIN32)
IF(NOT CMAKE_BUILD_TYPE)
@@ -32,7 +31,7 @@ SET(ARCHIVE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}
CACHE PATH "Install dir for static libraries")
SET(LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}
CACHE PATH "Install dir for shared libraries")
SET(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/jsoncpp
SET(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include
CACHE PATH "Install dir for headers")
SET(PACKAGE_INSTALL_DIR lib${LIB_SUFFIX}/cmake
CACHE PATH "Install dir for cmake package config files")
@@ -65,11 +64,12 @@ ENDMACRO()
#SET( JSONCPP_VERSION_MAJOR X )
#SET( JSONCPP_VERSION_MINOR Y )
#SET( JSONCPP_VERSION_PATCH Z )
SET( JSONCPP_VERSION 0.10.7 )
SET( JSONCPP_VERSION 1.7.0 )
jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION )
#IF(NOT JSONCPP_VERSION_FOUND)
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")
#ENDIF(NOT JSONCPP_VERSION_FOUND)
SET( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" )
MESSAGE(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}")
# File version.h is only regenerated on CMake configure step
@@ -81,13 +81,16 @@ CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/version.in"
NEWLINE_STYLE UNIX )
macro(UseCompilationWarningAsError)
if ( MSVC )
# Only enabled in debug because some old versions of VS STL generate
# warnings when compiled in release configuration.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_XX_COMPILER_ID MATCHES "Clang" )
if ( MSVC )
# Only enabled in debug because some old versions of VS STL generate
# warnings when compiled in release configuration.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
if (JSONCPP_WITH_STRICT_ISO)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors")
endif ()
endif()
endmacro()
# Include our configuration header
@@ -101,13 +104,23 @@ endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# using regular Clang or AppleClang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wshadow -Wshorten-64-to-32")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wshadow -Wextra -pedantic -Wno-long-long")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wextra -Werror=conversion")
# not yet ready for -Wsign-conversion
if (JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif ()
endif()
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
IF(JSONCPP_WITH_WARNING_AS_ERROR)
UseCompilationWarningAsError()
ENDIF()
@@ -117,8 +130,8 @@ IF(JSONCPP_WITH_PKGCONFIG_SUPPORT)
"pkg-config/jsoncpp.pc.in"
"pkg-config/jsoncpp.pc"
@ONLY)
INSTALL(FILES "${CMAKE_BINARY_DIR}/pkg-config/jsoncpp.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkg-config/jsoncpp.pc"
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig")
ENDIF()
IF(JSONCPP_WITH_CMAKE_PACKAGE)

View File

@@ -67,6 +67,7 @@ def amalgamate_source(source_top_dir=None,
header.add_text("/// to prevent private header inclusion.")
header.add_text("#define JSON_IS_AMALGAMATION")
header.add_file("include/json/version.h")
header.add_file("include/json/allocator.h")
header.add_file("include/json/config.h")
header.add_file("include/json/forwards.h")
header.add_file("include/json/features.h")

94
include/json/allocator.h Normal file
View File

@@ -0,0 +1,94 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef CPPTL_JSON_ALLOCATOR_H_INCLUDED
#define CPPTL_JSON_ALLOCATOR_H_INCLUDED
#include <cstring>
#include <memory>
namespace Json {
template<typename T>
class SecureAllocator {
public:
// Type definitions
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
/**
* Allocate memory for N items using the standard allocator.
*/
pointer allocate(size_type n) {
// allocate using "global operator new"
return static_cast<pointer>(::operator new(n * sizeof(T)));
}
/**
* Release memory which was allocated for N items at pointer P.
*
* The memory block is filled with zeroes before being released.
* The pointer argument is tagged as "volatile" to prevent the
* compiler optimizing out this critical step.
*/
void deallocate(volatile pointer p, size_type n) {
std::memset(p, 0, n * sizeof(T));
// free using "global operator delete"
::operator delete(p);
}
/**
* Construct an item in-place at pointer P.
*/
template<typename... Args>
void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
}
size_type max_size() const {
return size_t(-1) / sizeof(T);
}
pointer address( reference x ) const {
return std::addressof(x);
}
const_pointer address( const_reference x ) const {
return std::addressof(x);
}
/**
* Destroy an item in-place at pointer P.
*/
void destroy(pointer p) {
// destroy using "explicit destructor"
p->~T();
}
// Boilerplate
SecureAllocator() {}
template<typename U> SecureAllocator(const SecureAllocator<U>&) {}
template<typename U> struct rebind { using other = SecureAllocator<U>; };
};
template<typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true;
}
template<typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false;
}
} //namespace Json
#endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED

View File

@@ -25,7 +25,7 @@
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
JSONCPP_OSTRINGSTREAM oss; oss << message; \
Json::throwLogicError(oss.str()); \
abort(); \
}
@@ -38,7 +38,7 @@
// release builds we abort, for a core-dump or debugger.
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
JSONCPP_OSTRINGSTREAM oss; oss << message; \
assert(false && oss.str().c_str()); \
abort(); \
}

View File

@@ -5,6 +5,8 @@
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <stddef.h>
#include <string> //typdef String
/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
@@ -37,12 +39,12 @@
#ifdef JSON_IN_CPPTL
#define JSON_API CPPTL_API
#elif defined(JSON_DLL_BUILD)
#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#elif defined(JSON_DLL)
#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
@@ -51,49 +53,78 @@
#define JSON_API
#endif
#if !defined(JSON_HAS_UNIQUE_PTR)
#if __cplusplus >= 201103L
#define JSON_HAS_UNIQUE_PTR (1)
#elif _MSC_VER >= 1600
#define JSON_HAS_UNIQUE_PTR (1)
#else
#define JSON_HAS_UNIQUE_PTR (0)
#endif
#endif
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1
#if defined(_MSC_VER) && _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 // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6
#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 defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__clang__) && defined(__has_feature)
#if __has_feature(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
# 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)
#ifndef JSON_HAS_RVALUE_REFERENCES
#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // MSVC >= 2010
#ifdef __clang__
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
#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 // __clang__ || __GNUC__
#endif // not defined JSON_HAS_RVALUE_REFERENCES
#ifndef JSON_HAS_RVALUE_REFERENCES
#define JSON_HAS_RVALUE_REFERENCES 0
#endif
#ifdef __clang__
#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
#endif // __clang__ || __GNUC__
#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
#if __GNUC__ >= 6
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
#include "version.h"
#if JSONCPP_USING_SECURE_MEMORY
#include "allocator.h" //typedef Allocator
#endif
namespace Json {
typedef int Int;
typedef unsigned int UInt;
@@ -114,6 +145,19 @@ 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
#else
#define JSONCPP_STRING std::string
#define JSONCPP_OSTRINGSTREAM std::ostringstream
#define JSONCPP_OSTREAM std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
#define JSONCPP_ISTREAM std::istream
#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json
#endif // JSON_CONFIG_H_INCLUDED

View File

@@ -44,6 +44,12 @@ public:
/// \c true if root must be either an array or an object value. Default: \c
/// false.
bool strictRoot_;
/// \c true if dropped null placeholders are allowed. Default: \c false.
bool allowDroppedNullPlaceholders_;
/// \c true if numeric object key are allowed. Default: \c false.
bool allowNumericKeys_;
};
} // namespace Json

View File

@@ -35,6 +35,18 @@ public:
typedef char Char;
typedef const Char* Location;
/** \brief An error tagged with where in the JSON text it was encountered.
*
* The offsets give the [start, limit) range of bytes within the text. Note
* that this is bytes, not codepoints.
*
*/
struct StructuredError {
ptrdiff_t offset_start;
ptrdiff_t offset_limit;
JSONCPP_STRING message;
};
/** \brief Constructs a Reader allowing all features
* for parsing.
*/
@@ -87,7 +99,7 @@ public:
/// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&).
bool parse(std::istream& is, Value& root, bool collectComments = true);
bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
/** \brief Returns a user friendly string that list errors in the parsed
* document.
@@ -99,7 +111,7 @@ public:
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
std::string getFormatedErrorMessages() const;
JSONCPP_STRING getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed
* document.
@@ -109,7 +121,39 @@ public:
* occurred
* during parsing.
*/
std::string getFormattedErrorMessages() const;
JSONCPP_STRING getFormattedErrorMessages() const;
/** \brief Returns a vector of structured erros encounted while parsing.
* \return A (possibly empty) vector of StructuredError objects. Currently
* only one error can be returned, but the caller should tolerate
* multiple
* errors. This can occur if the parser recovers from a non-fatal
* parse error and then encounters additional errors.
*/
std::vector<StructuredError> getStructuredErrors() const;
/** \brief Add a semantic error message.
* \param value JSON Value location associated with the error
* \param message The error message.
* \return \c true if the error was successfully added, \c false if the
* Value offset exceeds the document size.
*/
bool pushError(const Value& value, const JSONCPP_STRING& message);
/** \brief Add a semantic error message with extra context.
* \param value JSON Value location associated with the error
* \param message The error message.
* \param extra Additional JSON Value location to contextualize the error
* \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);
/** \brief Return whether there are any errors.
* \return \c true if there are no errors to report \c false if
* errors have occurred.
*/
bool good() const;
private:
enum TokenType {
@@ -139,7 +183,7 @@ private:
class ErrorInfo {
public:
Token token_;
std::string message_;
JSONCPP_STRING message_;
Location extra_;
};
@@ -159,7 +203,7 @@ private:
bool decodeNumber(Token& token);
bool decodeNumber(Token& token, Value& decoded);
bool decodeString(Token& token);
bool decodeString(Token& token, std::string& decoded);
bool decodeString(Token& token, JSONCPP_STRING& decoded);
bool decodeDouble(Token& token);
bool decodeDouble(Token& token, Value& decoded);
bool decodeUnicodeCodePoint(Token& token,
@@ -170,9 +214,9 @@ private:
Location& current,
Location end,
unsigned int& unicode);
bool addError(const std::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 std::string& message,
bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
TokenType skipUntilToken);
void skipUntilSpace();
@@ -180,20 +224,20 @@ private:
Char getNextChar();
void
getLocationLineAndColumn(Location location, int& line, int& column) const;
std::string getLocationLineAndColumn(Location location) const;
JSONCPP_STRING getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);
typedef std::stack<Value*> Nodes;
Nodes nodes_;
Errors errors_;
std::string document_;
JSONCPP_STRING document_;
Location begin_;
Location end_;
Location current_;
Location lastValueEnd_;
Value* lastValue_;
std::string commentsBefore_;
JSONCPP_STRING commentsBefore_;
Features features_;
bool collectComments_;
}; // Reader
@@ -222,9 +266,9 @@ public:
*/
virtual bool parse(
char const* beginDoc, char const* endDoc,
Value* root, std::string* errs) = 0;
Value* root, JSONCPP_STRING* errs) = 0;
class Factory {
class JSON_API Factory {
public:
virtual ~Factory() {}
/** \brief Allocate a CharReader via operator new().
@@ -242,7 +286,7 @@ Usage:
CharReaderBuilder builder;
builder["collectComments"] = false;
Value value;
std::string errs;
JSONCPP_STRING errs;
bool ok = parseFromStream(builder, std::cin, &value, &errs);
\endcode
*/
@@ -289,9 +333,9 @@ public:
Json::Value settings_;
CharReaderBuilder();
virtual ~CharReaderBuilder();
~CharReaderBuilder() override;
virtual CharReader* newCharReader() const;
CharReader* newCharReader() const override;
/** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'.
@@ -300,7 +344,7 @@ public:
/** A simple way to update a specific setting.
*/
Value& operator[](std::string key);
Value& operator[](JSONCPP_STRING key);
/** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine)
@@ -322,7 +366,7 @@ public:
*/
bool JSON_API parseFromStream(
CharReader::Factory const&,
std::istream&,
JSONCPP_ISTREAM&,
Value* root, std::string* errs);
/** \brief Read from 'sin' into 'root'.
@@ -349,7 +393,7 @@ bool JSON_API parseFromStream(
\throw std::exception on parse error.
\see Json::operator<<()
*/
JSON_API std::istream& operator>>(std::istream&, Value&);
JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
} // namespace Json

View File

@@ -22,13 +22,6 @@
#include <cpptl/forwards.h>
#endif
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
//Conditional NORETURN attribute on the throw functions would:
// a) suppress false positives from static code analysis
// b) possibly improve optimization opportunities.
@@ -42,6 +35,13 @@
# endif
#endif
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
/** \brief JSON (JavaScript Object Notation).
*/
namespace Json {
@@ -52,11 +52,11 @@ namespace Json {
*/
class JSON_API Exception : public std::exception {
public:
Exception(std::string const& msg);
virtual ~Exception() throw();
virtual char const* what() const throw();
Exception(JSONCPP_STRING const& msg);
~Exception() throw() override;
char const* what() const throw() override;
protected:
std::string const msg_;
JSONCPP_STRING msg_;
};
/** Exceptions which the user cannot easily avoid.
@@ -67,7 +67,7 @@ protected:
*/
class JSON_API RuntimeError : public Exception {
public:
RuntimeError(std::string const& msg);
RuntimeError(JSONCPP_STRING const& msg);
};
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
@@ -78,13 +78,13 @@ public:
*/
class JSON_API LogicError : public Exception {
public:
LogicError(std::string const& msg);
LogicError(JSONCPP_STRING const& msg);
};
/// used internally
JSONCPP_NORETURN void throwRuntimeError(std::string const& msg);
JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
/// used internally
JSONCPP_NORETURN void throwLogicError(std::string const& msg);
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);
/** \brief Type of the value held by a Value object.
*/
@@ -175,7 +175,7 @@ private:
class JSON_API Value {
friend class ValueIteratorBase;
public:
typedef std::vector<std::string> Members;
typedef std::vector<JSONCPP_STRING> Members;
typedef ValueIterator iterator;
typedef ValueConstIterator const_iterator;
typedef Json::UInt UInt;
@@ -188,11 +188,8 @@ public:
typedef Json::LargestUInt LargestUInt;
typedef Json::ArrayIndex ArrayIndex;
static const Value& nullRef;
#if !defined(__ARMEL__)
/// \deprecated This exists for binary compatibility only. Use nullRef.
static const Value null;
#endif
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
/// Minimum signed integer value that can be stored in a Json::Value.
static const LargestInt minLargestInt;
/// Maximum signed integer value that can be stored in a Json::Value.
@@ -216,12 +213,7 @@ public:
static const UInt64 maxUInt64;
#endif // defined(JSON_HAS_INT64)
//MW: workaround for bug in NVIDIAs CUDA 7.5 nvcc compiler
#ifdef __NVCC__
public:
#else
private:
#endif //__NVCC__
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
class CZString {
public:
@@ -233,6 +225,9 @@ private:
CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other);
#if JSON_HAS_RVALUE_REFERENCES
CZString(CZString&& other);
#endif
~CZString();
CZString& operator=(CZString other);
bool operator<(CZString const& other) const;
@@ -308,18 +303,22 @@ Json::Value obj_value(Json::objectValue); // {}
* \endcode
*/
Value(const StaticString& value);
Value(const std::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
Value(bool value);
/// Deep copy.
Value(const Value& other);
#if JSON_HAS_RVALUE_REFERENCES
/// Move constructor
Value(Value&& other);
#endif
~Value();
/// Deep copy, then swap(other).
/// \note Over-write existing comments. To preserve comments, use #swapPayload().
Value &operator=(const Value &other);
Value& operator=(Value other);
/// Swap everything.
void swap(Value& other);
/// Swap values but leave comments and source offsets in place.
@@ -337,7 +336,10 @@ Json::Value obj_value(Json::objectValue); // {}
int compare(const Value& other) const;
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
std::string asString() const; ///< Embedded zeroes are possible.
#if JSONCPP_USING_SECURE_MEMORY
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.)
*/
@@ -441,11 +443,11 @@ Json::Value obj_value(Json::objectValue); // {}
const Value& operator[](const char* key) const;
/// Access an object value by name, create a null member if it does not exist.
/// \param key may contain embedded nulls.
Value& operator[](const std::string& key);
Value& operator[](const JSONCPP_STRING& key);
/// Access an object value by name, returns null if there is no member with
/// that name.
/// \param key may contain embedded nulls.
const Value& operator[](const std::string& key) const;
const Value& operator[](const JSONCPP_STRING& key) const;
/** \brief Access an object value by name, create a null member if it does not
exist.
@@ -476,7 +478,7 @@ Json::Value obj_value(Json::objectValue); // {}
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \param key may contain embedded nulls.
Value get(const std::string& key, const Value& defaultValue) const;
Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
#ifdef JSON_USE_CPPTL
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
@@ -501,7 +503,7 @@ Json::Value obj_value(Json::objectValue); // {}
/// Same as removeMember(const char*)
/// \param key may contain embedded nulls.
/// \deprecated
Value removeMember(const std::string& key);
Value 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);
@@ -511,8 +513,8 @@ Json::Value obj_value(Json::objectValue); // {}
\param key may contain embedded nulls.
\return true iff removed (no exceptions)
*/
bool removeMember(std::string const& key, Value* removed);
/// Same as removeMember(std::string const& key, Value* removed)
bool removeMember(JSONCPP_STRING const& key, Value* removed);
/// Same as removeMember(JSONCPP_STRING const& key, Value* removed)
bool removeMember(const char* begin, const char* end, Value* removed);
/** \brief Remove the indexed array element.
@@ -527,8 +529,8 @@ Json::Value obj_value(Json::objectValue); // {}
bool isMember(const char* key) const;
/// Return true if the object has a member named key.
/// \param key may contain embedded nulls.
bool isMember(const std::string& key) const;
/// Same as isMember(std::string const& key)const
bool isMember(const JSONCPP_STRING& key) const;
/// Same as isMember(JSONCPP_STRING const& key)const
bool isMember(const char* begin, const char* end) const;
#ifdef JSON_USE_CPPTL
/// Return true if the object has a member named key.
@@ -548,17 +550,17 @@ Json::Value obj_value(Json::objectValue); // {}
//# endif
/// \deprecated Always pass len.
JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
void setComment(const char* comment, CommentPlacement placement);
/// Comments must be //... or /* ... */
void setComment(const char* comment, size_t len, CommentPlacement placement);
/// Comments must be //... or /* ... */
void setComment(const std::string& comment, CommentPlacement placement);
void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
bool hasComment(CommentPlacement placement) const;
/// Include delimiters and embedded newlines.
std::string getComment(CommentPlacement placement) const;
JSONCPP_STRING getComment(CommentPlacement placement) const;
std::string toStyledString() const;
JSONCPP_STRING toStyledString() const;
const_iterator begin() const;
const_iterator end() const;
@@ -566,6 +568,13 @@ Json::Value obj_value(Json::objectValue); // {}
iterator begin();
iterator end();
// Accessors for the [start, limit) range of bytes within the JSON text from
// which this value was parsed, if any.
void setOffsetStart(ptrdiff_t start);
void setOffsetLimit(ptrdiff_t limit);
ptrdiff_t getOffsetStart() const;
ptrdiff_t getOffsetLimit() const;
private:
void initBasic(ValueType type, bool allocated = false);
@@ -602,6 +611,11 @@ private:
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
// was extracted.
ptrdiff_t start_;
ptrdiff_t limit_;
};
/** \brief Experimental and untested: represents an element of the "path" to
@@ -614,7 +628,7 @@ public:
PathArgument();
PathArgument(ArrayIndex index);
PathArgument(const char* key);
PathArgument(const std::string& key);
PathArgument(const JSONCPP_STRING& key);
private:
enum Kind {
@@ -622,7 +636,7 @@ private:
kindIndex,
kindKey
};
std::string key_;
JSONCPP_STRING key_;
ArrayIndex index_;
Kind kind_;
};
@@ -640,7 +654,7 @@ private:
*/
class JSON_API Path {
public:
Path(const std::string& path,
Path(const JSONCPP_STRING& path,
const PathArgument& a1 = PathArgument(),
const PathArgument& a2 = PathArgument(),
const PathArgument& a3 = PathArgument(),
@@ -657,12 +671,12 @@ private:
typedef std::vector<const PathArgument*> InArgs;
typedef std::vector<PathArgument> Args;
void makePath(const std::string& path, const InArgs& in);
void addPathInArg(const std::string& path,
void makePath(const JSONCPP_STRING& path, const InArgs& in);
void addPathInArg(const JSONCPP_STRING& path,
const InArgs& in,
InArgs::const_iterator& itInArg,
PathArgument::Kind kind);
void invalidPath(const std::string& path, int location);
void invalidPath(const JSONCPP_STRING& path, int location);
Args args_;
};
@@ -695,7 +709,7 @@ public:
/// Return the member name of the referenced Value, or "" if it is not an
/// objectValue.
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
std::string name() const;
JSONCPP_STRING name() const;
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
@@ -747,6 +761,7 @@ public:
typedef ValueConstIterator SelfType;
ValueConstIterator();
ValueConstIterator(ValueIterator const& other);
private:
/*! \internal Use by Value to create an iterator.
@@ -796,7 +811,7 @@ public:
typedef ValueIterator SelfType;
ValueIterator();
ValueIterator(const ValueConstIterator& other);
explicit ValueIterator(const ValueConstIterator& other);
ValueIterator(const ValueIterator& other);
private:

View File

@@ -3,11 +3,18 @@
#ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "0.10.7"
# define JSONCPP_VERSION_MAJOR 0
# define JSONCPP_VERSION_MINOR 10
# define JSONCPP_VERSION_PATCH 7
# define JSONCPP_VERSION_STRING "1.7.0"
# define JSONCPP_VERSION_MAJOR 1
# define JSONCPP_VERSION_MINOR 7
# 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))
#ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY
#endif
#define JSONCPP_USING_SECURE_MEMORY 1
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
#endif // JSON_VERSION_H_INCLUDED

View File

@@ -39,7 +39,7 @@ Usage:
*/
class JSON_API StreamWriter {
protected:
std::ostream* sout_; // not owned; will not delete
JSONCPP_OSTREAM* sout_; // not owned; will not delete
public:
StreamWriter();
virtual ~StreamWriter();
@@ -49,7 +49,7 @@ public:
\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, std::ostream* sout) = 0;
virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
/** \brief A simple abstract factory.
*/
@@ -66,7 +66,7 @@ public:
/** \brief Write into stringstream, then return string, for convenience.
* A StreamWriter will be created from the factory, used, and then deleted.
*/
std::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.
@@ -112,12 +112,12 @@ public:
Json::Value settings_;
StreamWriterBuilder();
virtual ~StreamWriterBuilder();
~StreamWriterBuilder() override;
/**
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
virtual StreamWriter* newStreamWriter() const;
StreamWriter* newStreamWriter() const override;
/** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'.
@@ -125,7 +125,7 @@ public:
bool validate(Json::Value* invalid) const;
/** A simple way to update a specific setting.
*/
Value& operator[](std::string key);
Value& operator[](JSONCPP_STRING key);
/** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine)
@@ -142,7 +142,7 @@ class JSON_API Writer {
public:
virtual ~Writer();
virtual std::string write(const Value& root) = 0;
virtual JSONCPP_STRING write(const Value& root) = 0;
};
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
@@ -158,18 +158,29 @@ class JSON_API FastWriter : public Writer {
public:
FastWriter();
virtual ~FastWriter() {}
~FastWriter() override {}
void enableYAMLCompatibility();
/** \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
* browser can handle the output just fine.
*/
void dropNullPlaceholders();
void omitEndingLineFeed();
public: // overridden from Writer
virtual std::string write(const Value& root);
JSONCPP_STRING write(const Value& root) override;
private:
void writeValue(const Value& value);
std::string document_;
JSONCPP_STRING document_;
bool yamlCompatiblityEnabled_;
bool dropNullPlaceholders_;
bool omitEndingLineFeed_;
};
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
@@ -199,36 +210,36 @@ private:
class JSON_API StyledWriter : public Writer {
public:
StyledWriter();
virtual ~StyledWriter() {}
~StyledWriter() override {}
public: // overridden from Writer
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
* \param root Value to serialize.
* \return String containing the JSON document that represents the root value.
*/
virtual std::string write(const Value& root);
JSONCPP_STRING write(const Value& root) override;
private:
void writeValue(const Value& value);
void writeArrayValue(const Value& value);
bool isMultineArray(const Value& value);
void pushValue(const std::string& value);
void pushValue(const JSONCPP_STRING& value);
void writeIndent();
void writeWithIndent(const std::string& value);
void writeWithIndent(const JSONCPP_STRING& value);
void indent();
void unindent();
void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root);
bool hasCommentForValue(const Value& value);
static std::string normalizeEOL(const std::string& text);
static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
typedef std::vector<std::string> ChildValues;
typedef std::vector<JSONCPP_STRING> ChildValues;
ChildValues childValues_;
std::string document_;
std::string indentString_;
int rightMargin_;
int indentSize_;
JSONCPP_STRING document_;
JSONCPP_STRING indentString_;
unsigned int rightMargin_;
unsigned int indentSize_;
bool addChildValues_;
};
@@ -260,7 +271,7 @@ private:
*/
class JSON_API StyledStreamWriter {
public:
StyledStreamWriter(std::string indentation = "\t");
StyledStreamWriter(JSONCPP_STRING indentation = "\t");
~StyledStreamWriter() {}
public:
@@ -270,46 +281,46 @@ public:
* \note There is no point in deriving from Writer, since write() should not
* return a value.
*/
void write(std::ostream& out, const Value& root);
void write(JSONCPP_OSTREAM& out, const Value& root);
private:
void writeValue(const Value& value);
void writeArrayValue(const Value& value);
bool isMultineArray(const Value& value);
void pushValue(const std::string& value);
void pushValue(const JSONCPP_STRING& value);
void writeIndent();
void writeWithIndent(const std::string& value);
void writeWithIndent(const JSONCPP_STRING& value);
void indent();
void unindent();
void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root);
bool hasCommentForValue(const Value& value);
static std::string normalizeEOL(const std::string& text);
static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
typedef std::vector<std::string> ChildValues;
typedef std::vector<JSONCPP_STRING> ChildValues;
ChildValues childValues_;
std::ostream* document_;
std::string indentString_;
int rightMargin_;
std::string indentation_;
JSONCPP_OSTREAM* document_;
JSONCPP_STRING indentString_;
unsigned int rightMargin_;
JSONCPP_STRING indentation_;
bool addChildValues_ : 1;
bool indented_ : 1;
};
#if defined(JSON_HAS_INT64)
std::string JSON_API valueToString(Int value);
std::string JSON_API valueToString(UInt value);
JSONCPP_STRING JSON_API valueToString(Int value);
JSONCPP_STRING JSON_API valueToString(UInt value);
#endif // if defined(JSON_HAS_INT64)
std::string JSON_API valueToString(LargestInt value);
std::string JSON_API valueToString(LargestUInt value);
std::string JSON_API valueToString(double value);
std::string JSON_API valueToString(bool value);
std::string JSON_API valueToQuotedString(const char* value);
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(bool value);
JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
} // namespace Json

View File

@@ -17,14 +17,14 @@
struct Options
{
std::string path;
JSONCPP_STRING path;
Json::Features features;
bool parseOnly;
typedef std::string (*writeFuncType)(Json::Value const&);
typedef JSONCPP_STRING (*writeFuncType)(Json::Value const&);
writeFuncType write;
};
static std::string normalizeFloatingPointStr(double value) {
static JSONCPP_STRING normalizeFloatingPointStr(double value) {
char buffer[32];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "%.16g", value);
@@ -32,18 +32,18 @@ static std::string normalizeFloatingPointStr(double value) {
snprintf(buffer, sizeof(buffer), "%.16g", value);
#endif
buffer[sizeof(buffer) - 1] = 0;
std::string s(buffer);
std::string::size_type index = s.find_last_of("eE");
if (index != std::string::npos) {
std::string::size_type hasSign =
JSONCPP_STRING s(buffer);
JSONCPP_STRING::size_type index = s.find_last_of("eE");
if (index != JSONCPP_STRING::npos) {
JSONCPP_STRING::size_type hasSign =
(s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0;
std::string::size_type exponentStartIndex = index + 1 + hasSign;
std::string normalized = s.substr(0, exponentStartIndex);
std::string::size_type indexDigit =
JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign;
JSONCPP_STRING normalized = s.substr(0, exponentStartIndex);
JSONCPP_STRING::size_type indexDigit =
s.find_first_not_of('0', exponentStartIndex);
std::string exponent = "0";
JSONCPP_STRING exponent = "0";
if (indexDigit !=
std::string::npos) // There is an exponent different from 0
JSONCPP_STRING::npos) // There is an exponent different from 0
{
exponent = s.substr(indexDigit);
}
@@ -52,17 +52,18 @@ static std::string normalizeFloatingPointStr(double value) {
return s;
}
static std::string readInputTestFile(const char* path) {
static JSONCPP_STRING readInputTestFile(const char* path) {
FILE* file = fopen(path, "rb");
if (!file)
return std::string("");
return JSONCPP_STRING("");
fseek(file, 0, SEEK_END);
long size = ftell(file);
long const size = ftell(file);
unsigned long const usize = static_cast<unsigned long const>(size);
fseek(file, 0, SEEK_SET);
std::string text;
JSONCPP_STRING text;
char* buffer = new char[size + 1];
buffer[size] = 0;
if (fread(buffer, 1, size, file) == (unsigned long)size)
if (fread(buffer, 1, usize, file) == usize)
text = buffer;
fclose(file);
delete[] buffer;
@@ -70,7 +71,7 @@ static std::string readInputTestFile(const char* path) {
}
static void
printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") {
printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") {
if (value.hasComment(Json::commentBefore)) {
fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str());
}
@@ -104,8 +105,8 @@ printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") {
break;
case Json::arrayValue: {
fprintf(fout, "%s=[]\n", path.c_str());
int size = value.size();
for (int index = 0; index < size; ++index) {
Json::ArrayIndex size = value.size();
for (Json::ArrayIndex index = 0; index < size; ++index) {
static char buffer[16];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "[%d]", index);
@@ -119,11 +120,11 @@ printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") {
fprintf(fout, "%s={}\n", path.c_str());
Json::Value::Members members(value.getMemberNames());
std::sort(members.begin(), members.end());
std::string suffix = *(path.end() - 1) == '.' ? "" : ".";
JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : ".";
for (Json::Value::Members::iterator it = members.begin();
it != members.end();
++it) {
const std::string& name = *it;
const JSONCPP_STRING name = *it;
printValueTree(fout, value[name], path + suffix + name);
}
} break;
@@ -136,15 +137,15 @@ printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") {
}
}
static int parseAndSaveValueTree(const std::string& input,
const std::string& actual,
const std::string& kind,
static int parseAndSaveValueTree(const JSONCPP_STRING& input,
const JSONCPP_STRING& actual,
const JSONCPP_STRING& kind,
const Json::Features& features,
bool parseOnly,
Json::Value* root)
{
Json::Reader reader(features);
bool parsingSuccessful = reader.parse(input, *root);
bool parsingSuccessful = reader.parse(input.data(), input.data() + input.size(), *root);
if (!parsingSuccessful) {
printf("Failed to parse %s file: \n%s\n",
kind.c_str(),
@@ -162,36 +163,36 @@ static int parseAndSaveValueTree(const std::string& input,
}
return 0;
}
// static std::string useFastWriter(Json::Value const& root) {
// static JSONCPP_STRING useFastWriter(Json::Value const& root) {
// Json::FastWriter writer;
// writer.enableYAMLCompatibility();
// return writer.write(root);
// }
static std::string useStyledWriter(
static JSONCPP_STRING useStyledWriter(
Json::Value const& root)
{
Json::StyledWriter writer;
return writer.write(root);
}
static std::string useStyledStreamWriter(
static JSONCPP_STRING useStyledStreamWriter(
Json::Value const& root)
{
Json::StyledStreamWriter writer;
std::ostringstream sout;
JSONCPP_OSTRINGSTREAM sout;
writer.write(sout, root);
return sout.str();
}
static std::string useBuiltStyledStreamWriter(
static JSONCPP_STRING useBuiltStyledStreamWriter(
Json::Value const& root)
{
Json::StreamWriterBuilder builder;
return Json::writeString(builder, root);
}
static int rewriteValueTree(
const std::string& rewritePath,
const JSONCPP_STRING& rewritePath,
const Json::Value& root,
Options::writeFuncType write,
std::string* rewrite)
JSONCPP_STRING* rewrite)
{
*rewrite = write(root);
FILE* fout = fopen(rewritePath.c_str(), "wt");
@@ -204,13 +205,13 @@ static int rewriteValueTree(
return 0;
}
static std::string removeSuffix(const std::string& path,
const std::string& extension) {
static JSONCPP_STRING removeSuffix(const JSONCPP_STRING& path,
const JSONCPP_STRING& extension) {
if (extension.length() >= path.length())
return std::string("");
std::string suffix = path.substr(path.length() - extension.length());
return JSONCPP_STRING("");
JSONCPP_STRING suffix = path.substr(path.length() - extension.length());
if (suffix != extension)
return std::string("");
return JSONCPP_STRING("");
return path.substr(0, path.length() - extension.length());
}
@@ -237,18 +238,18 @@ static int parseCommandLine(
return printUsage(argv);
}
int index = 1;
if (std::string(argv[index]) == "--json-checker") {
if (JSONCPP_STRING(argv[index]) == "--json-checker") {
opts->features = Json::Features::strictMode();
opts->parseOnly = true;
++index;
}
if (std::string(argv[index]) == "--json-config") {
if (JSONCPP_STRING(argv[index]) == "--json-config") {
printConfig();
return 3;
}
if (std::string(argv[index]) == "--json-writer") {
if (JSONCPP_STRING(argv[index]) == "--json-writer") {
++index;
std::string const writerName(argv[index++]);
JSONCPP_STRING const writerName(argv[index++]);
if (writerName == "StyledWriter") {
opts->write = &useStyledWriter;
} else if (writerName == "StyledStreamWriter") {
@@ -270,22 +271,22 @@ static int runTest(Options const& opts)
{
int exitCode = 0;
std::string input = readInputTestFile(opts.path.c_str());
JSONCPP_STRING input = readInputTestFile(opts.path.c_str());
if (input.empty()) {
printf("Failed to read input or empty input: %s\n", opts.path.c_str());
return 3;
}
std::string basePath = removeSuffix(opts.path, ".json");
JSONCPP_STRING basePath = removeSuffix(opts.path, ".json");
if (!opts.parseOnly && basePath.empty()) {
printf("Bad input path. Path does not end with '.expected':\n%s\n",
opts.path.c_str());
return 3;
}
std::string const actualPath = basePath + ".actual";
std::string const rewritePath = basePath + ".rewrite";
std::string const rewriteActualPath = basePath + ".actual-rewrite";
JSONCPP_STRING const actualPath = basePath + ".actual";
JSONCPP_STRING const rewritePath = basePath + ".rewrite";
JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite";
Json::Value root;
exitCode = parseAndSaveValueTree(
@@ -294,7 +295,7 @@ static int runTest(Options const& opts)
if (exitCode || opts.parseOnly) {
return exitCode;
}
std::string rewrite;
JSONCPP_STRING rewrite;
exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite);
if (exitCode) {
return exitCode;
@@ -310,12 +311,12 @@ static int runTest(Options const& opts)
}
int main(int argc, const char* argv[]) {
Options opts;
try {
int exitCode = parseCommandLine(argc, argv, &opts);
if (exitCode != 0) {
printf("Failed to parse command-line.");
return exitCode;
}
try {
return runTest(opts);
}
catch (const std::exception& e) {

View File

@@ -48,8 +48,8 @@ IF(BUILD_SHARED_LIBS)
INSTALL( TARGETS jsoncpp_lib ${INSTALL_EXPORT}
RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
LIBRARY DESTINATION "${LIBRARY_INSTALL_DIR}/${CMAKE_LIBRARY_ARCHITECTURE}"
ARCHIVE DESTINATION "${ARCHIVE_INSTALL_DIR}/${CMAKE_LIBRARY_ARCHITECTURE}")
LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR})
IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11)
TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib PUBLIC
@@ -67,8 +67,8 @@ IF(BUILD_STATIC_LIBS)
INSTALL( TARGETS jsoncpp_lib_static ${INSTALL_EXPORT}
RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
LIBRARY DESTINATION "${LIBRARY_INSTALL_DIR}/${CMAKE_LIBRARY_ARCHITECTURE}"
ARCHIVE DESTINATION "${ARCHIVE_INSTALL_DIR}/${CMAKE_LIBRARY_ARCHITECTURE}")
LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR})
IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11)
TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib_static PUBLIC

View File

@@ -18,9 +18,7 @@
#include <memory>
#include <set>
#include <limits>
#if defined(__BORLANDC__)
#include <stdio.h>
#endif
#if defined(_MSC_VER)
#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
#define snprintf sprintf_s
@@ -29,11 +27,17 @@
#else
#define snprintf _snprintf
#endif
#elif defined(__ANDROID__)
#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
// Disable warning about strdup being deprecated.
@@ -45,24 +49,27 @@ static int stackDepth_g = 0; // see readValue()
namespace Json {
#if JSON_HAS_UNIQUE_PTR
typedef std::unique_ptr<CharReader> const CharReaderPtr;
#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
// ////////////////////////////////
Features::Features()
: allowComments_(true), strictRoot_(false)
{}
: allowComments_(true), strictRoot_(false),
allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
Features Features::all() { return Features(); }
Features Features::strictMode() {
Features features;
features.allowComments_ = false;
features.strictRoot_ = true;
features.allowDroppedNullPlaceholders_ = false;
features.allowNumericKeys_ = false;
return features;
}
@@ -91,7 +98,8 @@ Reader::Reader(const Features& features)
bool
Reader::parse(const std::string& document, Value& root, bool collectComments) {
document_ = document;
JSONCPP_STRING documentCopy(document.data(), document.data() + document.capacity());
std::swap(documentCopy, document_);
const char* begin = document_.c_str();
const char* end = begin + document_.length();
return parse(begin, end, root, collectComments);
@@ -103,11 +111,11 @@ bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
// Those would allow streamed input from a file, if parse() were a
// template function.
// Since std::string is reference-counted, this at least does not
// Since JSONCPP_STRING is reference-counted, this at least does not
// create an extra copy.
std::string doc;
JSONCPP_STRING doc;
std::getline(sin, doc, (char)EOF);
return parse(doc, root, collectComments);
return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
}
bool Reader::parse(const char* beginDoc,
@@ -172,9 +180,11 @@ bool Reader::readValue() {
switch (token.type_) {
case tokenObjectBegin:
successful = readObject(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenArrayBegin:
successful = readArray(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenNumber:
successful = decodeNumber(token);
@@ -186,22 +196,42 @@ bool Reader::readValue() {
{
Value v(true);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenFalse:
{
Value v(false);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenNull:
{
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
// Else, fall through...
case tokenArraySeparator:
case tokenObjectEnd:
case tokenArrayEnd:
if (features_.allowDroppedNullPlaceholders_) {
// "Un-read" the current token and mark the current value as a null
// token.
current_--;
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(current_ - begin_ - 1);
currentValue().setOffsetLimit(current_ - begin_);
break;
} // Else, fall through...
default:
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return addError("Syntax error: value, object or array expected.", token);
}
@@ -339,9 +369,9 @@ bool Reader::readComment() {
return true;
}
static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
std::string normalized;
normalized.reserve(end - begin);
static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end) {
JSONCPP_STRING normalized;
normalized.reserve(static_cast<size_t>(end - begin));
Reader::Location current = begin;
while (current != end) {
char c = *current++;
@@ -361,7 +391,7 @@ static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
void
Reader::addComment(Location begin, Location end, CommentPlacement placement) {
assert(collectComments_);
const std::string& normalized = normalizeEOL(begin, end);
const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
if (placement == commentAfterOnSameLine) {
assert(lastValue_ != 0);
lastValue_->setComment(normalized, placement);
@@ -429,11 +459,12 @@ bool Reader::readString() {
return c == '"';
}
bool Reader::readObject(Token& /*tokenStart*/) {
bool Reader::readObject(Token& tokenStart) {
Token tokenName;
std::string name;
JSONCPP_STRING name;
Value init(objectValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
while (readToken(tokenName)) {
bool initialTokenOk = true;
while (tokenName.type_ == tokenComment && initialTokenOk)
@@ -446,6 +477,11 @@ bool Reader::readObject(Token& /*tokenStart*/) {
if (tokenName.type_ == tokenString) {
if (!decodeString(tokenName, name))
return recoverFromError(tokenObjectEnd);
} else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
Value numberName;
if (!decodeNumber(tokenName, numberName))
return recoverFromError(tokenObjectEnd);
name = JSONCPP_STRING(numberName.asCString());
} else {
break;
}
@@ -479,9 +515,10 @@ bool Reader::readObject(Token& /*tokenStart*/) {
"Missing '}' or object member name", tokenName, tokenObjectEnd);
}
bool Reader::readArray(Token& /*tokenStart*/) {
bool Reader::readArray(Token& tokenStart) {
Value init(arrayValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
skipSpaces();
if (*current_ == ']') // empty array
{
@@ -521,6 +558,8 @@ bool Reader::decodeNumber(Token& token) {
if (!decodeNumber(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -542,7 +581,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
Char c = *current++;
if (c < '0' || c > '9')
return decodeDouble(token, decoded);
Value::UInt digit(c - '0');
Value::UInt digit(static_cast<Value::UInt>(c - '0'));
if (value >= threshold) {
// We've hit or exceeded the max value divided by 10 (rounded down). If
// a) we've only just touched the limit, b) this is the last digit, and
@@ -571,15 +610,17 @@ bool Reader::decodeDouble(Token& token) {
if (!decodeDouble(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
bool Reader::decodeDouble(Token& token, Value& decoded) {
double value = 0;
std::string buffer(token.start_, token.end_);
std::istringstream is(buffer);
JSONCPP_STRING buffer(token.start_, token.end_);
JSONCPP_ISTRINGSTREAM is(buffer);
if (!(is >> value))
return addError("'" + std::string(token.start_, token.end_) +
return addError("'" + JSONCPP_STRING(token.start_, token.end_) +
"' is not a number.",
token);
decoded = value;
@@ -587,16 +628,18 @@ bool Reader::decodeDouble(Token& token, Value& decoded) {
}
bool Reader::decodeString(Token& token) {
std::string decoded_string;
JSONCPP_STRING decoded_string;
if (!decodeString(token, decoded_string))
return false;
Value decoded(decoded_string);
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
bool Reader::decodeString(Token& token, std::string& decoded) {
decoded.reserve(token.end_ - token.start_ - 2);
bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) {
decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
Location current = token.start_ + 1; // skip '"'
Location end = token.end_ - 1; // do not include '"'
while (current != end) {
@@ -680,13 +723,13 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
bool Reader::decodeUnicodeEscapeSequence(Token& token,
Location& current,
Location end,
unsigned int& unicode) {
unsigned int& ret_unicode) {
if (end - current < 4)
return addError(
"Bad unicode escape sequence in string: four digits expected.",
token,
current);
unicode = 0;
int unicode = 0;
for (int index = 0; index < 4; ++index) {
Char c = *current++;
unicode *= 16;
@@ -702,11 +745,12 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
token,
current);
}
ret_unicode = static_cast<unsigned int>(unicode);
return true;
}
bool
Reader::addError(const std::string& message, Token& token, Location extra) {
Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
ErrorInfo info;
info.token_ = token;
info.message_ = message;
@@ -716,7 +760,7 @@ Reader::addError(const std::string& message, Token& token, Location extra) {
}
bool Reader::recoverFromError(TokenType skipUntilToken) {
int errorCount = int(errors_.size());
size_t const errorCount = errors_.size();
Token skip;
for (;;) {
if (!readToken(skip))
@@ -728,7 +772,7 @@ bool Reader::recoverFromError(TokenType skipUntilToken) {
return false;
}
bool Reader::addErrorAndRecover(const std::string& message,
bool Reader::addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
TokenType skipUntilToken) {
addError(message, token);
@@ -766,7 +810,7 @@ void Reader::getLocationLineAndColumn(Location location,
++line;
}
std::string Reader::getLocationLineAndColumn(Location location) const {
JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const {
int line, column;
getLocationLineAndColumn(location, line, column);
char buffer[18 + 16 + 16 + 1];
@@ -775,12 +819,12 @@ std::string Reader::getLocationLineAndColumn(Location location) const {
}
// Deprecated. Preserved for backward compatibility
std::string Reader::getFormatedErrorMessages() const {
JSONCPP_STRING Reader::getFormatedErrorMessages() const {
return getFormattedErrorMessages();
}
std::string Reader::getFormattedErrorMessages() const {
std::string formattedMessage;
JSONCPP_STRING Reader::getFormattedErrorMessages() const {
JSONCPP_STRING formattedMessage;
for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError) {
@@ -795,14 +839,64 @@ std::string Reader::getFormattedErrorMessages() const {
return formattedMessage;
}
// Reader
/////////////////////////
std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
std::vector<Reader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError) {
const ErrorInfo& error = *itError;
Reader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
structured.offset_limit = error.token_.end_ - begin_;
structured.message = error.message_;
allErrors.push_back(structured);
}
return allErrors;
}
bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
ptrdiff_t const length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = end_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = 0;
errors_.push_back(info);
return true;
}
bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
ptrdiff_t const length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length
|| extra.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = begin_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = begin_ + extra.getOffsetStart();
errors_.push_back(info);
return true;
}
bool Reader::good() const {
return !errors_.size();
}
// exact copy of Features
class OurFeatures {
public:
static OurFeatures all();
OurFeatures();
bool allowComments_;
bool strictRoot_;
bool allowDroppedNullPlaceholders_;
@@ -817,15 +911,6 @@ public:
// exact copy of Implementation of class Features
// ////////////////////////////////
OurFeatures::OurFeatures()
: allowComments_(true), strictRoot_(false)
, allowDroppedNullPlaceholders_(false), allowNumericKeys_(false)
, allowSingleQuotes_(false)
, failIfExtra_(false)
, allowSpecialFloats_(false)
{
}
OurFeatures OurFeatures::all() { return OurFeatures(); }
// Implementation of class Reader
@@ -837,9 +922,9 @@ public:
typedef char Char;
typedef const Char* Location;
struct StructuredError {
size_t offset_start;
size_t offset_limit;
std::string message;
ptrdiff_t offset_start;
ptrdiff_t offset_limit;
JSONCPP_STRING message;
};
OurReader(OurFeatures const& features);
@@ -847,7 +932,11 @@ public:
const char* endDoc,
Value& root,
bool collectComments = true);
std::string getFormattedErrorMessages() const;
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 good() const;
private:
OurReader(OurReader const&); // no impl
@@ -883,7 +972,7 @@ private:
class ErrorInfo {
public:
Token token_;
std::string message_;
JSONCPP_STRING message_;
Location extra_;
};
@@ -904,7 +993,7 @@ private:
bool decodeNumber(Token& token);
bool decodeNumber(Token& token, Value& decoded);
bool decodeString(Token& token);
bool decodeString(Token& token, std::string& decoded);
bool decodeString(Token& token, JSONCPP_STRING& decoded);
bool decodeDouble(Token& token);
bool decodeDouble(Token& token, Value& decoded);
bool decodeUnicodeCodePoint(Token& token,
@@ -915,9 +1004,9 @@ private:
Location& current,
Location end,
unsigned int& unicode);
bool addError(const std::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 std::string& message,
bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
TokenType skipUntilToken);
void skipUntilSpace();
@@ -925,20 +1014,20 @@ private:
Char getNextChar();
void
getLocationLineAndColumn(Location location, int& line, int& column) const;
std::string getLocationLineAndColumn(Location location) const;
JSONCPP_STRING getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);
typedef std::stack<Value*> Nodes;
Nodes nodes_;
Errors errors_;
std::string document_;
JSONCPP_STRING document_;
Location begin_;
Location end_;
Location current_;
Location lastValueEnd_;
Value* lastValue_;
std::string commentsBefore_;
JSONCPP_STRING commentsBefore_;
int stackDepth_;
OurFeatures const features_;
@@ -949,7 +1038,9 @@ private:
OurReader::OurReader(OurFeatures const& features)
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
lastValue_(), commentsBefore_(), features_(features), collectComments_() {
lastValue_(), commentsBefore_(),
stackDepth_(0),
features_(features), collectComments_() {
}
bool OurReader::parse(const char* beginDoc,
@@ -1015,9 +1106,11 @@ bool OurReader::readValue() {
switch (token.type_) {
case tokenObjectBegin:
successful = readObject(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenArrayBegin:
successful = readArray(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenNumber:
successful = decodeNumber(token);
@@ -1029,36 +1122,48 @@ bool OurReader::readValue() {
{
Value v(true);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenFalse:
{
Value v(false);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenNull:
{
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case 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:
{
Value v(std::numeric_limits<double>::infinity());
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenNegInf:
{
Value v(-std::numeric_limits<double>::infinity());
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenArraySeparator:
@@ -1070,9 +1175,13 @@ bool OurReader::readValue() {
current_--;
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(current_ - begin_ - 1);
currentValue().setOffsetLimit(current_ - begin_);
break;
} // else, fall through ...
default:
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return addError("Syntax error: value, object or array expected.", token);
}
@@ -1242,7 +1351,7 @@ bool OurReader::readComment() {
void
OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
assert(collectComments_);
const std::string& normalized = normalizeEOL(begin, end);
const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
if (placement == commentAfterOnSameLine) {
assert(lastValue_ != 0);
lastValue_->setComment(normalized, placement);
@@ -1327,11 +1436,12 @@ bool OurReader::readStringSingleQuote() {
return c == '\'';
}
bool OurReader::readObject(Token& /*tokenStart*/) {
bool OurReader::readObject(Token& tokenStart) {
Token tokenName;
std::string name;
JSONCPP_STRING name;
Value init(objectValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
while (readToken(tokenName)) {
bool initialTokenOk = true;
while (tokenName.type_ == tokenComment && initialTokenOk)
@@ -1360,7 +1470,7 @@ bool OurReader::readObject(Token& /*tokenStart*/) {
}
if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
std::string msg = "Duplicate key: '" + name + "'";
JSONCPP_STRING msg = "Duplicate key: '" + name + "'";
return addErrorAndRecover(
msg, tokenName, tokenObjectEnd);
}
@@ -1388,9 +1498,10 @@ bool OurReader::readObject(Token& /*tokenStart*/) {
"Missing '}' or object member name", tokenName, tokenObjectEnd);
}
bool OurReader::readArray(Token& /*tokenStart*/) {
bool OurReader::readArray(Token& tokenStart) {
Value init(arrayValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
skipSpaces();
if (*current_ == ']') // empty array
{
@@ -1430,6 +1541,8 @@ bool OurReader::decodeNumber(Token& token) {
if (!decodeNumber(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -1451,7 +1564,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
Char c = *current++;
if (c < '0' || c > '9')
return decodeDouble(token, decoded);
Value::UInt digit(c - '0');
Value::UInt digit(static_cast<Value::UInt>(c - '0'));
if (value >= threshold) {
// We've hit or exceeded the max value divided by 10 (rounded down). If
// a) we've only just touched the limit, b) this is the last digit, and
@@ -1478,15 +1591,42 @@ bool OurReader::decodeDouble(Token& token) {
if (!decodeDouble(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
bool OurReader::decodeDouble(Token& token, Value& decoded) {
double value = 0;
std::string buffer( token.start_, token.end_ );
std::istringstream is(buffer);
if (!(is >> value))
return addError("'" + std::string(token.start_, token.end_) +
const int bufferSize = 32;
int count;
ptrdiff_t const length = token.end_ - token.start_;
// Sanity check to avoid buffer overflow exploits.
if (length < 0) {
return addError("Unable to parse token length", token);
}
size_t const ulength = static_cast<size_t>(length);
// Avoid using a string constant for the format control string given to
// sscanf, as this can cause hard to debug crashes on OS X. See here for more
// info:
//
// http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
char format[] = "%lf";
if (length <= bufferSize) {
Char buffer[bufferSize + 1];
memcpy(buffer, token.start_, ulength);
buffer[length] = 0;
count = sscanf(buffer, format, &value);
} else {
JSONCPP_STRING buffer(token.start_, token.end_);
count = sscanf(buffer.c_str(), format, &value);
}
if (count != 1)
return addError("'" + JSONCPP_STRING(token.start_, token.end_) +
"' is not a number.",
token);
decoded = value;
@@ -1494,16 +1634,18 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) {
}
bool OurReader::decodeString(Token& token) {
std::string decoded_string;
JSONCPP_STRING decoded_string;
if (!decodeString(token, decoded_string))
return false;
Value decoded(decoded_string);
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
bool OurReader::decodeString(Token& token, std::string& decoded) {
decoded.reserve(token.end_ - token.start_ - 2);
bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) {
decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
Location current = token.start_ + 1; // skip '"'
Location end = token.end_ - 1; // do not include '"'
while (current != end) {
@@ -1587,13 +1729,13 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
bool OurReader::decodeUnicodeEscapeSequence(Token& token,
Location& current,
Location end,
unsigned int& unicode) {
unsigned int& ret_unicode) {
if (end - current < 4)
return addError(
"Bad unicode escape sequence in string: four digits expected.",
token,
current);
unicode = 0;
int unicode = 0;
for (int index = 0; index < 4; ++index) {
Char c = *current++;
unicode *= 16;
@@ -1609,11 +1751,12 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token,
token,
current);
}
ret_unicode = static_cast<unsigned int>(unicode);
return true;
}
bool
OurReader::addError(const std::string& message, Token& token, Location extra) {
OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
ErrorInfo info;
info.token_ = token;
info.message_ = message;
@@ -1623,7 +1766,7 @@ OurReader::addError(const std::string& message, Token& token, Location extra) {
}
bool OurReader::recoverFromError(TokenType skipUntilToken) {
int errorCount = int(errors_.size());
size_t errorCount = errors_.size();
Token skip;
for (;;) {
if (!readToken(skip))
@@ -1635,7 +1778,7 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) {
return false;
}
bool OurReader::addErrorAndRecover(const std::string& message,
bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
TokenType skipUntilToken) {
addError(message, token);
@@ -1673,7 +1816,7 @@ void OurReader::getLocationLineAndColumn(Location location,
++line;
}
std::string OurReader::getLocationLineAndColumn(Location location) const {
JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const {
int line, column;
getLocationLineAndColumn(location, line, column);
char buffer[18 + 16 + 16 + 1];
@@ -1681,8 +1824,8 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
return buffer;
}
std::string OurReader::getFormattedErrorMessages() const {
std::string formattedMessage;
JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
JSONCPP_STRING formattedMessage;
for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError) {
@@ -1697,6 +1840,60 @@ std::string OurReader::getFormattedErrorMessages() const {
return formattedMessage;
}
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
std::vector<OurReader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError) {
const ErrorInfo& error = *itError;
OurReader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
structured.offset_limit = error.token_.end_ - begin_;
structured.message = error.message_;
allErrors.push_back(structured);
}
return allErrors;
}
bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
ptrdiff_t length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = end_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = 0;
errors_.push_back(info);
return true;
}
bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
ptrdiff_t length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length
|| extra.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = begin_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = begin_ + extra.getOffsetStart();
errors_.push_back(info);
return true;
}
bool OurReader::good() const {
return !errors_.size();
}
class OurCharReader : public CharReader {
bool const collectComments_;
@@ -1708,9 +1905,9 @@ public:
: collectComments_(collectComments)
, reader_(features)
{}
virtual bool parse(
bool parse(
char const* beginDoc, char const* endDoc,
Value* root, std::string* errs) {
Value* root, JSONCPP_STRING* errs) override {
bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
if (errs) {
*errs = reader_.getFormattedErrorMessages();
@@ -1740,7 +1937,7 @@ CharReader* CharReaderBuilder::newCharReader() const
features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
return new OurCharReader(collectComments, features);
}
static void getValidReaderKeys(std::set<std::string>* valid_keys)
static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
{
valid_keys->clear();
valid_keys->insert("collectComments");
@@ -1759,19 +1956,19 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const
Json::Value my_invalid;
if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
Json::Value& inv = *invalid;
std::set<std::string> valid_keys;
std::set<JSONCPP_STRING> valid_keys;
getValidReaderKeys(&valid_keys);
Value::Members keys = settings_.getMemberNames();
size_t n = keys.size();
for (size_t i = 0; i < n; ++i) {
std::string const& key = keys[i];
JSONCPP_STRING const& key = keys[i];
if (valid_keys.find(key) == valid_keys.end()) {
inv[key] = settings_[key];
}
}
return 0u == inv.size();
}
Value& CharReaderBuilder::operator[](std::string key)
Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
{
return settings_[key];
}
@@ -1784,6 +1981,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
(*settings)["allowDroppedNullPlaceholders"] = false;
(*settings)["allowNumericKeys"] = false;
(*settings)["allowSingleQuotes"] = false;
(*settings)["stackLimit"] = 1000;
(*settings)["failIfExtra"] = true;
(*settings)["rejectDupKeys"] = true;
(*settings)["allowSpecialFloats"] = false;
@@ -1810,12 +2008,12 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
// global functions
bool parseFromStream(
CharReader::Factory const& fact, std::istream& sin,
Value* root, std::string* errs)
CharReader::Factory const& fact, JSONCPP_ISTREAM& sin,
Value* root, JSONCPP_STRING* errs)
{
std::ostringstream ssin;
JSONCPP_OSTRINGSTREAM ssin;
ssin << sin.rdbuf();
std::string doc = ssin.str();
JSONCPP_STRING doc = ssin.str();
char const* begin = doc.data();
char const* end = begin + doc.size();
// Note that we do not actually need a null-terminator.
@@ -1823,16 +2021,16 @@ bool parseFromStream(
return reader->parse(begin, end, root, errs);
}
std::istream& operator>>(std::istream& sin, Value& root) {
JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
CharReaderBuilder b;
std::string errs;
JSONCPP_STRING errs;
bool ok = parseFromStream(b, sin, &root, &errs);
if (!ok) {
fprintf(stderr,
"Error from reader: %s",
errs.c_str());
throwRuntimeError("reader error");
throwRuntimeError(errs);
}
return sin;
}

View File

@@ -15,8 +15,8 @@
namespace Json {
/// Converts a unicode code-point to UTF-8.
static inline std::string codePointToUTF8(unsigned int cp) {
std::string result;
static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
JSONCPP_STRING result;
// based on description from http://en.wikipedia.org/wiki/UTF-8

View File

@@ -18,9 +18,7 @@
#endif
#include <cstddef> // size_t
#include <algorithm> // min()
#if defined(__BORLANDC__)
#include <mem.h>
#endif
#define JSON_ASSERT_UNREACHABLE assert(false)
namespace Json {
@@ -31,13 +29,12 @@ namespace Json {
#if defined(__ARMEL__)
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#else
// This exists for binary compatibility only. Use nullRef.
const Value Value::null;
#define ALIGNAS(byte_alignment)
#endif
static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
const unsigned char& kNullRef = kNull[0];
const Value& Value::nullRef = reinterpret_cast<const Value&>(kNullRef);
const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
const Value& Value::nullRef = null;
const Int Value::minInt = Int(~(UInt(-1) / 2));
const Int Value::maxInt = Int(UInt(-1) / 2);
@@ -58,11 +55,14 @@ const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
template <typename T, typename U>
static inline bool InRange(double d, T min, U max) {
// 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 >= min && d <= max;
}
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
static inline double integerToDouble(Json::UInt64 value) {
return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1));
}
template <typename T> static inline double integerToDouble(T value) {
@@ -83,10 +83,11 @@ static inline bool InRange(double d, T min, U max) {
* @return Pointer on the duplicate instance of string.
*/
static inline char* duplicateStringValue(const char* value,
size_t length) {
size_t length)
{
// Avoid an integer overflow in the call to malloc below by limiting length
// to a sane value.
if (length >= (size_t)Value::maxInt)
if (length >= static_cast<size_t>(Value::maxInt))
length = Value::maxInt - 1;
char* newString = static_cast<char*>(malloc(length + 1));
@@ -108,7 +109,7 @@ static inline char* duplicateAndPrefixStringValue(
{
// Avoid an integer overflow in the call to malloc below by limiting length
// to a sane value.
JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U,
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;
@@ -137,7 +138,29 @@ inline static void decodePrefixedString(
}
/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
*/
static inline void releaseStringValue(char* value) { free(value); }
#if JSONCPP_USING_SECURE_MEMORY
static inline void releasePrefixedStringValue(char* value) {
unsigned length = 0;
char const* valueDecoded;
decodePrefixedString(true, value, &length, &valueDecoded);
size_t const size = sizeof(unsigned) + length + 1U;
memset(value, 0, size);
free(value);
}
static inline void releaseStringValue(char* value, unsigned length) {
// length==0 => we allocated the strings memory
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 length) {
free(value);
}
#endif // JSONCPP_USING_SECURE_MEMORY
} // namespace Json
@@ -155,7 +178,7 @@ static inline void releaseStringValue(char* value) { free(value); }
namespace Json {
Exception::Exception(std::string const& msg)
Exception::Exception(JSONCPP_STRING const& msg)
: msg_(msg)
{}
Exception::~Exception() throw()
@@ -164,17 +187,17 @@ char const* Exception::what() const throw()
{
return msg_.c_str();
}
RuntimeError::RuntimeError(std::string const& msg)
RuntimeError::RuntimeError(JSONCPP_STRING const& msg)
: Exception(msg)
{}
LogicError::LogicError(std::string const& msg)
LogicError::LogicError(JSONCPP_STRING const& msg)
: Exception(msg)
{}
JSONCPP_NORETURN void throwRuntimeError(std::string const& msg)
JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
{
throw RuntimeError(msg);
}
JSONCPP_NORETURN void throwLogicError(std::string const& msg)
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
{
throw LogicError(msg);
}
@@ -187,16 +210,17 @@ JSONCPP_NORETURN void throwLogicError(std::string const& msg)
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
Value::CommentInfo::CommentInfo() : comment_(0) {}
Value::CommentInfo::CommentInfo() : comment_(0)
{}
Value::CommentInfo::~CommentInfo() {
if (comment_)
releaseStringValue(comment_);
releaseStringValue(comment_, 0u);
}
void Value::CommentInfo::setComment(const char* text, size_t len) {
if (comment_) {
releaseStringValue(comment_);
releaseStringValue(comment_, 0u);
comment_ = 0;
}
JSON_ASSERT(text != 0);
@@ -221,28 +245,34 @@ 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)
: cstr_(str)
{
: cstr_(str) {
// allocate != duplicate
storage_.policy_ = allocate & 0x3;
storage_.length_ = ulength & 0x3FFFFFFF;
}
Value::CZString::CZString(const CZString& other)
: cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
? duplicateStringValue(other.cstr_, other.storage_.length_)
: other.cstr_)
{
storage_.policy_ = (other.cstr_
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_));
: 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_) {
other.cstr_ = nullptr;
}
#endif
Value::CZString::~CZString() {
if (cstr_ && storage_.policy_ == duplicate)
releaseStringValue(const_cast<char*>(cstr_));
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
}
}
void Value::CZString::swap(CZString& other) {
@@ -262,6 +292,7 @@ bool Value::CZString::operator<(const CZString& other) const {
unsigned this_len = this->storage_.length_;
unsigned other_len = other.storage_.length_;
unsigned min_len = std::min(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;
@@ -275,6 +306,7 @@ bool Value::CZString::operator==(const CZString& other) const {
unsigned this_len = this->storage_.length_;
unsigned other_len = other.storage_.length_;
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;
}
@@ -361,7 +393,7 @@ Value::Value(const char* beginValue, const char* endValue) {
duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
}
Value::Value(const std::string& value) {
Value::Value(const JSONCPP_STRING& value) {
initBasic(stringValue, true);
value_.string_ =
duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
@@ -387,7 +419,7 @@ Value::Value(bool value) {
Value::Value(Value const& other)
: type_(other.type_), allocated_(false)
,
comments_(0)
comments_(0), start_(other.start_), limit_(other.limit_)
{
switch (type_) {
case nullValue:
@@ -428,6 +460,14 @@ Value::Value(Value const& other)
}
}
#if JSON_HAS_RVALUE_REFERENCES
// Move constructor
Value::Value(Value&& other) {
initBasic(nullValue);
swap(other);
}
#endif
Value::~Value() {
switch (type_) {
case nullValue:
@@ -438,7 +478,7 @@ Value::~Value() {
break;
case stringValue:
if (allocated_)
releaseStringValue(value_.string_);
releasePrefixedStringValue(value_.string_);
break;
case arrayValue:
case objectValue:
@@ -450,11 +490,12 @@ Value::~Value() {
if (comments_)
delete[] comments_;
value_.uint_ = 0;
}
Value &Value::operator=(const Value &other) {
Value temp(other);
swap(temp);
Value& Value::operator=(Value other) {
swap(other);
return *this;
}
@@ -471,6 +512,8 @@ void Value::swapPayload(Value& other) {
void Value::swap(Value& other) {
swapPayload(other);
std::swap(comments_, other.comments_);
std::swap(start_, other.start_);
std::swap(limit_, other.limit_);
}
ValueType Value::type() const { return type_; }
@@ -511,6 +554,7 @@ bool Value::operator<(const Value& other) const {
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
unsigned min_len = std::min(this_len, other_len);
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;
@@ -566,6 +610,7 @@ bool Value::operator==(const Value& other) const {
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;
}
@@ -591,6 +636,18 @@ const char* Value::asCString() const {
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;
unsigned this_len;
char const* 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;
@@ -600,7 +657,7 @@ bool Value::getString(char const** str, char const** cend) const {
return true;
}
std::string Value::asString() const {
JSONCPP_STRING Value::asString() const {
switch (type_) {
case nullValue:
return "";
@@ -610,7 +667,7 @@ std::string Value::asString() const {
unsigned this_len;
char const* this_str;
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
return std::string(this_str, this_len);
return JSONCPP_STRING(this_str, this_len);
}
case booleanValue:
return value_.bool_ ? "true" : "false";
@@ -770,7 +827,8 @@ float Value::asFloat() const {
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return static_cast<float>(value_.uint_);
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return integerToDouble(value_.uint_);
// This can fail (silently?) if the value is bigger than MAX_FLOAT.
return static_cast<float>(integerToDouble(value_.uint_));
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
case realValue:
return static_cast<float>(value_.real_);
@@ -873,6 +931,8 @@ void Value::clear() {
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
type_ == objectValue,
"in Json::Value::clear(): requires complex value");
start_ = 0;
limit_ = 0;
switch (type_) {
case arrayValue:
case objectValue:
@@ -897,7 +957,7 @@ void Value::resize(ArrayIndex newSize) {
for (ArrayIndex index = newSize; index < oldSize; ++index) {
value_.map_->erase(index);
}
assert(size() == newSize);
JSON_ASSERT(size() == newSize);
}
}
@@ -948,6 +1008,8 @@ void Value::initBasic(ValueType vtype, bool allocated) {
type_ = vtype;
allocated_ = allocated;
comments_ = 0;
start_ = 0;
limit_ = 0;
}
// Access an object value by name, create a null member if it does not exist.
@@ -1015,7 +1077,7 @@ const Value& Value::operator[](const char* key) const
if (!found) return nullRef;
return *found;
}
Value const& Value::operator[](std::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 nullRef;
@@ -1026,7 +1088,7 @@ Value& Value::operator[](const char* key) {
return resolveReference(key, key + strlen(key));
}
Value& Value::operator[](const std::string& key) {
Value& Value::operator[](const JSONCPP_STRING& key) {
return resolveReference(key.data(), key.data() + key.length());
}
@@ -1057,7 +1119,7 @@ Value Value::get(char const* key, Value const& defaultValue) const
{
return get(key, key + strlen(key), defaultValue);
}
Value Value::get(std::string const& key, Value const& defaultValue) const
Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const
{
return get(key.data(), key.data() + key.length(), defaultValue);
}
@@ -1080,7 +1142,7 @@ bool Value::removeMember(const char* key, Value* removed)
{
return removeMember(key, key + strlen(key), removed);
}
bool Value::removeMember(std::string const& key, Value* removed)
bool Value::removeMember(JSONCPP_STRING const& key, Value* removed)
{
return removeMember(key.data(), key.data() + key.length(), removed);
}
@@ -1095,7 +1157,7 @@ Value Value::removeMember(const char* key)
removeMember(key, key + strlen(key), &removed);
return removed; // still null if removeMember() did nothing
}
Value Value::removeMember(const std::string& key)
Value Value::removeMember(const JSONCPP_STRING& key)
{
return removeMember(key.c_str());
}
@@ -1139,7 +1201,7 @@ bool Value::isMember(char const* key) const
{
return isMember(key, key + strlen(key));
}
bool Value::isMember(std::string const& key) const
bool Value::isMember(JSONCPP_STRING const& key) const
{
return isMember(key.data(), key.data() + key.length());
}
@@ -1161,7 +1223,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(std::string((*it).first.data(),
members.push_back(JSONCPP_STRING((*it).first.data(),
(*it).first.length()));
}
return members;
@@ -1303,7 +1365,7 @@ void Value::setComment(const char* comment, CommentPlacement placement) {
setComment(comment, strlen(comment), placement);
}
void Value::setComment(const std::string& comment, CommentPlacement placement) {
void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) {
setComment(comment.c_str(), comment.length(), placement);
}
@@ -1311,13 +1373,21 @@ bool Value::hasComment(CommentPlacement placement) const {
return comments_ != 0 && comments_[placement].comment_ != 0;
}
std::string Value::getComment(CommentPlacement placement) const {
JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
if (hasComment(placement))
return comments_[placement].comment_;
return "";
}
std::string Value::toStyledString() const {
void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
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);
}
@@ -1385,13 +1455,13 @@ PathArgument::PathArgument(ArrayIndex index)
PathArgument::PathArgument(const char* key)
: key_(key), index_(), kind_(kindKey) {}
PathArgument::PathArgument(const std::string& key)
PathArgument::PathArgument(const JSONCPP_STRING& key)
: key_(key.c_str()), index_(), kind_(kindKey) {}
// class Path
// //////////////////////////////////////////////////////////////////
Path::Path(const std::string& path,
Path::Path(const JSONCPP_STRING& path,
const PathArgument& a1,
const PathArgument& a2,
const PathArgument& a3,
@@ -1406,7 +1476,7 @@ Path::Path(const std::string& path,
makePath(path, in);
}
void Path::makePath(const std::string& path, const InArgs& in) {
void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) {
const char* current = path.c_str();
const char* end = current + path.length();
InArgs::const_iterator itInArg = in.begin();
@@ -1432,12 +1502,12 @@ void Path::makePath(const std::string& path, const InArgs& in) {
const char* beginName = current;
while (current != end && !strchr("[.", *current))
++current;
args_.push_back(std::string(beginName, current));
args_.push_back(JSONCPP_STRING(beginName, current));
}
}
}
void Path::addPathInArg(const std::string& /*path*/,
void Path::addPathInArg(const JSONCPP_STRING& /*path*/,
const InArgs& in,
InArgs::const_iterator& itInArg,
PathArgument::Kind kind) {
@@ -1450,7 +1520,7 @@ void Path::addPathInArg(const std::string& /*path*/,
}
}
void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) {
// Error: invalid path.
}

View File

@@ -92,12 +92,12 @@ UInt ValueIteratorBase::index() const {
return Value::UInt(-1);
}
std::string ValueIteratorBase::name() const {
JSONCPP_STRING ValueIteratorBase::name() const {
char const* keey;
char const* end;
keey = memberName(&end);
if (!keey) return std::string();
return std::string(keey, end);
if (!keey) return JSONCPP_STRING();
return JSONCPP_STRING(keey, end);
}
char const* ValueIteratorBase::memberName() const {
@@ -129,6 +129,9 @@ ValueConstIterator::ValueConstIterator(
const Value::ObjectValues::iterator& current)
: ValueIteratorBase(current) {}
ValueConstIterator::ValueConstIterator(ValueIterator const& other)
: ValueIteratorBase(other) {}
ValueConstIterator& ValueConstIterator::
operator=(const ValueIteratorBase& other) {
copy(other);
@@ -149,7 +152,9 @@ ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
: ValueIteratorBase(current) {}
ValueIterator::ValueIterator(const ValueConstIterator& other)
: ValueIteratorBase(other) {}
: ValueIteratorBase(other) {
throwRuntimeError("ConstIterator to Iterator should never be allowed.");
}
ValueIterator::ValueIterator(const ValueIterator& other)
: ValueIteratorBase(other) {}

View File

@@ -16,33 +16,51 @@
#include <cstring>
#include <cstdio>
#if defined(__BORLANDC__)
#include <stdio.h>
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
#include <float.h>
#define isfinite _finite
#elif defined(__sun) && defined(__SVR4) //Solaris
#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(isfinite)
#if defined(__ia64) && !defined(finite)
#define isfinite(x) ((sizeof(x) == sizeof(float) ? \
_Isfinitef(x) : _IsFinite(x)))
#else
#include <math.h>
#define isfinite finite
#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
#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__)
#elif defined(__ANDROID__) || defined(__QNXNTO__)
#define snprintf snprintf
#elif __cplusplus >= 201103L
#if !defined(__MINGW32__) && !defined(__CYGWIN__)
#define snprintf std::snprintf
#endif
#endif
#if defined(__BORLANDC__)
#include <float.h>
@@ -57,10 +75,10 @@
namespace Json {
#if JSON_HAS_UNIQUE_PTR
typedef std::unique_ptr<StreamWriter> const StreamWriterPtr;
#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) {
@@ -81,7 +99,7 @@ static bool containsControlCharacter0(const char* str, unsigned len) {
return false;
}
std::string valueToString(LargestInt value) {
JSONCPP_STRING valueToString(LargestInt value) {
UIntToStringBuffer buffer;
char* current = buffer + sizeof(buffer);
if (value == Value::minLargestInt) {
@@ -97,7 +115,7 @@ std::string valueToString(LargestInt value) {
return current;
}
std::string valueToString(LargestUInt value) {
JSONCPP_STRING valueToString(LargestUInt value) {
UIntToStringBuffer buffer;
char* current = buffer + sizeof(buffer);
uintToString(value, current);
@@ -107,17 +125,17 @@ std::string valueToString(LargestUInt value) {
#if defined(JSON_HAS_INT64)
std::string valueToString(Int value) {
JSONCPP_STRING valueToString(Int value) {
return valueToString(LargestInt(value));
}
std::string valueToString(UInt value) {
JSONCPP_STRING valueToString(UInt value) {
return valueToString(LargestUInt(value));
}
#endif // # if defined(JSON_HAS_INT64)
std::string valueToString(double value, bool useSpecialFloats, unsigned int precision) {
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[32];
@@ -147,23 +165,23 @@ std::string valueToString(double value, bool useSpecialFloats, unsigned int prec
return buffer;
}
std::string valueToString(double value) { return valueToString(value, false, 17); }
JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); }
std::string valueToString(bool value) { return value ? "true" : "false"; }
JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; }
std::string valueToQuotedString(const char* value) {
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 std::string("\"") + value + "\"";
return JSONCPP_STRING("\"") + value + "\"";
// We have to walk value and escape any special characters.
// Appending to std::string is not efficient, but this should be rare.
// Appending to JSONCPP_STRING is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
std::string::size_type maxsize =
JSONCPP_STRING::size_type maxsize =
strlen(value) * 2 + 3; // allescaped+quotes+NULL
std::string result;
JSONCPP_STRING result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
for (const char* c = value; *c != 0; ++c) {
@@ -199,7 +217,7 @@ std::string valueToQuotedString(const char* value) {
// sequence from occurring.
default:
if (isControlCharacter(*c)) {
std::ostringstream oss;
JSONCPP_OSTRINGSTREAM oss;
oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
<< std::setw(4) << static_cast<int>(*c);
result += oss.str();
@@ -228,19 +246,19 @@ static char const* strnpbrk(char const* s, char const* accept, size_t n) {
}
return NULL;
}
static std::string valueToQuotedStringN(const char* value, unsigned length) {
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))
return std::string("\"") + value + "\"";
return JSONCPP_STRING("\"") + value + "\"";
// We have to walk value and escape any special characters.
// Appending to std::string is not efficient, but this should be rare.
// Appending to JSONCPP_STRING is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
std::string::size_type maxsize =
JSONCPP_STRING::size_type maxsize =
length * 2 + 3; // allescaped+quotes+NULL
std::string result;
JSONCPP_STRING result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
char const* end = value + length;
@@ -277,7 +295,7 @@ static std::string valueToQuotedStringN(const char* value, unsigned length) {
// sequence from occurring.
default:
if ((isControlCharacter(*c)) || (*c == 0)) {
std::ostringstream oss;
JSONCPP_OSTRINGSTREAM oss;
oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
<< std::setw(4) << static_cast<int>(*c);
result += oss.str();
@@ -299,21 +317,28 @@ Writer::~Writer() {}
// //////////////////////////////////////////////////////////////////
FastWriter::FastWriter()
: yamlCompatiblityEnabled_(false) {}
: yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
omitEndingLineFeed_(false) {}
void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
std::string FastWriter::write(const Value& root) {
void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
JSONCPP_STRING FastWriter::write(const Value& root) {
document_ = "";
writeValue(root);
document_ += "\n";
if (!omitEndingLineFeed_)
document_ += "\n";
return document_;
}
void FastWriter::writeValue(const Value& value) {
switch (value.type()) {
case nullValue:
document_ += "null";
if (!dropNullPlaceholders_)
document_ += "null";
break;
case intValue:
document_ += valueToString(value.asLargestInt());
@@ -338,8 +363,8 @@ void FastWriter::writeValue(const Value& value) {
break;
case arrayValue: {
document_ += '[';
int size = value.size();
for (int index = 0; index < size; ++index) {
ArrayIndex size = value.size();
for (ArrayIndex index = 0; index < size; ++index) {
if (index > 0)
document_ += ',';
writeValue(value[index]);
@@ -351,7 +376,7 @@ void FastWriter::writeValue(const Value& value) {
document_ += '{';
for (Value::Members::iterator it = members.begin(); it != members.end();
++it) {
const std::string& name = *it;
const JSONCPP_STRING& name = *it;
if (it != members.begin())
document_ += ',';
document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
@@ -369,7 +394,7 @@ void FastWriter::writeValue(const Value& value) {
StyledWriter::StyledWriter()
: rightMargin_(74), indentSize_(3), addChildValues_() {}
std::string StyledWriter::write(const Value& root) {
JSONCPP_STRING StyledWriter::write(const Value& root) {
document_ = "";
addChildValues_ = false;
indentString_ = "";
@@ -419,7 +444,7 @@ void StyledWriter::writeValue(const Value& value) {
indent();
Value::Members::iterator it = members.begin();
for (;;) {
const std::string& name = *it;
const JSONCPP_STRING& name = *it;
const Value& childValue = value[name];
writeCommentBeforeValue(childValue);
writeWithIndent(valueToQuotedString(name.c_str()));
@@ -483,26 +508,25 @@ void StyledWriter::writeArrayValue(const Value& value) {
}
bool StyledWriter::isMultineArray(const Value& value) {
int size = value.size();
ArrayIndex const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
for (int index = 0; index < size && !isMultiLine; ++index) {
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
const Value& childValue = value[index];
isMultiLine =
isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
}
if (!isMultiLine) // check if line length > max line length
{
childValues_.reserve(size);
addChildValues_ = true;
int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
for (int index = 0; index < size; ++index) {
ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
for (ArrayIndex index = 0; index < size; ++index) {
if (hasCommentForValue(value[index])) {
isMultiLine = true;
}
writeValue(value[index]);
lineLength += int(childValues_[index].length());
lineLength += static_cast<ArrayIndex>(childValues_[index].length());
}
addChildValues_ = false;
isMultiLine = isMultiLine || lineLength >= rightMargin_;
@@ -510,7 +534,7 @@ bool StyledWriter::isMultineArray(const Value& value) {
return isMultiLine;
}
void StyledWriter::pushValue(const std::string& value) {
void StyledWriter::pushValue(const JSONCPP_STRING& value) {
if (addChildValues_)
childValues_.push_back(value);
else
@@ -528,15 +552,15 @@ void StyledWriter::writeIndent() {
document_ += indentString_;
}
void StyledWriter::writeWithIndent(const std::string& value) {
void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) {
writeIndent();
document_ += value;
}
void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); }
void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); }
void StyledWriter::unindent() {
assert(int(indentString_.size()) >= indentSize_);
assert(indentString_.size() >= indentSize_);
indentString_.resize(indentString_.size() - indentSize_);
}
@@ -546,8 +570,8 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) {
document_ += "\n";
writeIndent();
const std::string& comment = root.getComment(commentBefore);
std::string::const_iterator iter = comment.begin();
const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) {
document_ += *iter;
if (*iter == '\n' &&
@@ -580,11 +604,11 @@ bool StyledWriter::hasCommentForValue(const Value& value) {
// Class StyledStreamWriter
// //////////////////////////////////////////////////////////////////
StyledStreamWriter::StyledStreamWriter(std::string indentation)
StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
: document_(NULL), rightMargin_(74), indentation_(indentation),
addChildValues_() {}
void StyledStreamWriter::write(std::ostream& out, const Value& root) {
void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
document_ = &out;
addChildValues_ = false;
indentString_ = "";
@@ -637,7 +661,7 @@ void StyledStreamWriter::writeValue(const Value& value) {
indent();
Value::Members::iterator it = members.begin();
for (;;) {
const std::string& name = *it;
const JSONCPP_STRING& name = *it;
const Value& childValue = value[name];
writeCommentBeforeValue(childValue);
writeWithIndent(valueToQuotedString(name.c_str()));
@@ -703,26 +727,25 @@ void StyledStreamWriter::writeArrayValue(const Value& value) {
}
bool StyledStreamWriter::isMultineArray(const Value& value) {
int size = value.size();
ArrayIndex const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
for (int index = 0; index < size && !isMultiLine; ++index) {
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
const Value& childValue = value[index];
isMultiLine =
isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
}
if (!isMultiLine) // check if line length > max line length
{
childValues_.reserve(size);
addChildValues_ = true;
int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
for (int index = 0; index < size; ++index) {
ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
for (ArrayIndex index = 0; index < size; ++index) {
if (hasCommentForValue(value[index])) {
isMultiLine = true;
}
writeValue(value[index]);
lineLength += int(childValues_[index].length());
lineLength += static_cast<ArrayIndex>(childValues_[index].length());
}
addChildValues_ = false;
isMultiLine = isMultiLine || lineLength >= rightMargin_;
@@ -730,7 +753,7 @@ bool StyledStreamWriter::isMultineArray(const Value& value) {
return isMultiLine;
}
void StyledStreamWriter::pushValue(const std::string& value) {
void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) {
if (addChildValues_)
childValues_.push_back(value);
else
@@ -745,7 +768,7 @@ void StyledStreamWriter::writeIndent() {
*document_ << '\n' << indentString_;
}
void StyledStreamWriter::writeWithIndent(const std::string& value) {
void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) {
if (!indented_) writeIndent();
*document_ << value;
indented_ = false;
@@ -763,8 +786,8 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
return;
if (!indented_) writeIndent();
const std::string& comment = root.getComment(commentBefore);
std::string::const_iterator iter = comment.begin();
const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) {
*document_ << *iter;
if (*iter == '\n' &&
@@ -809,48 +832,48 @@ struct CommentStyle {
struct BuiltStyledStreamWriter : public StreamWriter
{
BuiltStyledStreamWriter(
std::string const& indentation,
JSONCPP_STRING const& indentation,
CommentStyle::Enum cs,
std::string const& colonSymbol,
std::string const& nullSymbol,
std::string const& endingLineFeedSymbol,
JSONCPP_STRING const& colonSymbol,
JSONCPP_STRING const& nullSymbol,
JSONCPP_STRING const& endingLineFeedSymbol,
bool useSpecialFloats,
unsigned int precision);
virtual int write(Value const& root, std::ostream* sout);
int write(Value const& root, JSONCPP_OSTREAM* sout) override;
private:
void writeValue(Value const& value);
void writeArrayValue(Value const& value);
bool isMultineArray(Value const& value);
void pushValue(std::string const& value);
void pushValue(JSONCPP_STRING const& value);
void writeIndent();
void writeWithIndent(std::string const& value);
void writeWithIndent(JSONCPP_STRING const& value);
void indent();
void unindent();
void writeCommentBeforeValue(Value const& root);
void writeCommentAfterValueOnSameLine(Value const& root);
static bool hasCommentForValue(const Value& value);
typedef std::vector<std::string> ChildValues;
typedef std::vector<JSONCPP_STRING> ChildValues;
ChildValues childValues_;
std::string indentString_;
int rightMargin_;
std::string indentation_;
JSONCPP_STRING indentString_;
unsigned int rightMargin_;
JSONCPP_STRING indentation_;
CommentStyle::Enum cs_;
std::string colonSymbol_;
std::string nullSymbol_;
std::string endingLineFeedSymbol_;
JSONCPP_STRING colonSymbol_;
JSONCPP_STRING nullSymbol_;
JSONCPP_STRING endingLineFeedSymbol_;
bool addChildValues_ : 1;
bool indented_ : 1;
bool useSpecialFloats_ : 1;
unsigned int precision_;
};
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
std::string const& indentation,
JSONCPP_STRING const& indentation,
CommentStyle::Enum cs,
std::string const& colonSymbol,
std::string const& nullSymbol,
std::string const& endingLineFeedSymbol,
JSONCPP_STRING const& colonSymbol,
JSONCPP_STRING const& nullSymbol,
JSONCPP_STRING const& endingLineFeedSymbol,
bool useSpecialFloats,
unsigned int precision)
: rightMargin_(74)
@@ -865,7 +888,7 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
, precision_(precision)
{
}
int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
{
sout_ = sout;
addChildValues_ = false;
@@ -919,7 +942,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
indent();
Value::Members::iterator it = members.begin();
for (;;) {
std::string const& name = *it;
JSONCPP_STRING const& name = *it;
Value const& childValue = value[name];
writeCommentBeforeValue(childValue);
writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
@@ -987,26 +1010,25 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
}
bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
int size = value.size();
ArrayIndex const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
for (int index = 0; index < size && !isMultiLine; ++index) {
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
Value const& childValue = value[index];
isMultiLine =
isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
}
if (!isMultiLine) // check if line length > max line length
{
childValues_.reserve(size);
addChildValues_ = true;
int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
for (int index = 0; index < size; ++index) {
ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
for (ArrayIndex index = 0; index < size; ++index) {
if (hasCommentForValue(value[index])) {
isMultiLine = true;
}
writeValue(value[index]);
lineLength += int(childValues_[index].length());
lineLength += static_cast<ArrayIndex>(childValues_[index].length());
}
addChildValues_ = false;
isMultiLine = isMultiLine || lineLength >= rightMargin_;
@@ -1014,7 +1036,7 @@ bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
return isMultiLine;
}
void BuiltStyledStreamWriter::pushValue(std::string const& value) {
void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) {
if (addChildValues_)
childValues_.push_back(value);
else
@@ -1033,7 +1055,7 @@ void BuiltStyledStreamWriter::writeIndent() {
}
}
void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) {
void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) {
if (!indented_) writeIndent();
*sout_ << value;
indented_ = false;
@@ -1052,8 +1074,8 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
return;
if (!indented_) writeIndent();
const std::string& comment = root.getComment(commentBefore);
std::string::const_iterator iter = comment.begin();
const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) {
*sout_ << *iter;
if (*iter == '\n' &&
@@ -1103,8 +1125,8 @@ StreamWriterBuilder::~StreamWriterBuilder()
{}
StreamWriter* StreamWriterBuilder::newStreamWriter() const
{
std::string indentation = settings_["indentation"].asString();
std::string cs_str = settings_["commentStyle"].asString();
JSONCPP_STRING indentation = settings_["indentation"].asString();
JSONCPP_STRING cs_str = settings_["commentStyle"].asString();
bool eyc = settings_["enableYAMLCompatibility"].asBool();
bool dnp = settings_["dropNullPlaceholders"].asBool();
bool usf = settings_["useSpecialFloats"].asBool();
@@ -1117,23 +1139,23 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
} else {
throwRuntimeError("commentStyle must be 'All' or 'None'");
}
std::string colonSymbol = " : ";
JSONCPP_STRING colonSymbol = " : ";
if (eyc) {
colonSymbol = ": ";
} else if (indentation.empty()) {
colonSymbol = ":";
}
std::string nullSymbol = "null";
JSONCPP_STRING nullSymbol = "null";
if (dnp) {
nullSymbol = "";
}
if (pre > 17) pre = 17;
std::string endingLineFeedSymbol = "";
JSONCPP_STRING endingLineFeedSymbol = "";
return new BuiltStyledStreamWriter(
indentation, cs,
colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
}
static void getValidWriterKeys(std::set<std::string>* valid_keys)
static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
{
valid_keys->clear();
valid_keys->insert("indentation");
@@ -1148,19 +1170,19 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const
Json::Value my_invalid;
if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
Json::Value& inv = *invalid;
std::set<std::string> valid_keys;
std::set<JSONCPP_STRING> valid_keys;
getValidWriterKeys(&valid_keys);
Value::Members keys = settings_.getMemberNames();
size_t n = keys.size();
for (size_t i = 0; i < n; ++i) {
std::string const& key = keys[i];
JSONCPP_STRING const& key = keys[i];
if (valid_keys.find(key) == valid_keys.end()) {
inv[key] = settings_[key];
}
}
return 0u == inv.size();
}
Value& StreamWriterBuilder::operator[](std::string key)
Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
{
return settings_[key];
}
@@ -1177,14 +1199,14 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
//! [StreamWriterBuilderDefaults]
}
std::string writeString(StreamWriter::Factory const& builder, Value const& root) {
std::ostringstream sout;
JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) {
JSONCPP_OSTRINGSTREAM sout;
StreamWriterPtr const writer(builder.newStreamWriter());
writer->write(root, &sout);
return sout.str();
}
std::ostream& operator<<(std::ostream& sout, Value const& root) {
JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
StreamWriterBuilder builder;
StreamWriterPtr const writer(builder.newStreamWriter());
writer->write(root, &sout);

View File

@@ -10,4 +10,11 @@
# 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
#endif
#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
#endif // JSON_VERSION_H_INCLUDED

View File

@@ -81,7 +81,7 @@ TestResult::TestResult()
predicateStackTail_ = &rootPredicateNode_;
}
void TestResult::setTestName(const std::string& name) { name_ = name; }
void TestResult::setTestName(const JSONCPP_STRING& name) { name_ = name; }
TestResult&
TestResult::addFailure(const char* file, unsigned int line, const char* expr) {
@@ -163,7 +163,7 @@ void TestResult::printFailure(bool printTestName) const {
Failures::const_iterator itEnd = failures_.end();
for (Failures::const_iterator it = failures_.begin(); it != itEnd; ++it) {
const Failure& failure = *it;
std::string indent(failure.nestingLevel_ * 2, ' ');
JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' ');
if (failure.file_) {
printf("%s%s(%d): ", indent.c_str(), failure.file_, failure.line_);
}
@@ -173,19 +173,19 @@ void TestResult::printFailure(bool printTestName) const {
printf("\n");
}
if (!failure.message_.empty()) {
std::string reindented = indentText(failure.message_, indent + " ");
JSONCPP_STRING reindented = indentText(failure.message_, indent + " ");
printf("%s\n", reindented.c_str());
}
}
}
std::string TestResult::indentText(const std::string& text,
const std::string& indent) {
std::string reindented;
std::string::size_type lastIndex = 0;
JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text,
const JSONCPP_STRING& indent) {
JSONCPP_STRING reindented;
JSONCPP_STRING::size_type lastIndex = 0;
while (lastIndex < text.size()) {
std::string::size_type nextIndex = text.find('\n', lastIndex);
if (nextIndex == std::string::npos) {
JSONCPP_STRING::size_type nextIndex = text.find('\n', lastIndex);
if (nextIndex == JSONCPP_STRING::npos) {
nextIndex = text.size() - 1;
}
reindented += indent;
@@ -195,7 +195,7 @@ std::string TestResult::indentText(const std::string& text,
return reindented;
}
TestResult& TestResult::addToLastFailure(const std::string& message) {
TestResult& TestResult::addToLastFailure(const JSONCPP_STRING& message) {
if (messageTarget_ != 0) {
messageTarget_->message_ += message;
}
@@ -240,9 +240,9 @@ unsigned int Runner::testCount() const {
return static_cast<unsigned int>(tests_.size());
}
std::string Runner::testNameAt(unsigned int index) const {
JSONCPP_STRING Runner::testNameAt(unsigned int index) const {
TestCase* test = tests_[index]();
std::string name = test->testName();
JSONCPP_STRING name = test->testName();
delete test;
return name;
}
@@ -303,7 +303,7 @@ bool Runner::runAllTest(bool printSummary) const {
}
}
bool Runner::testIndex(const std::string& testName,
bool Runner::testIndex(const JSONCPP_STRING& testName,
unsigned int& indexOut) const {
unsigned int count = testCount();
for (unsigned int index = 0; index < count; ++index) {
@@ -323,10 +323,10 @@ void Runner::listTests() const {
}
int Runner::runCommandLine(int argc, const char* argv[]) const {
// typedef std::deque<std::string> TestNames;
// typedef std::deque<JSONCPP_STRING> TestNames;
Runner subrunner;
for (int index = 1; index < argc; ++index) {
std::string opt = argv[index];
JSONCPP_STRING opt = argv[index];
if (opt == "--list-tests") {
listTests();
return 0;
@@ -426,9 +426,23 @@ void Runner::printUsage(const char* appName) {
// Assertion functions
// //////////////////////////////////////////////////////////////////
JSONCPP_STRING ToJsonString(const char* toConvert) {
return JSONCPP_STRING(toConvert);
}
JSONCPP_STRING ToJsonString(JSONCPP_STRING in) {
return in;
}
#if JSONCPP_USING_SECURE_MEMORY
JSONCPP_STRING ToJsonString(std::string in) {
return JSONCPP_STRING(in.data(), in.data() + in.length());
}
#endif
TestResult& checkStringEqual(TestResult& result,
const std::string& expected,
const std::string& actual,
const JSONCPP_STRING& expected,
const JSONCPP_STRING& actual,
const char* file,
unsigned int line,
const char* expr) {

View File

@@ -32,8 +32,8 @@ class Failure {
public:
const char* file_;
unsigned int line_;
std::string expr_;
std::string message_;
JSONCPP_STRING expr_;
JSONCPP_STRING message_;
unsigned int nestingLevel_;
};
@@ -65,7 +65,7 @@ public:
/// \internal Implementation detail for predicate macros
PredicateContext* predicateStackTail_;
void setTestName(const std::string& name);
void setTestName(const JSONCPP_STRING& name);
/// Adds an assertion failure.
TestResult&
@@ -82,7 +82,7 @@ public:
// Generic operator that will work with anything ostream can deal with.
template <typename T> TestResult& operator<<(const T& value) {
std::ostringstream oss;
JSONCPP_OSTRINGSTREAM oss;
oss.precision(16);
oss.setf(std::ios_base::floatfield);
oss << value;
@@ -96,19 +96,19 @@ public:
TestResult& operator<<(Json::UInt64 value);
private:
TestResult& addToLastFailure(const std::string& message);
TestResult& addToLastFailure(const JSONCPP_STRING& message);
unsigned int getAssertionNestingLevel() const;
/// Adds a failure or a predicate context
void addFailureInfo(const char* file,
unsigned int line,
const char* expr,
unsigned int nestingLevel);
static std::string indentText(const std::string& text,
const std::string& indent);
static JSONCPP_STRING indentText(const JSONCPP_STRING& text,
const JSONCPP_STRING& indent);
typedef std::deque<Failure> Failures;
Failures failures_;
std::string name_;
JSONCPP_STRING name_;
PredicateContext rootPredicateNode_;
PredicateContext::Id lastUsedPredicateId_;
/// Failure which is the target of the messages added using operator <<
@@ -155,7 +155,7 @@ public:
unsigned int testCount() const;
/// Returns the name of the test case at the specified index
std::string testNameAt(unsigned int index) const;
JSONCPP_STRING testNameAt(unsigned int index) const;
/// Runs the test case at the specified index using the specified TestResult
void runTestAt(unsigned int index, TestResult& result) const;
@@ -168,7 +168,7 @@ private: // prevents copy construction and assignment
private:
void listTests() const;
bool testIndex(const std::string& testName, unsigned int& index) const;
bool testIndex(const JSONCPP_STRING& testName, unsigned int& index) const;
static void preventDialogOnCrash();
private:
@@ -191,9 +191,15 @@ TestResult& checkEqual(TestResult& result,
return result;
}
JSONCPP_STRING ToJsonString(const char* toConvert);
JSONCPP_STRING ToJsonString(JSONCPP_STRING in);
#if JSONCPP_USING_SECURE_MEMORY
JSONCPP_STRING ToJsonString(std::string in);
#endif
TestResult& checkStringEqual(TestResult& result,
const std::string& expected,
const std::string& actual,
const JSONCPP_STRING& expected,
const JSONCPP_STRING& actual,
const char* file,
unsigned int line,
const char* expr);
@@ -235,8 +241,8 @@ TestResult& checkStringEqual(TestResult& result,
/// \brief Asserts that two values are equals.
#define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \
JsonTest::checkStringEqual(*result_, \
std::string(expected), \
std::string(actual), \
JsonTest::ToJsonString(expected), \
JsonTest::ToJsonString(actual), \
__FILE__, \
__LINE__, \
#expected " == " #actual)
@@ -265,8 +271,8 @@ TestResult& checkStringEqual(TestResult& result,
} \
\
public: /* overidden from TestCase */ \
virtual const char* testName() const { return #FixtureType "/" #name; } \
virtual void runTestCase(); \
const char* testName() const override { return #FixtureType "/" #name; } \
void runTestCase() override; \
}; \
\
void Test##FixtureType##name::runTestCase()

View File

@@ -8,6 +8,9 @@
#include <json/json.h>
#include <cstring>
#include <limits>
#include <sstream>
#include <string>
#include <iomanip>
// Make numeric limits more convenient to talk about.
// Assumes int type in 32 bits.
@@ -36,7 +39,7 @@ static inline double uint64ToDouble(Json::UInt64 value) {
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
static inline double uint64ToDouble(Json::UInt64 value) {
return static_cast<double>(Json::Int64(value / 2)) * 2.0 +
Json::Int64(value & 1);
static_cast<double>(Json::Int64(value & 1));
}
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
@@ -99,21 +102,21 @@ struct ValueTest : JsonTest::TestCase {
/// Normalize the representation of floating-point number by stripped leading
/// 0 in exponent.
static std::string normalizeFloatingPointStr(const std::string& s);
static JSONCPP_STRING normalizeFloatingPointStr(const JSONCPP_STRING& s);
};
std::string ValueTest::normalizeFloatingPointStr(const std::string& s) {
std::string::size_type index = s.find_last_of("eE");
if (index != std::string::npos) {
std::string::size_type hasSign =
JSONCPP_STRING ValueTest::normalizeFloatingPointStr(const JSONCPP_STRING& s) {
JSONCPP_STRING::size_type index = s.find_last_of("eE");
if (index != JSONCPP_STRING::npos) {
JSONCPP_STRING::size_type hasSign =
(s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0;
std::string::size_type exponentStartIndex = index + 1 + hasSign;
std::string normalized = s.substr(0, exponentStartIndex);
std::string::size_type indexDigit =
JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign;
JSONCPP_STRING normalized = s.substr(0, exponentStartIndex);
JSONCPP_STRING::size_type indexDigit =
s.find_first_not_of('0', exponentStartIndex);
std::string exponent = "0";
JSONCPP_STRING exponent = "0";
if (indexDigit !=
std::string::npos) // There is an exponent different from 0
JSONCPP_STRING::npos) // There is an exponent different from 0
{
exponent = s.substr(indexDigit);
}
@@ -297,10 +300,7 @@ JSONTEST_FIXTURE(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(0.0, null_.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("", null_.asString());
#if !defined(__ARMEL__)
// See line #165 of include/json/value.h
JSONTEST_ASSERT_EQUAL(Json::Value::null, null_);
#endif
}
JSONTEST_FIXTURE(ValueTest, strings) {
@@ -647,7 +647,7 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1048576",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// -2^20
val = Json::Value(-(1 << 20));
@@ -888,7 +888,7 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1099511627776",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// -2^40
val = Json::Value(-(Json::Int64(1) << 40));
@@ -963,7 +963,7 @@ JSONTEST_FIXTURE(ValueTest, integers) {
val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("9.2233720368547758e+18",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// int64 min
val = Json::Value(Json::Int64(kint64min));
@@ -1011,7 +1011,7 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-9.2233720368547758e+18",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// 10^19
const Json::UInt64 ten_to_19 = static_cast<Json::UInt64>(1e19);
@@ -1058,7 +1058,7 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(1e19, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1e+19",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// uint64 max
val = Json::Value(Json::UInt64(kuint64max));
@@ -1102,7 +1102,7 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1.8446744073709552e+19",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
#endif
}
@@ -1192,7 +1192,7 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) {
#endif
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("2147483647.5",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A bit under int32 min
val = Json::Value(kint32min - 0.5);
@@ -1220,7 +1220,7 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) {
#endif
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("-2147483648.5",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A bit over uint32 max
val = Json::Value(kuint32max + 0.5);
@@ -1250,29 +1250,29 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) {
#endif
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("4294967295.5",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
val = Json::Value(1.2345678901234);
JSONTEST_ASSERT_STRING_EQUAL("1.2345678901234001",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A 16-digit floating point number.
val = Json::Value(2199023255552000.0f);
JSONTEST_ASSERT_EQUAL(float(2199023255552000.0f), val.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("2199023255552000",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A very large floating point number.
val = Json::Value(3.402823466385289e38);
JSONTEST_ASSERT_EQUAL(float(3.402823466385289e38), val.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("3.402823466385289e+38",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// An even larger floating point number.
val = Json::Value(1.2345678e300);
JSONTEST_ASSERT_EQUAL(double(1.2345678e300), val.asDouble());
JSONTEST_ASSERT_STRING_EQUAL("1.2345678e+300",
normalizeFloatingPointStr(val.asString()));
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
}
void ValueTest::checkConstMemberCount(const Json::Value& value,
@@ -1516,10 +1516,29 @@ JSONTEST_FIXTURE(ValueTest, typeChecksThrowExceptions) {
#endif
}
JSONTEST_FIXTURE(ValueTest, offsetAccessors) {
Json::Value x;
JSONTEST_ASSERT(x.getOffsetStart() == 0);
JSONTEST_ASSERT(x.getOffsetLimit() == 0);
x.setOffsetStart(10);
x.setOffsetLimit(20);
JSONTEST_ASSERT(x.getOffsetStart() == 10);
JSONTEST_ASSERT(x.getOffsetLimit() == 20);
Json::Value y(x);
JSONTEST_ASSERT(y.getOffsetStart() == 10);
JSONTEST_ASSERT(y.getOffsetLimit() == 20);
Json::Value z;
z.swap(y);
JSONTEST_ASSERT(z.getOffsetStart() == 10);
JSONTEST_ASSERT(z.getOffsetLimit() == 20);
JSONTEST_ASSERT(y.getOffsetStart() == 0);
JSONTEST_ASSERT(y.getOffsetLimit() == 0);
}
JSONTEST_FIXTURE(ValueTest, StaticString) {
char mutant[] = "hello";
Json::StaticString ss(mutant);
std::string regular(mutant);
JSONCPP_STRING regular(mutant);
mutant[1] = 'a';
JSONTEST_ASSERT_STRING_EQUAL("hallo", ss.c_str());
JSONTEST_ASSERT_STRING_EQUAL("hello", regular.c_str());
@@ -1541,15 +1560,15 @@ JSONTEST_FIXTURE(ValueTest, StaticString) {
JSONTEST_FIXTURE(ValueTest, CommentBefore) {
Json::Value val; // fill val
val.setComment(std::string("// this comment should appear before"), Json::commentBefore);
val.setComment(JSONCPP_STRING("// this comment should appear before"), Json::commentBefore);
Json::StreamWriterBuilder wbuilder;
wbuilder.settings_["commentStyle"] = "All";
{
char const expected[] = "// this comment should appear before\nnull";
std::string result = Json::writeString(wbuilder, val);
JSONCPP_STRING result = Json::writeString(wbuilder, val);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
std::string res2 = val.toStyledString();
std::string exp2 = "\n";
JSONCPP_STRING res2 = val.toStyledString();
JSONCPP_STRING exp2 = "\n";
exp2 += expected;
exp2 += "\n";
JSONTEST_ASSERT_STRING_EQUAL(exp2, res2);
@@ -1558,10 +1577,10 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) {
val.swapPayload(other);
{
char const expected[] = "// this comment should appear before\n\"hello\"";
std::string result = Json::writeString(wbuilder, val);
JSONCPP_STRING result = Json::writeString(wbuilder, val);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
std::string res2 = val.toStyledString();
std::string exp2 = "\n";
JSONCPP_STRING res2 = val.toStyledString();
JSONCPP_STRING exp2 = "\n";
exp2 += expected;
exp2 += "\n";
JSONTEST_ASSERT_STRING_EQUAL(exp2, res2);
@@ -1572,10 +1591,10 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) {
// Assignment over-writes comments.
{
char const expected[] = "\"hello\"";
std::string result = Json::writeString(wbuilder, val);
JSONCPP_STRING result = Json::writeString(wbuilder, val);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
std::string res2 = val.toStyledString();
std::string exp2 = "";
JSONCPP_STRING res2 = val.toStyledString();
JSONCPP_STRING exp2 = "";
exp2 += expected;
exp2 += "\n";
JSONTEST_ASSERT_STRING_EQUAL(exp2, res2);
@@ -1584,7 +1603,7 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) {
JSONTEST_FIXTURE(ValueTest, zeroes) {
char const cstr[] = "h\0i";
std::string binary(cstr, sizeof(cstr)); // include trailing 0
JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0
JSONTEST_ASSERT_EQUAL(4U, binary.length());
Json::StreamWriterBuilder b;
{
@@ -1612,7 +1631,7 @@ JSONTEST_FIXTURE(ValueTest, zeroes) {
JSONTEST_FIXTURE(ValueTest, zeroesInKeys) {
char const cstr[] = "h\0i";
std::string binary(cstr, sizeof(cstr)); // include trailing 0
JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0
JSONTEST_ASSERT_EQUAL(4U, binary.length());
{
Json::Value root;
@@ -1641,8 +1660,8 @@ JSONTEST_FIXTURE(ValueTest, specialFloats) {
b.settings_["useSpecialFloats"] = true;
Json::Value v = std::numeric_limits<double>::quiet_NaN();
std::string expected = "NaN";
std::string result = Json::writeString(b, v);
JSONCPP_STRING expected = "NaN";
JSONCPP_STRING result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
v = std::numeric_limits<double>::infinity();
@@ -1661,10 +1680,10 @@ JSONTEST_FIXTURE(ValueTest, precision) {
b.settings_["precision"] = 5;
Json::Value v = 100.0/3;
std::string expected = "33.333";
std::string result = Json::writeString(b, v);
JSONCPP_STRING expected = "33.333";
JSONCPP_STRING result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
v = 0.25000000;
expected = "0.25";
result = Json::writeString(b, v);
@@ -1693,6 +1712,17 @@ JSONTEST_FIXTURE(ValueTest, precision) {
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
}
struct WriterTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) {
Json::FastWriter writer;
Json::Value nullValue;
JSONTEST_ASSERT(writer.write(nullValue) == "null\n");
writer.dropNullPlaceholders();
JSONTEST_ASSERT(writer.write(nullValue) == "\n");
}
struct StreamWriterTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) {
@@ -1705,15 +1735,15 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) {
}
JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) {
std::string binary("hi", 3); // include trailing 0
JSONCPP_STRING binary("hi", 3); // include trailing 0
JSONTEST_ASSERT_EQUAL(3, binary.length());
std::string expected("\"hi\\u0000\""); // unicoded zero
JSONCPP_STRING expected("\"hi\\u0000\""); // unicoded zero
Json::StreamWriterBuilder b;
{
Json::Value root;
root = binary;
JSONTEST_ASSERT_STRING_EQUAL(binary, root.asString());
std::string out = Json::writeString(b, root);
JSONCPP_STRING out = Json::writeString(b, root);
JSONTEST_ASSERT_EQUAL(expected.size(), out.size());
JSONTEST_ASSERT_STRING_EQUAL(expected, out);
}
@@ -1721,7 +1751,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) {
Json::Value root;
root["top"] = binary;
JSONTEST_ASSERT_STRING_EQUAL(binary, root["top"].asString());
std::string out = Json::writeString(b, root["top"]);
JSONCPP_STRING out = Json::writeString(b, root["top"]);
JSONTEST_ASSERT_STRING_EQUAL(expected, out);
}
}
@@ -1734,6 +1764,7 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) {
bool ok = reader.parse("{ \"property\" : \"value\" }", root);
JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0);
}
JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
@@ -1745,6 +1776,25 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
root);
JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0);
JSONTEST_ASSERT(root["property"].getOffsetStart() == 15);
JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34);
JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16);
JSONTEST_ASSERT(root["property"][0].getOffsetLimit() == 23);
JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25);
JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33);
JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44);
JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 76);
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57);
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 60);
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 71);
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 75);
JSONTEST_ASSERT(root["null"].getOffsetStart() == 87);
JSONTEST_ASSERT(root["null"].getOffsetLimit() == 91);
JSONTEST_ASSERT(root["false"].getOffsetStart() == 103);
JSONTEST_ASSERT(root["false"].getOffsetLimit() == 108);
JSONTEST_ASSERT(root.getOffsetStart() == 0);
JSONTEST_ASSERT(root.getOffsetLimit() == 110);
}
JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
@@ -1755,6 +1805,13 @@ JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
"* Line 1, Column 15\n Syntax error: value, object or array "
"expected.\n");
std::vector<Json::Reader::StructuredError> errors =
reader.getStructuredErrors();
JSONTEST_ASSERT(errors.size() == 1);
JSONTEST_ASSERT(errors.at(0).offset_start == 14);
JSONTEST_ASSERT(errors.at(0).offset_limit == 15);
JSONTEST_ASSERT(errors.at(0).message ==
"Syntax error: value, object or array expected.");
}
JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
@@ -1765,6 +1822,13 @@ JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
"* Line 1, Column 19\n Syntax error: value, object or array "
"expected.\n");
std::vector<Json::Reader::StructuredError> errors =
reader.getStructuredErrors();
JSONTEST_ASSERT(errors.size() == 1);
JSONTEST_ASSERT(errors.at(0).offset_start == 18);
JSONTEST_ASSERT(errors.at(0).offset_limit == 19);
JSONTEST_ASSERT(errors.at(0).message ==
"Syntax error: value, object or array expected.");
}
JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
@@ -1775,6 +1839,12 @@ JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
"* Line 1, Column 16\n Bad escape sequence in string\nSee "
"Line 1, Column 20 for detail.\n");
std::vector<Json::Reader::StructuredError> errors =
reader.getStructuredErrors();
JSONTEST_ASSERT(errors.size() == 1);
JSONTEST_ASSERT(errors.at(0).offset_start == 15);
JSONTEST_ASSERT(errors.at(0).offset_limit == 23);
JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string");
}
struct CharReaderTest : JsonTest::TestCase {};
@@ -1782,7 +1852,7 @@ struct CharReaderTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) {
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
Json::Value root;
char const doc[] = "{ \"property\" : \"value\" }";
bool ok = reader->parse(
@@ -1796,7 +1866,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) {
JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) {
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
Json::Value root;
char const doc[] =
"{ \"property\" : [\"value\", \"value2\"], \"obj\" : "
@@ -1813,7 +1883,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) {
JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) {
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
Json::Value root;
char const doc[] =
"{ \"property\" :: \"value\" }";
@@ -1830,7 +1900,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) {
JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) {
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
Json::Value root;
char const doc[] =
"{ \"pr佐藤erty\" :: \"value\" }";
@@ -1847,7 +1917,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) {
JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) {
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
Json::Value root;
char const doc[] =
"{ \"property\" : \"v\\alue\" }";
@@ -1869,7 +1939,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) {
{
b.settings_["stackLimit"] = 2;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -1881,7 +1951,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) {
{
b.settings_["stackLimit"] = 1;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
JSONTEST_ASSERT_THROWS(reader->parse(
doc, doc + std::strlen(doc),
&root, &errs));
@@ -1899,7 +1969,7 @@ JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) {
{
b.strictMode(&b.settings_);
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -1923,7 +1993,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) {
{
b.settings_["failIfExtra"] = false;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -1935,7 +2005,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) {
{
b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -1950,7 +2020,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) {
b.settings_["failIfExtra"] = false;
b.strictMode(&b.settings_);
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -1970,7 +2040,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) {
"1:2:3";
b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -1990,7 +2060,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) {
"{ \"property\" : \"value\" } //trailing\n//comment\n";
b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -2007,7 +2077,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) {
"[ \"property\" , \"value\" ] //trailing\n//comment\n";
b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -2023,7 +2093,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) {
" true /*trailing\ncomment*/";
b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader());
std::string errs;
JSONCPP_STRING errs;
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
@@ -2038,7 +2108,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
Json::CharReaderBuilder b;
b.settings_["allowDroppedNullPlaceholders"] = true;
Json::Value root;
std::string errs;
JSONCPP_STRING errs;
Json::CharReader* reader(b.newCharReader());
{
char const doc[] = "{\"a\":,\"b\":true}";
@@ -2190,7 +2260,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) {
Json::CharReaderBuilder b;
b.settings_["allowSingleQuotes"] = true;
Json::Value root;
std::string errs;
JSONCPP_STRING errs;
Json::CharReader* reader(b.newCharReader());
{
char const doc[] = "{'a':true,\"b\":true}";
@@ -2223,7 +2293,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) {
Json::CharReaderBuilder b;
b.settings_["allowSingleQuotes"] = true;
Json::Value root;
std::string errs;
JSONCPP_STRING errs;
Json::CharReader* reader(b.newCharReader());
{
char const doc[] = "{'a':true,\"b\":true}";
@@ -2256,7 +2326,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) {
Json::CharReaderBuilder b;
b.settings_["allowSpecialFloats"] = true;
Json::Value root;
std::string errs;
JSONCPP_STRING errs;
Json::CharReader* reader(b.newCharReader());
{
char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}";
@@ -2275,7 +2345,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) {
struct TestData {
int line;
bool ok;
std::string in;
JSONCPP_STRING in;
};
const TestData test_data[] = {
{__LINE__, 1, "{\"a\":9}"},
@@ -2355,7 +2425,7 @@ JSONTEST_FIXTURE(IteratorTest, distance) {
json["k1"] = "a";
json["k2"] = "b";
int dist = 0;
std::string str;
JSONCPP_STRING str;
for (Json::ValueIterator it = json.begin(); it != json.end(); ++it) {
dist = it - json.begin();
str = it->asString().c_str();
@@ -2400,6 +2470,46 @@ JSONTEST_FIXTURE(IteratorTest, indexes) {
JSONTEST_ASSERT(it == json.end());
}
JSONTEST_FIXTURE(IteratorTest, const) {
Json::Value const v;
JSONTEST_ASSERT_THROWS(
Json::Value::iterator it(v.begin()) // Compile, but throw.
);
Json::Value value;
for(int i = 9; i < 12; ++i)
{
JSONCPP_OSTRINGSTREAM out;
out << std::setw(2) << i;
JSONCPP_STRING str = out.str();
value[str] = str;
}
JSONCPP_OSTRINGSTREAM out;
//in old code, this will get a compile error
Json::Value::const_iterator iter = value.begin();
for(; iter != value.end(); ++iter)
{
out << *iter << ',';
}
JSONCPP_STRING expected = "\" 9\",\"10\",\"11\",";
JSONTEST_ASSERT_STRING_EQUAL(expected, out.str());
}
struct RValueTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(RValueTest, moveConstruction) {
#if JSON_HAS_RVALUE_REFERENCES
Json::Value json;
json["key"] = "value";
Json::Value moved = std::move(json);
JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not equal.
JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type());
JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type());
#endif
}
int main(int argc, const char* argv[]) {
JsonTest::Runner runner;
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
@@ -2421,6 +2531,7 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore);
@@ -2430,6 +2541,7 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, precision);
JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders);
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders);
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes);
@@ -2469,6 +2581,9 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, names);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, const);
JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction);
return runner.runCommandLine(argc, argv);
}

View File

@@ -19,6 +19,8 @@ env | sort
cmake -DJSONCPP_WITH_CMAKE_PACKAGE=$CMAKE_PKG -DBUILD_SHARED_LIBS=$SHARED_LIB -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_MAKE .
make
cmake -DJSONCPP_WITH_CMAKE_PACKAGE=$CMAKE_PKG -DBUILD_SHARED_LIBS=$SHARED_LIB -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_MAKE -DJSONCPP_USE_SECURE_MEMORY=1 .
make
# Python is not available in Travis for osx.
# https://github.com/travis-ci/travis-ci/issues/2320

View File

@@ -1 +1 @@
0.10.7
1.7.0