Compare commits

..

15 Commits

Author SHA1 Message Date
Baptiste Lepilleur
710c73a950 Release 0.5.0 2010-03-12 07:31:04 +00:00
Baptiste Lepilleur
66464f2c62 Release 0.5.0 2010-03-11 21:09:07 +00:00
Baptiste Lepilleur
d0e9ec5d54 Release 0.5.0 2010-02-25 07:55:28 +00:00
Baptiste Lepilleur
d90fc720ef Release 0.5.0 2010-02-25 07:51:43 +00:00
Baptiste Lepilleur
97af24d2f8 Release 0.5.0 2010-02-24 22:46:35 +00:00
Baptiste Lepilleur
3a75efb375 Release 0.5.0 2010-02-24 22:41:18 +00:00
Baptiste Lepilleur
da6ccbbcfb Release 0.5.0 2010-02-24 22:37:29 +00:00
Baptiste Lepilleur
50c383ba01 Release 0.5.0 2010-02-24 22:34:06 +00:00
Baptiste Lepilleur
df75e4aa84 Release 0.5.0 2010-02-24 20:45:50 +00:00
Baptiste Lepilleur
2279ce36c4 Release 0.5.0 2010-02-24 07:36:38 +00:00
Baptiste Lepilleur
64cc86bf5f Release 0.5.0 2010-02-23 20:41:23 +00:00
Baptiste Lepilleur
6283d0c7c1 Release 0.5.0 2010-02-23 07:51:07 +00:00
Baptiste Lepilleur
c45da10999 Release 0.5.0 2010-02-23 07:43:10 +00:00
Baptiste Lepilleur
9597adfcd0 Release 0.5.0 2010-02-23 03:28:23 +00:00
Baptiste Lepilleur
d07ebe671a Release 0.5.0 2010-02-23 03:23:09 +00:00
42 changed files with 343 additions and 1306 deletions

56
LICENSE
View File

@@ -1,55 +1 @@
The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
The author (Baptiste Lepilleur) explicitly disclaims copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the
conditions of the MIT License (see below), or 3) under the terms of dual
Public Domain/MIT License conditions described here, as they choose.
The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:
http://en.wikipedia.org/wiki/MIT_License
The full text of the MIT License follows:
========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
========================================================================
(END LICENSE TEXT)
The MIT license is compatible with both the GPL and commercial
software, affording one all of the rights of Public Domain with the
minor nuisance of being required to keep the above copyright notice
and license text in the source code. Note also that by accepting the
Public Domain "license" you can re-license your copy using whatever
license you like.
The json-cpp library and this documentation are in Public Domain.

View File

@@ -1,95 +0,0 @@
New in JsonCpp 0.6.0:
---------------------
* Compilation
- LD_LIBRARY_PATH and LIBRARY_PATH environment variables are now
propagated to the build environment as this is required for some
compiler installation.
- Added support for Microsoft Visual Studio 2008 (bug #2930462):
The platform "msvc90" has been added.
Notes: you need to setup the environment by running vcvars32.bat
(e.g. MSVC 2008 command prompt in start menu) before running scons.
- Added support for amalgated source and header generation (a la sqlite).
Refer to README.txt section "Generating amalgated source and header"
for detail.
* Value
- Removed experimental ValueAllocator, it caused static
initialization/destruction order issues (bug #2934500).
The DefaultValueAllocator has been inlined in code.
- Added support for 64 bits integer:
Types Json::Int64 and Json::UInt64 have been added. They are aliased
to 64 bits integers on system that support them (based on __int64 on
Microsoft Visual Studio platform, and long long on other platforms).
Types Json::LargestInt and Json::LargestUInt have been added. They are
aliased to the largest integer type supported:
either Json::Int/Json::UInt or Json::Int64/Json::UInt64 respectively.
Json::Value::asInt() and Json::Value::asUInt() still returns plain
"int" based types, but asserts if an attempt is made to retrieve
a 64 bits value that can not represented as the return type.
Json::Value::asInt64() and Json::Value::asUInt64() have been added
to obtain the 64 bits integer value.
Json::Value::asLargestInt() and Json::Value::asLargestUInt() returns
the integer as a LargestInt/LargestUInt respectively. Those functions
functions are typically used when implementing writer.
The reader attempts to read number as 64 bits integer, and fall back
to reading a double if the number is not in the range of 64 bits
integer.
Warning: Json::Value::asInt() and Json::Value::asUInt() now returns
long long. This changes break code that was passing the return value
to *printf() function.
Support for 64 bits integer can be disabled by defining the macro
JSON_NO_INT64 (uncomment it in json/config.h for example), though
it should have no impact on existing usage.
- The type Json::ArrayIndex is used for indexes of a JSON value array. It
is an unsigned int (typically 32 bits).
- Array index can be passed as int to operator[], allowing use of literal:
Json::Value array;
array.append( 1234 );
int value = array[0].asInt(); // did not compile previously
- Added float Json::Value::asFloat() to obtain a floating point value as a
float (avoid lost of precision warning caused by used of asDouble()
to initialize a float).
* Reader
- Renamed Reader::getFormatedErrorMessages() to getFormattedErrorMessages.
Bug #3023708 (Formatted has 2 't'). The old member function is deprecated
but still present for backward compatibility.
* Tests
- Added test to ensure that the escape sequence "\/" is corrected handled
by the parser.
* Bug fixes
- Bug #3139677: JSON [1 2 3] was incorrectly parsed as [1, 3]. Error is now
correctly detected.
- Bug #3139678: stack buffer overflow when parsing a double with a
length of 32 characters.
* License
- See file LICENSE for details. Basically JsonCpp is now licensed under
MIT license, or public domain if desired and recognized in your jurisdiction.
Thanks to Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) who
helped figuring out the solution to the public domain issue.

View File

@@ -5,8 +5,8 @@ JSON (JavaScript Object Notation) is a lightweight data-interchange format.
It can represent integer, real number, string, an ordered sequence of
value, and a collection of name/value pairs.
JsonCpp (http://jsoncpp.sourceforge.net/) is a simple API to manipulate
JSON value, handle serialization and unserialization to string.
JsonCpp is a simple API to manipulate JSON value, handle serialization
and unserialization to string.
It can also preserve existing comment in unserialization/serialization steps,
making it a convenient format to store user input files.
@@ -21,7 +21,7 @@ JsonCpp uses Scons (http://www.scons.org) as a build system. Scons requires
python to be installed (http://www.python.org).
You download scons-local distribution from the following url:
http://sourceforge.net/projects/scons/files/scons-local/1.2.0/
http://sourceforge.net/project/showfiles.php?group_id=30337&package_id=67375
Unzip it in the directory where you found this README file. scons.py Should be
at the same level as README.
@@ -35,14 +35,9 @@ where PLTFRM may be one of:
msvc70 Microsoft Visual Studio 2002
msvc71 Microsoft Visual Studio 2003
msvc80 Microsoft Visual Studio 2005
msvc90 Microsoft Visual Studio 2008
linux-gcc Gnu C++ (linux, also reported to work for Mac OS X)
Notes: if you are building with Microsoft Visual Studio 2008, you need to
setup the environment by running vcvars32.bat (e.g. MSVC 2008 command prompt)
before running scons.
Adding platform is fairly simple. You need to change the Sconstruct file
adding platform is fairly simple. You need to change the Sconstruct file
to do so.
and TARGET may be:
@@ -52,13 +47,6 @@ and TARGET may be:
* Running the test manually:
==========================
Notes that test can be run by scons using the 'check' target (see above).
You need to run test manually only if you are troubleshooting an issue.
In the instruction below, replace "path to jsontest.exe" with the path
of the 'jsontest' executable that was compiled on your platform.
cd test
# This will run the Reader/Writer tests
python runjsontests.py "path to jsontest.exe"
@@ -86,43 +74,6 @@ python doxybuild.py --open --with-dot
See doxybuild.py --help for options.
Notes that the documentation is also available for download as a tarball.
The documentation of the latest release is available online at:
http://jsoncpp.sourceforge.net/
* Generating amalgated source and header
======================================
JsonCpp is provided with a script to generate a single header and a single
source file to ease inclusion in an existing project.
The amalgated source can be generated at any time by running the following
command from the top-directory (requires python 2.6):
python amalgate.py
It is possible to specify header name. See -h options for detail. By default,
the following files are generated:
- dist/jsoncpp.cpp: source file that need to be added to your project
- dist/json/json.h: header file corresponding to use in your project. It is
equivalent to including json/json.h in non-amalgated source. This header
only depends on standard headers.
- dist/json/json-forwards.h: header the provides forward declaration
of all JsonCpp types. This typically what should be included in headers to
speed-up compilation.
The amalgated sources are generated by concatenating JsonCpp source in the
correct order and defining macro JSON_IS_AMALGATED to prevent inclusion of
other headers.
* Using json-cpp in your project:
===============================
include/ should be added to your compiler include path. jsoncpp headers
should be included as follow:
#include <json/json.h>
* Adding a reader/writer test:
============================
@@ -164,9 +115,3 @@ Below is a short description of the content of each file:
jsontest.exe from reading test_complex_01.rewrite.
test_complex_01.process-output: jsontest.exe output, typically useful to
understand parsing error.
* License
=======
See file LICENSE for details. Basically JsonCpp is licensed under
MIT license, or public domain if desired and recognized in your jurisdiction.

View File

@@ -18,7 +18,7 @@ options = Variables()
options.Add( EnumVariable('platform',
'Platform (compiler/stl) used to build the project',
'msvc71',
allowed_values='suncc vacpp mingw msvc6 msvc7 msvc71 msvc80 msvc90 linux-gcc'.split(),
allowed_values='suncc vacpp mingw msvc6 msvc7 msvc71 msvc80 linux-gcc'.split(),
ignorecase=2) )
try:
@@ -57,9 +57,8 @@ def make_environ_vars():
"""Returns a dictionnary with environment variable to use when compiling."""
# PATH is required to find the compiler
# TEMP is required for at least mingw
# LD_LIBRARY_PATH & co is required on some system for the compiler
vars = {}
for name in ('PATH', 'TEMP', 'TMP', 'LD_LIBRARY_PATH', 'LIBRARY_PATH'):
for name in ('PATH', 'TEMP', 'TMP'):
if name in os.environ:
vars[name] = os.environ[name]
return vars
@@ -102,18 +101,6 @@ elif platform == 'msvc80':
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -EHsc /nologo /MT'
elif platform == 'msvc90':
env['MSVS_VERSION']='9.0'
# Scons 1.2 fails to detect the correct location of the platform SDK.
# So we propagate those from the environment. This requires that the
# user run vcvars32.bat before compiling.
if 'INCLUDE' in os.environ:
env['ENV']['INCLUDE'] = os.environ['INCLUDE']
if 'LIB' in os.environ:
env['ENV']['LIB'] = os.environ['LIB']
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -EHsc /nologo /MT'
elif platform == 'mingw':
env.Tool( 'mingw' )
env.Append( CPPDEFINES=[ "WIN32", "NDEBUG", "_MT" ] )

View File

@@ -1,147 +0,0 @@
"""Amalgate json-cpp library sources into a single source and header file.
Requires Python 2.6
Example of invocation (must be invoked from json-cpp top directory):
python amalgate.py
"""
import os
import os.path
import sys
class AmalagatedFile:
def __init__( self, top_dir ):
self.top_dir = top_dir
self.blocks = []
def add_text( self, text ):
if not text.endswith( '\n' ):
text += '\n'
self.blocks.append( text )
def add_file( self, relative_input_path, wrap_in_comment=False ):
def add_marker( prefix ):
self.add_text( '' )
self.add_text( '// ' + '/'*70 )
self.add_text( '// %s of content of file: %s' % (prefix, relative_input_path.replace('\\','/')) )
self.add_text( '// ' + '/'*70 )
self.add_text( '' )
add_marker( 'Beginning' )
f = open( os.path.join( self.top_dir, relative_input_path ), 'rt' )
content = f.read()
if wrap_in_comment:
content = '/*\n' + content + '\n*/'
self.add_text( content )
f.close()
add_marker( 'End' )
self.add_text( '\n\n\n\n' )
def get_value( self ):
return ''.join( self.blocks ).replace('\r\n','\n')
def write_to( self, output_path ):
output_dir = os.path.dirname( output_path )
if output_dir and not os.path.isdir( output_dir ):
os.makedirs( output_dir )
f = open( output_path, 'wb' )
f.write( self.get_value() )
f.close()
def amalgate_source( source_top_dir=None,
target_source_path=None,
header_include_path=None ):
"""Produces amalgated source.
Parameters:
source_top_dir: top-directory
target_source_path: output .cpp path
header_include_path: generated header path relative to target_source_path.
"""
print 'Amalgating header...'
header = AmalagatedFile( source_top_dir )
header.add_text( '/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).' )
header.add_text( '/// It is intented to be used with #include <%s>' % header_include_path )
header.add_file( 'LICENSE', wrap_in_comment=True )
header.add_text( '#ifndef JSON_AMALGATED_H_INCLUDED' )
header.add_text( '# define JSON_AMALGATED_H_INCLUDED' )
header.add_text( '/// If defined, indicates that the source file is amalgated' )
header.add_text( '/// to prevent private header inclusion.' )
header.add_text( '#define JSON_IS_AMALGATED' )
header.add_file( 'include/json/config.h' )
header.add_file( 'include/json/forwards.h' )
header.add_file( 'include/json/features.h' )
header.add_file( 'include/json/value.h' )
header.add_file( 'include/json/reader.h' )
header.add_file( 'include/json/writer.h' )
header.add_text( '#endif //ifndef JSON_AMALGATED_H_INCLUDED' )
target_header_path = os.path.join( os.path.dirname(target_source_path), header_include_path )
print 'Writing amalgated header to %r' % target_header_path
header.write_to( target_header_path )
base, ext = os.path.splitext( header_include_path )
forward_header_include_path = base + '-forwards' + ext
print 'Amalgating forward header...'
header = AmalagatedFile( source_top_dir )
header.add_text( '/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).' )
header.add_text( '/// It is intented to be used with #include <%s>' % forward_header_include_path )
header.add_text( '/// This header provides forward declaration for all JsonCpp types.' )
header.add_file( 'LICENSE', wrap_in_comment=True )
header.add_text( '#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED' )
header.add_text( '# define JSON_FORWARD_AMALGATED_H_INCLUDED' )
header.add_text( '/// If defined, indicates that the source file is amalgated' )
header.add_text( '/// to prevent private header inclusion.' )
header.add_text( '#define JSON_IS_AMALGATED' )
header.add_file( 'include/json/config.h' )
header.add_file( 'include/json/forwards.h' )
header.add_text( '#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED' )
target_forward_header_path = os.path.join( os.path.dirname(target_source_path),
forward_header_include_path )
print 'Writing amalgated forward header to %r' % target_forward_header_path
header.write_to( target_forward_header_path )
print 'Amalgating source...'
source = AmalagatedFile( source_top_dir )
source.add_text( '/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).' )
source.add_text( '/// It is intented to be used with #include <%s>' % header_include_path )
source.add_file( 'LICENSE', wrap_in_comment=True )
source.add_text( '' )
source.add_text( '#include <%s>' % header_include_path )
source.add_text( '' )
source.add_file( 'src/lib_json\json_tool.h' )
source.add_file( 'src/lib_json\json_reader.cpp' )
source.add_file( 'src/lib_json\json_batchallocator.h' )
source.add_file( 'src/lib_json\json_valueiterator.inl' )
source.add_file( 'src/lib_json\json_value.cpp' )
source.add_file( 'src/lib_json\json_writer.cpp' )
print 'Writing amalgated source to %r' % target_source_path
source.write_to( target_source_path )
def main():
usage = """%prog [options]
Generate a single amalgated source and header file from the sources.
"""
from optparse import OptionParser
parser = OptionParser(usage=usage)
parser.allow_interspersed_args = False
parser.add_option('-s', '--source', dest="target_source_path", action='store', default='dist/jsoncpp.cpp',
help="""Output .cpp source path. [Default: %default]""")
parser.add_option('-i', '--include', dest="header_include_path", action='store', default='json/json.h',
help="""Header include path. Used to include the header from the amalgated source file. [Default: %default]""")
parser.add_option('-t', '--top-dir', dest="top_dir", action='store', default=os.getcwd(),
help="""Source top-directory. [Default: %default]""")
parser.enable_interspersed_args()
options, args = parser.parse_args()
msg = amalgate_source( source_top_dir=options.top_dir,
target_source_path=options.target_source_path,
header_include_path=options.header_include_path )
if msg:
sys.stderr.write( msg + '\n' )
sys.exit( 1 )
else:
print 'Source succesfully amalagated'
if __name__ == '__main__':
main()

View File

@@ -1,93 +0,0 @@
"""Updates the license text in source file.
"""
# An existing license is found if the file starts with the string below,
# and ends with the first blank line.
LICENSE_BEGIN = "// Copyright "
BRIEF_LICENSE = LICENSE_BEGIN + """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
""".replace('\r\n','\n')
def update_license( path, dry_run, show_diff ):
"""Update the license statement in the specified file.
Parameters:
path: path of the C++ source file to update.
dry_run: if True, just print the path of the file that would be updated,
but don't change it.
show_diff: if True, print the path of the file that would be modified,
as well as the change made to the file.
"""
with open( path, 'rt' ) as fin:
original_text = fin.read().replace('\r\n','\n')
newline = fin.newlines and fin.newlines[0] or '\n'
if not original_text.startswith( LICENSE_BEGIN ):
# No existing license found => prepend it
new_text = BRIEF_LICENSE + original_text
else:
license_end_index = original_text.index( '\n\n' ) # search first blank line
new_text = BRIEF_LICENSE + original_text[license_end_index+2:]
if original_text != new_text:
if not dry_run:
with open( path, 'wb' ) as fout:
fout.write( new_text.replace('\n', newline ) )
print 'Updated', path
if show_diff:
import difflib
print '\n'.join( difflib.unified_diff( original_text.split('\n'),
new_text.split('\n') ) )
return True
return False
def update_license_in_source_directories( source_dirs, dry_run, show_diff ):
"""Updates license text in C++ source files found in directory source_dirs.
Parameters:
source_dirs: list of directory to scan for C++ sources. Directories are
scanned recursively.
dry_run: if True, just print the path of the file that would be updated,
but don't change it.
show_diff: if True, print the path of the file that would be modified,
as well as the change made to the file.
"""
from devtools import antglob
prune_dirs = antglob.prune_dirs + 'scons-local* ./build* ./libs ./dist'
for source_dir in source_dirs:
cpp_sources = antglob.glob( source_dir,
includes = '''**/*.h **/*.cpp **/*.inl''',
prune_dirs = prune_dirs )
for source in cpp_sources:
update_license( source, dry_run, show_diff )
def main():
usage = """%prog DIR [DIR2...]
Updates license text in sources of the project in source files found
in the directory specified on the command-line.
Example of call:
python devtools\licenseupdater.py include src -n --diff
=> Show change that would be made to the sources.
python devtools\licenseupdater.py include src
=> Update license statement on all sources in directories include/ and src/.
"""
from optparse import OptionParser
parser = OptionParser(usage=usage)
parser.allow_interspersed_args = False
parser.add_option('-n', '--dry-run', dest="dry_run", action='store_true', default=False,
help="""Only show what files are updated, do not update the files""")
parser.add_option('--diff', dest="show_diff", action='store_true', default=False,
help="""On update, show change made to the file.""")
parser.enable_interspersed_args()
options, args = parser.parse_args()
update_license_in_source_directories( args, options.dry_run, options.show_diff )
print 'Done'
if __name__ == '__main__':
import sys
import os.path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
main()

View File

@@ -11,7 +11,7 @@ JsonCpp - JSON data format manipulation library
<table width="100%">
<tr>
<td width="40%" align="left" valign="center">
<a href="http://sourceforge.net/projects/jsoncpp/">
<a href="http://sourceforge.net/projects/jsoncpp">
JsonCpp project page
</a>
</td>

View File

@@ -22,7 +22,7 @@ Here is an example of JSON data:
],
// Tab indent size
"indent" : { "length" : 3, "use_space": true }
"indent" : { "length" : 3, "use_space" = true }
}
\endverbatim
@@ -46,7 +46,7 @@ if ( !parsingSuccessful )
{
// report to the user the failure and their locations in the document.
std::cout << "Failed to parse configuration\n"
<< reader.getFormattedErrorMessages();
<< reader.getFormatedErrorMessages();
return;
}
@@ -82,12 +82,12 @@ std::cin >> root["subtree"];
std::cout << root;
\endcode
\section _pbuild Build instructions
\section _plinks Build instructions
The build instructions are located in the file
<a HREF="README.txt">README.txt</a> in the top-directory of the project.
Permanent link to the latest revision of the file in subversion:
<a HREF="http://jsoncpp.svn.sourceforge.net/viewvc/jsoncpp/trunk/jsoncpp/README.txt?view=markup">latest README.txt</a>
<a HREF="http://svn.sourceforge.net/viewcvs.cgi/jsoncpp/README.txt?view=markup">latest README.txt</a>
\section _pdownload Download
The sources can be downloaded from
@@ -100,16 +100,9 @@ http://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/trunk/</a>
To checkout the source, see the following
<a HREF="http://sourceforge.net/scm/?type=svn&group_id=144446">instructions</a>.
\section _news What's New?
The description of latest changes can be found in
<a HREF="NEWS.txt">NEWS.txt</a> in the top-directory of the project.
Permanent link to the latest revision of the file in subversion:
<a HREF="http://svn.sourceforge.net/viewcvs.cgi/jsoncpp/README.txt?view=markup">latest NEWS.txt</a>
\section _plinks Project links
- <a HREF="http://jsoncpp.sourceforge.net">json-cpp home</a>
- <a HREF="http://www.sourceforge.net/projects/jsoncpp/">json-cpp sourceforge project</a>
- <a HREF="http://www.sourceforge.net/projects/jsoncpp">json-cpp sourceforge project</a>
\section _rlinks Related links
- <a HREF="http://www.json.org/">JSON</a> Specification and alternate language implementations.
@@ -117,10 +110,7 @@ Permanent link to the latest revision of the file in subversion:
- <a HREF="http://www.cl.cam.ac.uk/~mgk25/unicode.html">UTF-8 and Unicode FAQ</a>.
\section _license License
See file <a HREF="LICENSE">LICENSE</a> in the top-directory of the project.
Basically JsonCpp is licensed under MIT license, or public domain if desired
and recognized in your jurisdiction.
The json-cpp library and this documentation are in Public Domain.
\author Baptiste Lepilleur <blep@users.sourceforge.net>
*/

View File

@@ -11,27 +11,22 @@
- aix/vacpp
- Add JsonCpp version to header as numeric for use in preprocessor test
- Remove buggy experimental hash stuff
- Release on sourceforge download
\section ms_strict Adds a strict mode to reader/parser
Strict JSON support as specific in RFC 4627 (http://www.ietf.org/rfc/rfc4627.txt?number=4627).
- Enforce only object or array as root element
- Disable comment support
- Get jsonchecker failing tests to pass in strict mode
\section ms_writer Writter control
Provides more control to determine how specific items are serialized when JSON allow choice:
- Optionally allow escaping of non-ASCII characters using unicode escape sequence "\\u".
- Optionally allow escaping of "/" using "\/".
\section ms_separation Expose json reader/writer API that do not impose using Json::Value.
Some typical use-case involve an application specific structure to/from a JSON document.
- Event base parser to allow unserializing a Json document directly in datastructure instead of
using the intermediate Json::Value.
- Stream based parser to serialized a Json document without using Json::Value as input.
- "Stream" based parser to serialized a Json document without using Json::Value as input.
- Performance oriented parser/writer:
- Provides an event based parser. Should allow pulling & skipping events for ease of use.
- Provides a JSON document builder: fast only.
\section ms_perfo Performance tuning
- Provides support for static property name definition avoiding allocation
- Provides support for static property name definition avoiding allocation
- Static property dictionnary can be provided to JSON reader
- Performance scenario & benchmarking
\section testing Testing
- Adds more tests for unicode parsing (e.g. including surrogate and error detection).
*/

View File

@@ -127,8 +127,6 @@ def build_doc( options, make_release=False ):
tarball_sources = [
output_dir,
'README.txt',
'LICENSE',
'NEWS.txt',
'version'
]
tarball_basedir = os.path.join( output_dir, html_output_dirname )

View File

@@ -1,8 +1,3 @@
// 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 JSON_AUTOLINK_H_INCLUDED
# define JSON_AUTOLINK_H_INCLUDED

View File

@@ -1,8 +1,3 @@
// 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 JSON_CONFIG_H_INCLUDED
# define JSON_CONFIG_H_INCLUDED
@@ -16,7 +11,7 @@
//# define JSON_USE_CPPTL_SMALLMAP 1
/// If defined, indicates that Json specific container should be used
/// (hash table & simple deque container with customizable allocator).
/// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332
/// THIS FEATURE IS STILL EXPERIMENTAL!
//# define JSON_VALUE_USE_INTERNAL_MAP 1
/// Force usage of standard new/malloc based allocator instead of memory pool based allocator.
/// The memory pools allocator used optimization (initializing Value and ValueInternalLink
@@ -28,12 +23,6 @@
/// instead of C assert macro.
# define JSON_USE_EXCEPTION 1
/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgated header.
// #define JSON_IS_AMALGATED
# ifdef JSON_IN_CPPTL
# include <cpptl/config.h>
# ifndef JSON_USE_CPPTL
@@ -51,46 +40,4 @@
# define JSON_API
# 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
#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // 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))
#endif
#if !defined(JSONCPP_DEPRECATED)
# define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
namespace Json {
typedef int Int;
typedef unsigned int UInt;
# if defined(JSON_NO_INT64)
typedef int LargestInt;
typedef unsigned int LargestUInt;
# undef JSON_HAS_INT64
# else // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
# if defined(_MSC_VER) // Microsoft Visual Studio
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
# else // if defined(_MSC_VER) // Other platforms, use long long
typedef long long int Int64;
typedef unsigned long long int UInt64;
# endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
# define JSON_HAS_INT64
# endif // if defined(JSON_NO_INT64)
} // end namespace Json
#endif // JSON_CONFIG_H_INCLUDED

View File

@@ -1,49 +1,42 @@
// 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_FEATURES_H_INCLUDED
# define CPPTL_JSON_FEATURES_H_INCLUDED
#if !defined(JSON_IS_AMALGATED)
# include "forwards.h"
#endif // if !defined(JSON_IS_AMALGATED)
namespace Json {
/** \brief Configuration passed to reader and writer.
* This configuration object can be used to force the Reader or Writer
* to behave in a standard conforming way.
*/
class JSON_API Features
{
public:
/** \brief A configuration that allows all features and assumes all strings are UTF-8.
* - C & C++ comments are allowed
* - Root object can be any JSON value
* - Assumes Value strings are encoded in UTF-8
*/
static Features all();
/** \brief A configuration that is strictly compatible with the JSON specification.
* - Comments are forbidden.
* - Root object must be either an array or an object value.
* - Assumes Value strings are encoded in UTF-8
*/
static Features strictMode();
/** \brief Initialize the configuration like JsonConfig::allFeatures;
*/
Features();
/// \c true if comments are allowed. Default: \c true.
bool allowComments_;
/// \c true if root must be either an array or an object value. Default: \c false.
bool strictRoot_;
};
} // namespace Json
#endif // CPPTL_JSON_FEATURES_H_INCLUDED
#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
# define CPPTL_JSON_FEATURES_H_INCLUDED
# include "forwards.h"
namespace Json {
/** \brief Configuration passed to reader and writer.
* This configuration object can be used to force the Reader or Writer
* to behave in a standard conforming way.
*/
class JSON_API Features
{
public:
/** \brief A configuration that allows all features and assumes all strings are UTF-8.
* - C & C++ comments are allowed
* - Root object can be any JSON value
* - Assumes Value strings are encoded in UTF-8
*/
static Features all();
/** \brief A configuration that is strictly compatible with the JSON specification.
* - Comments are forbidden.
* - Root object must be either an array or an object value.
* - Assumes Value strings are encoded in UTF-8
*/
static Features strictMode();
/** \brief Initialize the configuration like JsonConfig::allFeatures;
*/
Features();
/// \c true if comments are allowed. Default: \c true.
bool allowComments_;
/// \c true if root must be either an array or an object value. Default: \c false.
bool strictRoot_;
};
} // namespace Json
#endif // CPPTL_JSON_FEATURES_H_INCLUDED

View File

@@ -1,14 +1,7 @@
// 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 JSON_FORWARDS_H_INCLUDED
# define JSON_FORWARDS_H_INCLUDED
#if !defined(JSON_IS_AMALGATED)
# include "config.h"
#endif // if !defined(JSON_IS_AMALGATED)
namespace Json {
@@ -23,7 +16,8 @@ namespace Json {
class Features;
// value.h
typedef unsigned int ArrayIndex;
typedef int Int;
typedef unsigned int UInt;
class StaticString;
class Path;
class PathArgument;
@@ -32,6 +26,7 @@ namespace Json {
class ValueIterator;
class ValueConstIterator;
#ifdef JSON_VALUE_USE_INTERNAL_MAP
class ValueAllocator;
class ValueMapAllocator;
class ValueInternalLink;
class ValueInternalArray;

View File

@@ -1,8 +1,3 @@
// 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 JSON_JSON_H_INCLUDED
# define JSON_JSON_H_INCLUDED

View File

@@ -1,15 +1,8 @@
// 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_READER_H_INCLUDED
# define CPPTL_JSON_READER_H_INCLUDED
#if !defined(JSON_IS_AMALGATED)
# include "features.h"
# include "value.h"
#endif // if !defined(JSON_IS_AMALGATED)
# include <deque>
# include <stack>
# include <string>
@@ -51,9 +44,7 @@ namespace Json {
bool collectComments = true );
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the document to read.
* \param endDoc Pointer on the end of the UTF-8 encoded string of the document to read.
\ Must be >= beginDoc.
* \param document UTF-8 encoded string containing the document to read.
* \param root [out] Contains the root value of the document if it was
* successfully parsed.
* \param collectComments \c true to collect comment and allow writing them back during
@@ -76,18 +67,9 @@ namespace Json {
* \return Formatted error message with the list of errors with their location in
* the parsed document. An empty string is returned if no error occurred
* during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
std::string getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed document.
* \return Formatted error message with the list of errors with their location in
* the parsed document. An empty string is returned if no error occurred
* during parsing.
*/
std::string getFormattedErrorMessages() const;
private:
enum TokenType
{

View File

@@ -1,14 +1,7 @@
// 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_H_INCLUDED
# define CPPTL_JSON_H_INCLUDED
#if !defined(JSON_IS_AMALGATED)
# include "forwards.h"
#endif // if !defined(JSON_IS_AMALGATED)
# include <string>
# include <vector>
@@ -128,36 +121,13 @@ namespace Json {
typedef ValueConstIterator const_iterator;
typedef Json::UInt UInt;
typedef Json::Int Int;
# if defined(JSON_HAS_INT64)
typedef Json::UInt64 UInt64;
typedef Json::Int64 Int64;
#endif // defined(JSON_HAS_INT64)
typedef Json::LargestInt LargestInt;
typedef Json::LargestUInt LargestUInt;
typedef Json::ArrayIndex ArrayIndex;
typedef UInt ArrayIndex;
static const Value 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.
static const LargestInt maxLargestInt;
/// Maximum unsigned integer value that can be stored in a Json::Value.
static const LargestUInt maxLargestUInt;
/// Minimum signed int value that can be stored in a Json::Value.
static const Int minInt;
/// Maximum signed int value that can be stored in a Json::Value.
static const Int minInt;
static const Int maxInt;
/// Maximum unsigned int value that can be stored in a Json::Value.
static const UInt maxUInt;
/// Minimum signed 64 bits int value that can be stored in a Json::Value.
static const Int64 minInt64;
/// Maximum signed 64 bits int value that can be stored in a Json::Value.
static const Int64 maxInt64;
/// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
static const UInt64 maxUInt64;
private:
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
# ifndef JSON_VALUE_USE_INTERNAL_MAP
@@ -170,20 +140,20 @@ namespace Json {
duplicate,
duplicateOnCopy
};
CZString( ArrayIndex index );
CZString( int index );
CZString( const char *cstr, DuplicationPolicy allocate );
CZString( const CZString &other );
~CZString();
CZString &operator =( const CZString &other );
bool operator<( const CZString &other ) const;
bool operator==( const CZString &other ) const;
ArrayIndex index() const;
int index() const;
const char *c_str() const;
bool isStaticString() const;
private:
void swap( CZString &other );
const char *cstr_;
ArrayIndex index_;
int index_;
};
public:
@@ -214,10 +184,6 @@ namespace Json {
Value( ValueType type = nullValue );
Value( Int value );
Value( UInt value );
#if defined(JSON_HAS_INT64)
Value( Int64 value );
Value( UInt64 value );
#endif // if defined(JSON_HAS_INT64)
Value( double value );
Value( const char *value );
Value( const char *beginValue, const char *endValue );
@@ -265,11 +231,6 @@ namespace Json {
# endif
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
@@ -287,7 +248,7 @@ namespace Json {
bool isConvertibleTo( ValueType other ) const;
/// Number of values in array or object
ArrayIndex size() const;
UInt size() const;
/// \brief Return true if empty array, empty object, or null;
/// otherwise, false.
@@ -306,38 +267,24 @@ namespace Json {
/// May only be called on nullValue or arrayValue.
/// \pre type() is arrayValue or nullValue
/// \post type() is arrayValue
void resize( ArrayIndex size );
void resize( UInt size );
/// Access an array element (zero based index ).
/// If the array contains less than index element, then null value are inserted
/// in the array so that its size is index+1.
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
Value &operator[]( ArrayIndex index );
/// Access an array element (zero based index ).
/// If the array contains less than index element, then null value are inserted
/// in the array so that its size is index+1.
Value &operator[]( UInt index );
/// Access an array element (zero based index )
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
Value &operator[]( int index );
/// Access an array element (zero based index )
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
const Value &operator[]( ArrayIndex index ) const;
/// Access an array element (zero based index )
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
const Value &operator[]( int index ) const;
/// If the array contains at least index+1 elements, returns the element value,
const Value &operator[]( UInt index ) const;
/// If the array contains at least index+1 elements, returns the element value,
/// otherwise returns defaultValue.
Value get( ArrayIndex index,
Value get( UInt index,
const Value &defaultValue ) const;
/// Return true if index < size().
bool isValidIndex( ArrayIndex index ) const;
bool isValidIndex( UInt index ) const;
/// \brief Append value to array at the end.
///
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
@@ -477,8 +424,8 @@ namespace Json {
union ValueHolder
{
LargestInt int_;
LargestUInt uint_;
Int int_;
UInt uint_;
double real_;
bool bool_;
char *string_;
@@ -507,7 +454,7 @@ namespace Json {
friend class Path;
PathArgument();
PathArgument( ArrayIndex index );
PathArgument( UInt index );
PathArgument( const char *key );
PathArgument( const std::string &key );
@@ -519,7 +466,7 @@ namespace Json {
kindKey
};
std::string key_;
ArrayIndex index_;
UInt index_;
Kind kind_;
};
@@ -566,7 +513,26 @@ namespace Json {
Args args_;
};
/** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
*
* - makeMemberName() and releaseMemberName() are called to respectively duplicate and
* free an Json::objectValue member name.
* - duplicateStringValue() and releaseStringValue() are called similarly to
* duplicate and free a Json::stringValue value.
*/
class ValueAllocator
{
public:
enum { unknown = (unsigned)-1 };
virtual ~ValueAllocator();
virtual char *makeMemberName( const char *memberName ) = 0;
virtual void releaseMemberName( char *memberName ) = 0;
virtual char *duplicateStringValue( const char *value,
unsigned int length = unknown ) = 0;
virtual void releaseStringValue( char *value ) = 0;
};
#ifdef JSON_VALUE_USE_INTERNAL_MAP
/** \brief Allocator to customize Value internal map.

View File

@@ -1,14 +1,7 @@
// 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 JSON_WRITER_H_INCLUDED
# define JSON_WRITER_H_INCLUDED
#if !defined(JSON_IS_AMALGATED)
# include "value.h"
#endif // if !defined(JSON_IS_AMALGATED)
# include <vector>
# include <string>
# include <iostream>
@@ -164,12 +157,8 @@ namespace Json {
bool addChildValues_;
};
# if defined(JSON_HAS_INT64)
std::string JSON_API valueToString( Int value );
std::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 );

View File

@@ -3,10 +3,7 @@
Requires Python 2.6
Example of invocation (use to test the script):
python makerelease.py --platform=msvc6,msvc71,msvc80,msvc90,mingw -ublep 0.6.0 0.7.0-dev
When testing this script:
python makerelease.py --force --retag --platform=msvc6,msvc71,msvc80,mingw -ublep test-0.6.0 test-0.6.1-dev
python makerelease.py --force --retag --platform=msvc6,msvc71,msvc80,mingw -ublep 0.5.0 0.6.0-dev
Example of invocation when doing a release:
python makerelease.py 0.5.0 0.6.0-dev
@@ -23,7 +20,6 @@ import tempfile
import os
import time
from devtools import antglob, fixeol, tarball
import amalgate
SVN_ROOT = 'https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/'
SVN_TAG_ROOT = SVN_ROOT + 'tags/jsoncpp'
@@ -323,14 +319,6 @@ Warning: --force should only be used when developping/testing the release script
print 'Generating source tarball to', source_tarball_path
tarball.make_tarball( source_tarball_path, [export_dir], export_dir, prefix_dir=source_dir )
amalgated_tarball_path = 'dist/%s-amalgated.tar.gz' % source_dir
print 'Generating amalgated source tarball to', amalgated_tarball_path
amalgated_dir = 'dist/amalgated'
amalgate.amalgate_source( export_dir, '%s/jsoncpp.cpp' % amalgated_dir, 'json/json.h' )
amalgated_source_dir = 'jsoncpp-src-amalgated' + release_version
tarball.make_tarball( amalgated_tarball_path, [amalgated_dir],
amalgated_dir, prefix_dir=amalgated_source_dir )
# Decompress source tarball, download and install scons-local
distcheck_dir = 'dist/distcheck'
distcheck_top_dir = distcheck_dir + '/' + source_dir

View File

@@ -1,12 +1,3 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
/* This executable is used for testing parser/writer using real JSON files.
*/
#include <json/json.h>
#include <algorithm> // sort
#include <stdio.h>
@@ -44,10 +35,10 @@ printValueTree( FILE *fout, Json::Value &value, const std::string &path = "." )
fprintf( fout, "%s=null\n", path.c_str() );
break;
case Json::intValue:
fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asLargestInt() ).c_str() );
fprintf( fout, "%s=%d\n", path.c_str(), value.asInt() );
break;
case Json::uintValue:
fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asLargestUInt() ).c_str() );
fprintf( fout, "%s=%u\n", path.c_str(), value.asUInt() );
break;
case Json::realValue:
fprintf( fout, "%s=%.16g\n", path.c_str(), value.asDouble() );
@@ -105,7 +96,7 @@ parseAndSaveValueTree( const std::string &input,
{
printf( "Failed to parse %s file: \n%s\n",
kind.c_str(),
reader.getFormattedErrorMessages().c_str() );
reader.getFormatedErrorMessages().c_str() );
return 1;
}
@@ -157,19 +148,6 @@ removeSuffix( const std::string &path,
return path.substr( 0, path.length() - extension.length() );
}
static void
printConfig()
{
// Print the configuration used to compile JsonCpp
#if defined(JSON_NO_INT64)
printf( "JSON_NO_INT64=1\n" );
#else
printf( "JSON_NO_INT64=0\n" );
#endif
}
static int
printUsage( const char *argv[] )
{
@@ -197,12 +175,6 @@ parseCommandLine( int argc, const char *argv[],
++index;
}
if ( std::string(argv[1]) == "--json-config" )
{
printConfig();
return 3;
}
if ( index == argc || index + 1 < argc )
{
return printUsage( argv );
@@ -224,44 +196,36 @@ int main( int argc, const char *argv[] )
return exitCode;
}
try
std::string input = readInputTestFile( path.c_str() );
if ( input.empty() )
{
std::string input = readInputTestFile( path.c_str() );
if ( input.empty() )
{
printf( "Failed to read input or empty input: %s\n", path.c_str() );
return 3;
}
std::string basePath = removeSuffix( argv[1], ".json" );
if ( !parseOnly && basePath.empty() )
{
printf( "Bad input path. Path does not end with '.expected':\n%s\n", path.c_str() );
return 3;
}
std::string actualPath = basePath + ".actual";
std::string rewritePath = basePath + ".rewrite";
std::string rewriteActualPath = basePath + ".actual-rewrite";
Json::Value root;
exitCode = parseAndSaveValueTree( input, actualPath, "input", root, features, parseOnly );
if ( exitCode == 0 && !parseOnly )
{
std::string rewrite;
exitCode = rewriteValueTree( rewritePath, root, rewrite );
if ( exitCode == 0 )
{
Json::Value rewriteRoot;
exitCode = parseAndSaveValueTree( rewrite, rewriteActualPath,
"rewrite", rewriteRoot, features, parseOnly );
}
}
printf( "Failed to read input or empty input: %s\n", path.c_str() );
return 3;
}
catch ( const std::exception &e )
std::string basePath = removeSuffix( argv[1], ".json" );
if ( !parseOnly && basePath.empty() )
{
printf( "Unhandled exception:\n%s\n", e.what() );
exitCode = 1;
printf( "Bad input path. Path does not end with '.expected':\n%s\n", path.c_str() );
return 3;
}
std::string actualPath = basePath + ".actual";
std::string rewritePath = basePath + ".rewrite";
std::string rewriteActualPath = basePath + ".actual-rewrite";
Json::Value root;
exitCode = parseAndSaveValueTree( input, actualPath, "input", root, features, parseOnly );
if ( exitCode == 0 && !parseOnly )
{
std::string rewrite;
exitCode = rewriteValueTree( rewritePath, root, rewrite );
if ( exitCode == 0 )
{
Json::Value rewriteRoot;
exitCode = parseAndSaveValueTree( rewrite, rewriteActualPath,
"rewrite", rewriteRoot, features, parseOnly );
}
}
return exitCode;

View File

@@ -1,8 +1,3 @@
// 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 JSONCPP_BATCHALLOCATOR_H_INCLUDED
# define JSONCPP_BATCHALLOCATOR_H_INCLUDED

View File

@@ -1,11 +1,5 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
// included by json_value.cpp
namespace Json {
// everything is within Json namespace
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -452,5 +446,3 @@ ValueInternalArray::compare( const ValueInternalArray &other ) const
}
return 0;
}
} // namespace Json

View File

@@ -1,11 +1,5 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
// included by json_value.cpp
namespace Json {
// everything is within Json namespace
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -421,7 +415,7 @@ ValueInternalMap::setNewItem( const char *key,
ValueInternalLink *link,
BucketIndex index )
{
char *duplicatedKey = makeMemberName( key );
char *duplicatedKey = valueAllocator()->makeMemberName( key );
++itemCount_;
link->keys_[index] = duplicatedKey;
link->items_[index].setItemUsed();
@@ -611,5 +605,3 @@ ValueInternalMap::distance( const IteratorState &x, const IteratorState &y )
increment( it );
return offset;
}
} // namespace Json

View File

@@ -1,13 +1,5 @@
// 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
#if !defined(JSON_IS_AMALGATED)
# include <json/reader.h>
# include <json/value.h>
# include "json_tool.h"
#endif // if !defined(JSON_IS_AMALGATED)
#include <json/reader.h>
#include <json/value.h>
#include <utility>
#include <cstdio>
#include <cassert>
@@ -74,6 +66,42 @@ containsNewLine( Reader::Location begin,
return false;
}
static std::string codePointToUTF8(unsigned int cp)
{
std::string result;
// based on description from http://en.wikipedia.org/wiki/UTF-8
if (cp <= 0x7f)
{
result.resize(1);
result[0] = static_cast<char>(cp);
}
else if (cp <= 0x7FF)
{
result.resize(2);
result[1] = static_cast<char>(0x80 | (0x3f & cp));
result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
}
else if (cp <= 0xFFFF)
{
result.resize(3);
result[2] = static_cast<char>(0x80 | (0x3f & cp));
result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
}
else if (cp <= 0x10FFFF)
{
result.resize(4);
result[3] = static_cast<char>(0x80 | (0x3f & cp));
result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
}
return result;
}
// Class Reader
// //////////////////////////////////////////////////////////////////
@@ -535,8 +563,8 @@ Reader::readArray( Token &tokenStart )
{
ok = readToken( token );
}
bool badTokenType = ( token.type_ != tokenArraySeparator &&
token.type_ != tokenArrayEnd );
bool badTokenType = ( token.type_ == tokenArraySeparator &&
token.type_ == tokenArrayEnd );
if ( !ok || badTokenType )
{
return addErrorAndRecover( "Missing ',' or ']' in array declaration",
@@ -562,41 +590,26 @@ Reader::decodeNumber( Token &token )
}
if ( isDouble )
return decodeDouble( token );
// Attempts to parse the number as an integer. If the number is
// larger than the maximum supported value of an integer then
// we decode the number as a double.
Location current = token.start_;
bool isNegative = *current == '-';
if ( isNegative )
++current;
Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt)
: Value::maxLargestUInt;
Value::LargestUInt threshold = maxIntegerValue / 10;
Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 );
assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 );
Value::LargestUInt value = 0;
Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt)
: Value::maxUInt) / 10;
Value::UInt value = 0;
while ( current < token.end_ )
{
Char c = *current++;
if ( c < '0' || c > '9' )
return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
Value::UInt digit(c - '0');
if ( value >= threshold )
{
// If the current digit is not the last one, or if it is
// greater than the last digit of the maximum integer value,
// the parse the number as a double.
if ( current != token.end_ || digit > lastDigitThreshold )
{
return decodeDouble( token );
}
}
value = value * 10 + digit;
return decodeDouble( token );
value = value * 10 + Value::UInt(c - '0');
}
if ( isNegative )
currentValue() = -Value::LargestInt( value );
else if ( value <= Value::LargestUInt(Value::maxInt) )
currentValue() = Value::LargestInt( value );
currentValue() = -Value::Int( value );
else if ( value <= Value::UInt(Value::maxInt) )
currentValue() = Value::Int( value );
else
currentValue() = value;
return true;
@@ -612,7 +625,7 @@ Reader::decodeDouble( Token &token )
int length = int(token.end_ - token.start_);
if ( length <= bufferSize )
{
Char buffer[bufferSize+1];
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );
buffer[length] = 0;
count = sscanf( buffer, "%lf", &value );
@@ -841,16 +854,8 @@ Reader::getLocationLineAndColumn( Location location ) const
}
// Deprecated. Preserved for backward compatibility
std::string
Reader::getFormatedErrorMessages() const
{
return getFormattedErrorMessages();
}
std::string
Reader::getFormattedErrorMessages() const
{
std::string formattedMessage;
for ( Errors::const_iterator itError = errors_.begin();
@@ -872,7 +877,7 @@ std::istream& operator>>( std::istream &sin, Value &root )
Json::Reader reader;
bool ok = reader.parse(sin, root, true);
//JSON_ASSERT( ok );
if (!ok) throw std::runtime_error(reader.getFormattedErrorMessages());
if (!ok) throw std::runtime_error(reader.getFormatedErrorMessages());
return sin;
}

View File

@@ -1,93 +0,0 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
# define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
/* This header provides common string manipulation support, such as UTF-8,
* portable conversion from/to string...
*
* It is an internal header that must not be exposed.
*/
namespace Json {
/// Converts a unicode code-point to UTF-8.
static inline std::string
codePointToUTF8(unsigned int cp)
{
std::string result;
// based on description from http://en.wikipedia.org/wiki/UTF-8
if (cp <= 0x7f)
{
result.resize(1);
result[0] = static_cast<char>(cp);
}
else if (cp <= 0x7FF)
{
result.resize(2);
result[1] = static_cast<char>(0x80 | (0x3f & cp));
result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
}
else if (cp <= 0xFFFF)
{
result.resize(3);
result[2] = static_cast<char>(0x80 | (0x3f & cp));
result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
}
else if (cp <= 0x10FFFF)
{
result.resize(4);
result[3] = static_cast<char>(0x80 | (0x3f & cp));
result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
}
return result;
}
/// Returns true if ch is a control character (in range [0,32[).
static inline bool
isControlCharacter(char ch)
{
return ch > 0 && ch <= 0x1F;
}
enum {
/// Constant that specify the size of the buffer that must be passed to uintToString.
uintToStringBufferSize = 3*sizeof(LargestUInt)+1
};
// Defines a char buffer for use with uintToString().
typedef char UIntToStringBuffer[uintToStringBufferSize];
/** Converts an unsigned integer to string.
* @param value Unsigned interger to convert to string
* @param current Input/Output string buffer.
* Must have at least uintToStringBufferSize chars free.
*/
static inline void
uintToString( LargestUInt value,
char *&current )
{
*--current = 0;
do
{
*--current = char(value % 10) + '0';
value /= 10;
}
while ( value != 0 );
}
} // namespace Json {
#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED

View File

@@ -1,16 +1,6 @@
// 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
#if !defined(JSON_IS_AMALGATED)
# include <json/value.h>
# include <json/writer.h>
# ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
# include "json_batchallocator.h"
# endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
#endif // if !defined(JSON_IS_AMALGATED)
#include <iostream>
#include <json/value.h>
#include <json/writer.h>
#include <utility>
#include <stdexcept>
#include <cstring>
@@ -19,6 +9,9 @@
# include <cpptl/conststring.h>
#endif
#include <cstddef> // size_t
#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
# include "json_batchallocator.h"
#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
#define JSON_ASSERT_UNREACHABLE assert( false )
#define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
@@ -30,49 +23,92 @@ const Value Value::null;
const Int Value::minInt = Int( ~(UInt(-1)/2) );
const Int Value::maxInt = Int( UInt(-1)/2 );
const UInt Value::maxUInt = UInt(-1);
const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) );
const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 );
const UInt64 Value::maxUInt64 = UInt64(-1);
const LargestInt Value::minLargestInt = LargestInt( ~(LargestUInt(-1)/2) );
const LargestInt Value::maxLargestInt = LargestInt( LargestUInt(-1)/2 );
const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
// A "safe" implementation of strdup. Allow null pointer to be passed.
// Also avoid warning on msvc80.
//
//inline char *safeStringDup( const char *czstring )
//{
// if ( czstring )
// {
// const size_t length = (unsigned int)( strlen(czstring) + 1 );
// char *newString = static_cast<char *>( malloc( length ) );
// memcpy( newString, czstring, length );
// return newString;
// }
// return 0;
//}
//
//inline char *safeStringDup( const std::string &str )
//{
// if ( !str.empty() )
// {
// const size_t length = str.length();
// char *newString = static_cast<char *>( malloc( length + 1 ) );
// memcpy( newString, str.c_str(), length );
// newString[length] = 0;
// return newString;
// }
// return 0;
//}
/// Unknown size marker
enum { unknown = (unsigned)-1 };
/** Duplicates the specified string value.
* @param value Pointer to the string to duplicate. Must be zero-terminated if
* length is "unknown".
* @param length Length of the value. if equals to unknown, then it will be
* computed using strlen(value).
* @return Pointer on the duplicate instance of string.
*/
static inline char *
duplicateStringValue( const char *value,
unsigned int length = unknown )
ValueAllocator::~ValueAllocator()
{
if ( length == unknown )
length = (unsigned int)strlen(value);
char *newString = static_cast<char *>( malloc( length + 1 ) );
JSON_ASSERT_MESSAGE( newString != 0, "Failed to allocate string value buffer" );
memcpy( newString, value, length );
newString[length] = 0;
return newString;
}
/** Free the string duplicated by duplicateStringValue().
*/
static inline void
releaseStringValue( char *value )
class DefaultValueAllocator : public ValueAllocator
{
if ( value )
free( value );
public:
virtual ~DefaultValueAllocator()
{
}
virtual char *makeMemberName( const char *memberName )
{
return duplicateStringValue( memberName );
}
virtual void releaseMemberName( char *memberName )
{
releaseStringValue( memberName );
}
virtual char *duplicateStringValue( const char *value,
unsigned int length = unknown )
{
//@todo invesgate this old optimization
//if ( !value || value[0] == 0 )
// return 0;
if ( length == unknown )
length = (unsigned int)strlen(value);
char *newString = static_cast<char *>( malloc( length + 1 ) );
memcpy( newString, value, length );
newString[length] = 0;
return newString;
}
virtual void releaseStringValue( char *value )
{
if ( value )
free( value );
}
};
static ValueAllocator *&valueAllocator()
{
static DefaultValueAllocator defaultAllocator;
static ValueAllocator *valueAllocator = &defaultAllocator;
return valueAllocator;
}
} // namespace Json
static struct DummyValueAllocatorInitializer {
DummyValueAllocatorInitializer()
{
valueAllocator(); // ensure valueAllocator() statics are initialized before main().
}
} dummyValueAllocatorInitializer;
// //////////////////////////////////////////////////////////////////
@@ -82,16 +118,13 @@ releaseStringValue( char *value )
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
#if !defined(JSON_IS_AMALGATED)
# ifdef JSON_VALUE_USE_INTERNAL_MAP
# include "json_internalarray.inl"
# include "json_internalmap.inl"
# endif // JSON_VALUE_USE_INTERNAL_MAP
#ifdef JSON_VALUE_USE_INTERNAL_MAP
# include "json_internalarray.inl"
# include "json_internalmap.inl"
#endif // JSON_VALUE_USE_INTERNAL_MAP
# include "json_valueiterator.inl"
#endif // if !defined(JSON_IS_AMALGATED)
namespace Json {
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -110,7 +143,7 @@ Value::CommentInfo::CommentInfo()
Value::CommentInfo::~CommentInfo()
{
if ( comment_ )
releaseStringValue( comment_ );
valueAllocator()->releaseStringValue( comment_ );
}
@@ -118,11 +151,11 @@ void
Value::CommentInfo::setComment( const char *text )
{
if ( comment_ )
releaseStringValue( comment_ );
JSON_ASSERT( text != 0 );
valueAllocator()->releaseStringValue( comment_ );
JSON_ASSERT( text );
JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
// It seems that /**/ style comments are acceptable as well.
comment_ = duplicateStringValue( text );
comment_ = valueAllocator()->duplicateStringValue( text );
}
@@ -138,14 +171,14 @@ Value::CommentInfo::setComment( const char *text )
// Notes: index_ indicates if the string was allocated when
// a string is stored.
Value::CZString::CZString( ArrayIndex index )
Value::CZString::CZString( int index )
: cstr_( 0 )
, index_( index )
{
}
Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
: cstr_( allocate == duplicate ? duplicateStringValue(cstr)
: cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr)
: cstr )
, index_( allocate )
{
@@ -153,7 +186,7 @@ Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
Value::CZString::CZString( const CZString &other )
: cstr_( other.index_ != noDuplication && other.cstr_ != 0
? duplicateStringValue( other.cstr_ )
? valueAllocator()->makeMemberName( other.cstr_ )
: other.cstr_ )
, index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
: other.index_ )
@@ -163,7 +196,7 @@ Value::CZString::CZString( const CZString &other )
Value::CZString::~CZString()
{
if ( cstr_ && index_ == duplicate )
releaseStringValue( const_cast<char *>( cstr_ ) );
valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) );
}
void
@@ -198,7 +231,7 @@ Value::CZString::operator==( const CZString &other ) const
}
ArrayIndex
int
Value::CZString::index() const
{
return index_;
@@ -276,17 +309,6 @@ Value::Value( ValueType type )
}
#if defined(JSON_HAS_INT64)
Value::Value( UInt value )
: type_( uintValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.uint_ = value;
}
Value::Value( Int value )
: type_( intValue )
, comments_( 0 )
@@ -297,21 +319,8 @@ Value::Value( Int value )
value_.int_ = value;
}
#endif // if defined(JSON_HAS_INT64)
Value::Value( Int64 value )
: type_( intValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.int_ = value;
}
Value::Value( UInt64 value )
Value::Value( UInt value )
: type_( uintValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
@@ -339,7 +348,7 @@ Value::Value( const char *value )
, itemIsUsed_( 0 )
#endif
{
value_.string_ = duplicateStringValue( value );
value_.string_ = valueAllocator()->duplicateStringValue( value );
}
@@ -352,8 +361,8 @@ Value::Value( const char *beginValue,
, itemIsUsed_( 0 )
#endif
{
value_.string_ = duplicateStringValue( beginValue,
(unsigned int)(endValue - beginValue) );
value_.string_ = valueAllocator()->duplicateStringValue( beginValue,
UInt(endValue - beginValue) );
}
@@ -365,8 +374,8 @@ Value::Value( const std::string &value )
, itemIsUsed_( 0 )
#endif
{
value_.string_ = duplicateStringValue( value.c_str(),
(unsigned int)value.length() );
value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(),
(unsigned int)value.length() );
}
@@ -391,7 +400,7 @@ Value::Value( const CppTL::ConstString &value )
, itemIsUsed_( 0 )
#endif
{
value_.string_ = duplicateStringValue( value, value.length() );
value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() );
}
# endif
@@ -425,7 +434,7 @@ Value::Value( const Value &other )
case stringValue:
if ( other.value_.string_ )
{
value_.string_ = duplicateStringValue( other.value_.string_ );
value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ );
allocated_ = true;
}
else
@@ -472,7 +481,7 @@ Value::~Value()
break;
case stringValue:
if ( allocated_ )
releaseStringValue( value_.string_ );
valueAllocator()->releaseStringValue( value_.string_ );
break;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
@@ -703,7 +712,6 @@ Value::asConstString() const
}
# endif
Value::Int
Value::asInt() const
{
@@ -712,11 +720,10 @@ Value::asInt() const
case nullValue:
return 0;
case intValue:
JSON_ASSERT_MESSAGE( value_.int_ >= minInt && value_.int_ <= maxInt, "unsigned integer out of signed int range" );
return Int(value_.int_);
return value_.int_;
case uintValue:
JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" );
return Int(value_.uint_);
JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" );
return value_.uint_;
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
return Int( value_.real_ );
@@ -732,7 +739,6 @@ Value::asInt() const
return 0; // unreachable;
}
Value::UInt
Value::asUInt() const
{
@@ -742,11 +748,9 @@ Value::asUInt() const
return 0;
case intValue:
JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
JSON_ASSERT_MESSAGE( value_.int_ <= maxUInt, "signed integer out of UInt range" );
return UInt(value_.int_);
return value_.int_;
case uintValue:
JSON_ASSERT_MESSAGE( value_.uint_ <= maxUInt, "unsigned integer out of UInt range" );
return UInt(value_.uint_);
return value_.uint_;
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
return UInt( value_.real_ );
@@ -762,88 +766,6 @@ Value::asUInt() const
return 0; // unreachable;
}
# if defined(JSON_HAS_INT64)
Value::Int64
Value::asInt64() const
{
switch ( type_ )
{
case nullValue:
return 0;
case intValue:
return value_.int_;
case uintValue:
JSON_ASSERT_MESSAGE( value_.uint_ <= UInt64(maxInt64), "unsigned integer out of Int64 range" );
return value_.uint_;
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= minInt64 && value_.real_ <= maxInt64, "Real out of Int64 range" );
return Int( value_.real_ );
case booleanValue:
return value_.bool_ ? 1 : 0;
case stringValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to Int64" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
Value::UInt64
Value::asUInt64() const
{
switch ( type_ )
{
case nullValue:
return 0;
case intValue:
JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to UInt64" );
return value_.int_;
case uintValue:
return value_.uint_;
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt64, "Real out of UInt64 range" );
return UInt( value_.real_ );
case booleanValue:
return value_.bool_ ? 1 : 0;
case stringValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to UInt64" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
# endif // if defined(JSON_HAS_INT64)
LargestInt
Value::asLargestInt() const
{
#if defined(JSON_NO_INT64)
return asInt();
#else
return asInt64();
#endif
}
LargestUInt
Value::asLargestUInt() const
{
#if defined(JSON_NO_INT64)
return asUInt();
#else
return asUInt64();
#endif
}
double
Value::asDouble() const
{
@@ -852,13 +774,9 @@ Value::asDouble() const
case nullValue:
return 0.0;
case intValue:
return static_cast<double>( value_.int_ );
return value_.int_;
case uintValue:
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return static_cast<double>( value_.uint_ );
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return static_cast<double>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return value_.uint_;
case realValue:
return value_.real_;
case booleanValue:
@@ -873,35 +791,6 @@ Value::asDouble() const
return 0; // unreachable;
}
float
Value::asFloat() const
{
switch ( type_ )
{
case nullValue:
return 0.0f;
case intValue:
return static_cast<float>( value_.int_ );
case uintValue:
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return static_cast<float>( value_.uint_ );
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
return static_cast<float>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
case realValue:
return static_cast<float>( value_.real_ );
case booleanValue:
return value_.bool_ ? 1.0f : 0.0f;
case stringValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to float" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0.0f; // unreachable;
}
bool
Value::asBool() const
{
@@ -980,7 +869,7 @@ Value::isConvertibleTo( ValueType other ) const
/// Number of values in array or object
ArrayIndex
Value::UInt
Value::size() const
{
switch ( type_ )
@@ -1002,7 +891,7 @@ Value::size() const
}
return 0;
case objectValue:
return ArrayIndex( value_.map_->size() );
return Int( value_.map_->size() );
#else
case arrayValue:
return Int( value_.array_->size() );
@@ -1059,23 +948,21 @@ Value::clear()
}
void
Value::resize( ArrayIndex newSize )
Value::resize( UInt newSize )
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
if ( type_ == nullValue )
*this = Value( arrayValue );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
ArrayIndex oldSize = size();
UInt oldSize = size();
if ( newSize == 0 )
clear();
else if ( newSize > oldSize )
(*this)[ newSize - 1 ];
else
{
for ( ArrayIndex index = newSize; index < oldSize; ++index )
{
for ( UInt index = newSize; index < oldSize; ++index )
value_.map_->erase( index );
}
assert( size() == newSize );
}
#else
@@ -1085,7 +972,7 @@ Value::resize( ArrayIndex newSize )
Value &
Value::operator[]( ArrayIndex index )
Value::operator[]( UInt index )
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
if ( type_ == nullValue )
@@ -1105,16 +992,8 @@ Value::operator[]( ArrayIndex index )
}
Value &
Value::operator[]( int index )
{
JSON_ASSERT( index >= 0 );
return (*this)[ ArrayIndex(index) ];
}
const Value &
Value::operator[]( ArrayIndex index ) const
Value::operator[]( UInt index ) const
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
if ( type_ == nullValue )
@@ -1132,14 +1011,6 @@ Value::operator[]( ArrayIndex index ) const
}
const Value &
Value::operator[]( int index ) const
{
JSON_ASSERT( index >= 0 );
return (*this)[ ArrayIndex(index) ];
}
Value &
Value::operator[]( const char *key )
{
@@ -1172,7 +1043,7 @@ Value::resolveReference( const char *key,
Value
Value::get( ArrayIndex index,
Value::get( UInt index,
const Value &defaultValue ) const
{
const Value *value = &((*this)[index]);
@@ -1181,7 +1052,7 @@ Value::get( ArrayIndex index,
bool
Value::isValidIndex( ArrayIndex index ) const
Value::isValidIndex( UInt index ) const
{
return index < size();
}
@@ -1644,7 +1515,7 @@ PathArgument::PathArgument()
}
PathArgument::PathArgument( ArrayIndex index )
PathArgument::PathArgument( Value::UInt index )
: index_( index )
, kind_( kindIndex )
{
@@ -1700,9 +1571,9 @@ Path::makePath( const std::string &path,
addPathInArg( path, in, itInArg, PathArgument::kindIndex );
else
{
ArrayIndex index = 0;
Value::UInt index = 0;
for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
index = index * 10 + ArrayIndex(*current - '0');
index = index * 10 + Value::UInt(*current - '0');
args_.push_back( index );
}
if ( current == end || *current++ != ']' )

View File

@@ -1,11 +1,6 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
// included by json_value.cpp
// everything is within Json namespace
namespace Json {
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -295,5 +290,3 @@ ValueIterator::operator =( const SelfType &other )
copy( other );
return *this;
}
} // namespace Json

View File

@@ -1,12 +1,4 @@
// 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
#if !defined(JSON_IS_AMALGATED)
# include <json/writer.h>
# include "json_tool.h"
#endif // if !defined(JSON_IS_AMALGATED)
#include <json/writer.h>
#include <utility>
#include <assert.h>
#include <stdio.h>
@@ -21,6 +13,11 @@
namespace Json {
static bool isControlCharacter(char ch)
{
return ch > 0 && ch <= 0x1F;
}
static bool containsControlCharacter( const char* str )
{
while ( *str )
@@ -30,16 +27,26 @@ static bool containsControlCharacter( const char* str )
}
return false;
}
std::string valueToString( LargestInt value )
static void uintToString( unsigned int value,
char *&current )
{
UIntToStringBuffer buffer;
*--current = 0;
do
{
*--current = (value % 10) + '0';
value /= 10;
}
while ( value != 0 );
}
std::string valueToString( Int value )
{
char buffer[32];
char *current = buffer + sizeof(buffer);
bool isNegative = value < 0;
if ( isNegative )
value = -value;
uintToString( LargestUInt(value), current );
uintToString( UInt(value), current );
if ( isNegative )
*--current = '-';
assert( current >= buffer );
@@ -47,31 +54,15 @@ std::string valueToString( LargestInt value )
}
std::string valueToString( LargestUInt value )
std::string valueToString( UInt value )
{
UIntToStringBuffer buffer;
char buffer[32];
char *current = buffer + sizeof(buffer);
uintToString( value, current );
assert( current >= buffer );
return current;
}
#if defined(JSON_HAS_INT64)
std::string valueToString( Int value )
{
return valueToString( LargestInt(value) );
}
std::string valueToString( UInt value )
{
return valueToString( LargestUInt(value) );
}
#endif // # if defined(JSON_HAS_INT64)
std::string valueToString( double value )
{
char buffer[32];
@@ -125,7 +116,7 @@ std::string valueToQuotedString( const char *value )
// We have to walk value and escape any special characters.
// Appending to std::string is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
std::string::size_type maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
std::string result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
@@ -222,10 +213,10 @@ FastWriter::writeValue( const Value &value )
document_ += "null";
break;
case intValue:
document_ += valueToString( value.asLargestInt() );
document_ += valueToString( value.asInt() );
break;
case uintValue:
document_ += valueToString( value.asLargestUInt() );
document_ += valueToString( value.asUInt() );
break;
case realValue:
document_ += valueToString( value.asDouble() );
@@ -305,10 +296,10 @@ StyledWriter::writeValue( const Value &value )
pushValue( "null" );
break;
case intValue:
pushValue( valueToString( value.asLargestInt() ) );
pushValue( valueToString( value.asInt() ) );
break;
case uintValue:
pushValue( valueToString( value.asLargestUInt() ) );
pushValue( valueToString( value.asUInt() ) );
break;
case realValue:
pushValue( valueToString( value.asDouble() ) );
@@ -581,10 +572,10 @@ StyledStreamWriter::writeValue( const Value &value )
pushValue( "null" );
break;
case intValue:
pushValue( valueToString( value.asLargestInt() ) );
pushValue( valueToString( value.asInt() ) );
break;
case uintValue:
pushValue( valueToString( value.asLargestUInt() ) );
pushValue( valueToString( value.asUInt() ) );
break;
case realValue:
pushValue( valueToString( value.asDouble() ) );

View File

@@ -1,8 +1,3 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC
#include "jsontest.h"
#include <stdio.h>

View File

@@ -1,8 +1,3 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSONTEST_H_INCLUDED
# define JSONTEST_H_INCLUDED
@@ -199,7 +194,7 @@ namespace JsonTest {
/// JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y;
/// JSONTEST_ASSERT( x == y );
#define JSONTEST_ASSERT( expr ) \
if ( expr ) \
if ( condition ) \
{ \
} \
else \

View File

@@ -1,8 +1,3 @@
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#include <json/json.h>
#include "jsontest.h"
@@ -28,7 +23,6 @@ struct ValueTest : JsonTest::TestCase
Json::Value unsignedInteger_;
Json::Value smallUnsignedInteger_;
Json::Value real_;
Json::Value float_;
Json::Value array1_;
Json::Value object1_;
Json::Value emptyString_;
@@ -44,7 +38,6 @@ struct ValueTest : JsonTest::TestCase
, smallUnsignedInteger_( Json::Value::UInt( Json::Value::maxInt ) )
, unsignedInteger_( 34567890u )
, real_( 1234.56789 )
, float_( 0.00390625f )
, emptyString_( "" )
, string1_( "a" )
, string_( "sometext with space" )
@@ -174,23 +167,6 @@ JSONTEST_FIXTURE( ValueTest, isUInt )
}
JSONTEST_FIXTURE( ValueTest, accessArray )
{
const unsigned int index0 = 0;
JSONTEST_ASSERT( Json::Value(1234) == array1_[index0] ) << "Json::Value::operator[ArrayIndex]";
JSONTEST_ASSERT( Json::Value(1234) == array1_[0] ) << "Json::Value::operator[int]";
const Json::Value &constArray = array1_;
JSONTEST_ASSERT( Json::Value(1234) == constArray[index0] ) << "Json::Value::operator[ArrayIndex] const";
JSONTEST_ASSERT( Json::Value(1234) == constArray[0] ) << "Json::Value::operator[int] const";
}
JSONTEST_FIXTURE( ValueTest, asFloat )
{
JSONTEST_ASSERT_EQUAL( 0.00390625f, float_.asFloat() ) << "Json::Value::asFloat()";
}
void
ValueTest::checkConstMemberCount( const Json::Value &value, unsigned int expectedCount )
{
@@ -264,8 +240,5 @@ int main( int argc, const char *argv[] )
JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isDouble );
JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isString );
JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isNull );
JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isNull );
JSONTEST_REGISTER_FIXTURE( runner, ValueTest, accessArray );
JSONTEST_REGISTER_FIXTURE( runner, ValueTest, asFloat );
return runner.runCommandLine( argc, argv );
}

View File

@@ -1 +0,0 @@
[ 1 2 3]

View File

@@ -1 +0,0 @@
.=9223372036854775808

View File

@@ -1,2 +0,0 @@
9223372036854775808

View File

@@ -1 +0,0 @@
.=-9223372036854775808

View File

@@ -1,2 +0,0 @@
-9223372036854775808

View File

@@ -1 +0,0 @@
.=18446744073709551615

View File

@@ -1,2 +0,0 @@
18446744073709551615

View File

@@ -1 +0,0 @@
.="http://jsoncpp.sourceforge.net/"

View File

@@ -1 +0,0 @@
"http:\/\/jsoncpp.sourceforge.net\/"

View File

@@ -49,8 +49,7 @@ def runAllTests( jsontest_executable_path, input_dir = None,
failed_tests = []
valgrind_path = use_valgrind and VALGRIND_CMD or ''
for input_path in tests + test_jsonchecker:
expect_failure = os.path.basename( input_path ).startswith( 'fail' )
is_json_checker_test = (input_path in test_jsonchecker) or expect_failure
is_json_checker_test = input_path in test_jsonchecker
print 'TESTING:', input_path,
options = is_json_checker_test and '--json-checker' or ''
pipe = os.popen( "%s%s %s %s" % (
@@ -59,6 +58,7 @@ def runAllTests( jsontest_executable_path, input_dir = None,
process_output = pipe.read()
status = pipe.close()
if is_json_checker_test:
expect_failure = os.path.basename( input_path ).startswith( 'fail' )
if expect_failure:
if status is None:
print 'FAILED'

View File

@@ -1 +1 @@
0.6.0-rc1
0.5.0