Skip to content

Commit 2362d3f

Browse files
committedJun 4, 2017
JsonCPP update from 0.10.6 to 1.8.0
1 parent bf6569b commit 2362d3f

File tree

2 files changed

+1020
-466
lines changed

2 files changed

+1020
-466
lines changed
 

‎lib/jsoncpp/json/json.h

+323-143
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,28 @@
66
// //////////////////////////////////////////////////////////////////////
77

88
/*
9-
The JsonCpp library's source code, including accompanying documentation,
9+
The JsonCpp library's source code, including accompanying documentation,
1010
tests and demonstration applications, are licensed under the following
1111
conditions...
1212
13-
The author (Baptiste Lepilleur) explicitly disclaims copyright in all
14-
jurisdictions which recognize such a disclaimer. In such jurisdictions,
13+
The author (Baptiste Lepilleur) explicitly disclaims copyright in all
14+
jurisdictions which recognize such a disclaimer. In such jurisdictions,
1515
this software is released into the Public Domain.
1616
1717
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
1818
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
1919
released under the terms of the MIT License (see below).
2020
21-
In jurisdictions which recognize Public Domain property, the user of this
22-
software may choose to accept it either as 1) Public Domain, 2) under the
23-
conditions of the MIT License (see below), or 3) under the terms of dual
21+
In jurisdictions which recognize Public Domain property, the user of this
22+
software may choose to accept it either as 1) Public Domain, 2) under the
23+
conditions of the MIT License (see below), or 3) under the terms of dual
2424
Public Domain/MIT License conditions described here, as they choose.
2525
2626
The MIT License is about as close to Public Domain as a license can get, and is
2727
described in clear, concise terms at:
2828
2929
http://en.wikipedia.org/wiki/MIT_License
30-
30+
3131
The full text of the MIT License follows:
3232
3333
========================================================================
@@ -77,7 +77,7 @@ license you like.
7777
/// If defined, indicates that the source file is amalgated
7878
/// to prevent private header inclusion.
7979
#define JSON_IS_AMALGAMATION
80-
#define JSONCPP_STRING
80+
8181
// //////////////////////////////////////////////////////////////////////
8282
// Beginning of content of file: include/json/version.h
8383
// //////////////////////////////////////////////////////////////////////
@@ -87,13 +87,20 @@ license you like.
8787
#ifndef JSON_VERSION_H_INCLUDED
8888
# define JSON_VERSION_H_INCLUDED
8989

90-
# define JSONCPP_VERSION_STRING "0.10.6"
91-
# define JSONCPP_VERSION_MAJOR 0
92-
# define JSONCPP_VERSION_MINOR 10
93-
# define JSONCPP_VERSION_PATCH 6
90+
# define JSONCPP_VERSION_STRING "1.8.0"
91+
# define JSONCPP_VERSION_MAJOR 1
92+
# define JSONCPP_VERSION_MINOR 8
93+
# define JSONCPP_VERSION_PATCH 0
9494
# define JSONCPP_VERSION_QUALIFIER
9595
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
9696

97+
#ifdef JSONCPP_USING_SECURE_MEMORY
98+
#undef JSONCPP_USING_SECURE_MEMORY
99+
#endif
100+
#define JSONCPP_USING_SECURE_MEMORY 0
101+
// If non-zero, the library zeroes any memory that it has allocated before
102+
// it frees its memory.
103+
97104
#endif // JSON_VERSION_H_INCLUDED
98105

99106
// //////////////////////////////////////////////////////////////////////
@@ -116,6 +123,9 @@ license you like.
116123

117124
#ifndef JSON_CONFIG_H_INCLUDED
118125
#define JSON_CONFIG_H_INCLUDED
126+
#include <stddef.h>
127+
#include <string> //typedef String
128+
#include <stdint.h> //typedef int64_t, uint64_t
119129

120130
/// If defined, indicates that json library is embedded in CppTL library.
121131
//# define JSON_IN_CPPTL 1
@@ -148,12 +158,12 @@ license you like.
148158
#ifdef JSON_IN_CPPTL
149159
#define JSON_API CPPTL_API
150160
#elif defined(JSON_DLL_BUILD)
151-
#if defined(_MSC_VER)
161+
#if defined(_MSC_VER) || defined(__MINGW32__)
152162
#define JSON_API __declspec(dllexport)
153163
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
154164
#endif // if defined(_MSC_VER)
155165
#elif defined(JSON_DLL)
156-
#if defined(_MSC_VER)
166+
#if defined(_MSC_VER) || defined(__MINGW32__)
157167
#define JSON_API __declspec(dllimport)
158168
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
159169
#endif // if defined(_MSC_VER)
@@ -167,34 +177,93 @@ license you like.
167177
// Storages, and 64 bits integer support is disabled.
168178
// #define JSON_NO_INT64 1
169179

170-
#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6
171-
// Microsoft Visual Studio 6 only support conversion from __int64 to double
172-
// (no conversion from unsigned __int64).
173-
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
174-
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
175-
// characters in the debug information)
176-
// All projects I've ever seen with VS6 were using this globally (not bothering
177-
// with pragma push/pop).
178-
#pragma warning(disable : 4786)
179-
#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6
180-
181-
#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
182-
/// Indicates that the following function is deprecated.
183-
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
184-
#elif defined(__clang__) && defined(__has_feature)
185-
#if __has_feature(attribute_deprecated_with_message)
186-
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
180+
#if defined(_MSC_VER) // MSVC
181+
# if _MSC_VER <= 1200 // MSVC 6
182+
// Microsoft Visual Studio 6 only support conversion from __int64 to double
183+
// (no conversion from unsigned __int64).
184+
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
185+
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
186+
// characters in the debug information)
187+
// All projects I've ever seen with VS6 were using this globally (not bothering
188+
// with pragma push/pop).
189+
# pragma warning(disable : 4786)
190+
# endif // MSVC 6
191+
192+
# if _MSC_VER >= 1500 // MSVC 2008
193+
/// Indicates that the following function is deprecated.
194+
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
195+
# endif
196+
197+
#endif // defined(_MSC_VER)
198+
199+
// In c++11 the override keyword allows you to explicity define that a function
200+
// is intended to override the base-class version. This makes the code more
201+
// managable and fixes a set of common hard-to-find bugs.
202+
#if __cplusplus >= 201103L
203+
# define JSONCPP_OVERRIDE override
204+
# define JSONCPP_NOEXCEPT noexcept
205+
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
206+
# define JSONCPP_OVERRIDE override
207+
# define JSONCPP_NOEXCEPT throw()
208+
#elif defined(_MSC_VER) && _MSC_VER >= 1900
209+
# define JSONCPP_OVERRIDE override
210+
# define JSONCPP_NOEXCEPT noexcept
211+
#else
212+
# define JSONCPP_OVERRIDE
213+
# define JSONCPP_NOEXCEPT throw()
187214
#endif
188-
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
189-
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
190-
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
191-
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
215+
216+
#ifndef JSON_HAS_RVALUE_REFERENCES
217+
218+
#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
219+
#define JSON_HAS_RVALUE_REFERENCES 1
220+
#endif // MSVC >= 2010
221+
222+
#ifdef __clang__
223+
#if __has_feature(cxx_rvalue_references)
224+
#define JSON_HAS_RVALUE_REFERENCES 1
225+
#endif // has_feature
226+
227+
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
228+
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
229+
#define JSON_HAS_RVALUE_REFERENCES 1
230+
#endif // GXX_EXPERIMENTAL
231+
232+
#endif // __clang__ || __GNUC__
233+
234+
#endif // not defined JSON_HAS_RVALUE_REFERENCES
235+
236+
#ifndef JSON_HAS_RVALUE_REFERENCES
237+
#define JSON_HAS_RVALUE_REFERENCES 0
192238
#endif
193239

240+
#ifdef __clang__
241+
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
242+
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
243+
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
244+
# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
245+
# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
246+
# endif // GNUC version
247+
#endif // __clang__ || __GNUC__
248+
194249
#if !defined(JSONCPP_DEPRECATED)
195250
#define JSONCPP_DEPRECATED(message)
196251
#endif // if !defined(JSONCPP_DEPRECATED)
197252

253+
#if __GNUC__ >= 6
254+
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
255+
#endif
256+
257+
#if !defined(JSON_IS_AMALGAMATION)
258+
259+
# include "version.h"
260+
261+
# if JSONCPP_USING_SECURE_MEMORY
262+
# include "allocator.h" //typedef Allocator
263+
# endif
264+
265+
#endif // if !defined(JSON_IS_AMALGAMATION)
266+
198267
namespace Json {
199268
typedef int Int;
200269
typedef unsigned int UInt;
@@ -208,13 +277,26 @@ typedef unsigned int LargestUInt;
208277
typedef __int64 Int64;
209278
typedef unsigned __int64 UInt64;
210279
#else // if defined(_MSC_VER) // Other platforms, use long long
211-
typedef long long int Int64;
212-
typedef unsigned long long int UInt64;
280+
typedef int64_t Int64;
281+
typedef uint64_t UInt64;
213282
#endif // if defined(_MSC_VER)
214283
typedef Int64 LargestInt;
215284
typedef UInt64 LargestUInt;
216285
#define JSON_HAS_INT64
217286
#endif // if defined(JSON_NO_INT64)
287+
#if JSONCPP_USING_SECURE_MEMORY
288+
#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
289+
#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
290+
#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>
291+
#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
292+
#define JSONCPP_ISTREAM std::istream
293+
#else
294+
#define JSONCPP_STRING std::string
295+
#define JSONCPP_OSTRINGSTREAM std::ostringstream
296+
#define JSONCPP_OSTREAM std::ostream
297+
#define JSONCPP_ISTRINGSTREAM std::istringstream
298+
#define JSONCPP_ISTREAM std::istream
299+
#endif // if JSONCPP_USING_SECURE_MEMORY
218300
} // end namespace Json
219301

220302
#endif // JSON_CONFIG_H_INCLUDED
@@ -295,6 +377,8 @@ class ValueConstIterator;
295377
#include "forwards.h"
296378
#endif // if !defined(JSON_IS_AMALGAMATION)
297379

380+
#pragma pack(push, 8)
381+
298382
namespace Json {
299383

300384
/** \brief Configuration passed to reader and writer.
@@ -329,10 +413,18 @@ class JSON_API Features {
329413
/// \c true if root must be either an array or an object value. Default: \c
330414
/// false.
331415
bool strictRoot_;
416+
417+
/// \c true if dropped null placeholders are allowed. Default: \c false.
418+
bool allowDroppedNullPlaceholders_;
419+
420+
/// \c true if numeric object key are allowed. Default: \c false.
421+
bool allowNumericKeys_;
332422
};
333423

334424
} // namespace Json
335425

426+
#pragma pack(pop)
427+
336428
#endif // CPPTL_JSON_FEATURES_H_INCLUDED
337429

338430
// //////////////////////////////////////////////////////////////////////
@@ -372,15 +464,8 @@ class JSON_API Features {
372464
#include <cpptl/forwards.h>
373465
#endif
374466

375-
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
376-
// be used by...
377-
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
378-
#pragma warning(push)
379-
#pragma warning(disable : 4251)
380-
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
381-
382467
//Conditional NORETURN attribute on the throw functions would:
383-
// a) suppress false positives from static code analysis
468+
// a) suppress false positives from static code analysis
384469
// b) possibly improve optimization opportunities.
385470
#if !defined(JSONCPP_NORETURN)
386471
# if defined(_MSC_VER)
@@ -392,6 +477,15 @@ class JSON_API Features {
392477
# endif
393478
#endif
394479

480+
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
481+
// be used by...
482+
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
483+
#pragma warning(push)
484+
#pragma warning(disable : 4251)
485+
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
486+
487+
#pragma pack(push, 8)
488+
395489
/** \brief JSON (JavaScript Object Notation).
396490
*/
397491
namespace Json {
@@ -402,39 +496,39 @@ namespace Json {
402496
*/
403497
class JSON_API Exception : public std::exception {
404498
public:
405-
Exception(std::string const& msg);
406-
virtual ~Exception() throw();
407-
virtual char const* what() const throw();
499+
Exception(JSONCPP_STRING const& msg);
500+
~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
501+
char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
408502
protected:
409-
std::string const msg_;
503+
JSONCPP_STRING msg_;
410504
};
411505

412506
/** Exceptions which the user cannot easily avoid.
413507
*
414508
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
415-
*
509+
*
416510
* \remark derived from Json::Exception
417511
*/
418512
class JSON_API RuntimeError : public Exception {
419513
public:
420-
RuntimeError(std::string const& msg);
514+
RuntimeError(JSONCPP_STRING const& msg);
421515
};
422516

423517
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
424518
*
425519
* These are precondition-violations (user bugs) and internal errors (our bugs).
426-
*
520+
*
427521
* \remark derived from Json::Exception
428522
*/
429523
class JSON_API LogicError : public Exception {
430524
public:
431-
LogicError(std::string const& msg);
525+
LogicError(JSONCPP_STRING const& msg);
432526
};
433527

434528
/// used internally
435-
JSONCPP_NORETURN void throwRuntimeError(std::string const& msg);
529+
JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
436530
/// used internally
437-
JSONCPP_NORETURN void throwLogicError(std::string const& msg);
531+
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);
438532

439533
/** \brief Type of the value held by a Value object.
440534
*/
@@ -525,7 +619,7 @@ class JSON_API StaticString {
525619
class JSON_API Value {
526620
friend class ValueIteratorBase;
527621
public:
528-
typedef std::vector<std::string> Members;
622+
typedef std::vector<JSONCPP_STRING> Members;
529623
typedef ValueIterator iterator;
530624
typedef ValueConstIterator const_iterator;
531625
typedef Json::UInt UInt;
@@ -538,11 +632,10 @@ class JSON_API Value {
538632
typedef Json::LargestUInt LargestUInt;
539633
typedef Json::ArrayIndex ArrayIndex;
540634

541-
static const Value& nullRef;
542-
#if !defined(__ARMEL__)
543-
/// \deprecated This exists for binary compatibility only. Use nullRef.
544-
static const Value null;
545-
#endif
635+
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
636+
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
637+
static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
638+
546639
/// Minimum signed integer value that can be stored in a Json::Value.
547640
static const LargestInt minLargestInt;
548641
/// Maximum signed integer value that can be stored in a Json::Value.
@@ -578,6 +671,9 @@ class JSON_API Value {
578671
CZString(ArrayIndex index);
579672
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
580673
CZString(CZString const& other);
674+
#if JSON_HAS_RVALUE_REFERENCES
675+
CZString(CZString&& other);
676+
#endif
581677
~CZString();
582678
CZString& operator=(CZString other);
583679
bool operator<(CZString const& other) const;
@@ -653,18 +749,22 @@ Json::Value obj_value(Json::objectValue); // {}
653749
* \endcode
654750
*/
655751
Value(const StaticString& value);
656-
Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too.
752+
Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too.
657753
#ifdef JSON_USE_CPPTL
658754
Value(const CppTL::ConstString& value);
659755
#endif
660756
Value(bool value);
661757
/// Deep copy.
662758
Value(const Value& other);
759+
#if JSON_HAS_RVALUE_REFERENCES
760+
/// Move constructor
761+
Value(Value&& other);
762+
#endif
663763
~Value();
664764

665765
/// Deep copy, then swap(other).
666766
/// \note Over-write existing comments. To preserve comments, use #swapPayload().
667-
Value &operator=(const Value &other);
767+
Value& operator=(Value other);
668768
/// Swap everything.
669769
void swap(Value& other);
670770
/// Swap values but leave comments and source offsets in place.
@@ -682,7 +782,10 @@ Json::Value obj_value(Json::objectValue); // {}
682782
int compare(const Value& other) const;
683783

684784
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
685-
std::string asString() const; ///< Embedded zeroes are possible.
785+
#if JSONCPP_USING_SECURE_MEMORY
786+
unsigned getCStringLength() const; //Allows you to understand the length of the CString
787+
#endif
788+
JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
686789
/** Get raw char* of string-value.
687790
* \return false if !string. (Seg-fault if str or end are NULL.)
688791
*/
@@ -786,11 +889,11 @@ Json::Value obj_value(Json::objectValue); // {}
786889
const Value& operator[](const char* key) const;
787890
/// Access an object value by name, create a null member if it does not exist.
788891
/// \param key may contain embedded nulls.
789-
Value& operator[](const std::string& key);
892+
Value& operator[](const JSONCPP_STRING& key);
790893
/// Access an object value by name, returns null if there is no member with
791894
/// that name.
792895
/// \param key may contain embedded nulls.
793-
const Value& operator[](const std::string& key) const;
896+
const Value& operator[](const JSONCPP_STRING& key) const;
794897
/** \brief Access an object value by name, create a null member if it does not
795898
exist.
796899
@@ -821,7 +924,7 @@ Json::Value obj_value(Json::objectValue); // {}
821924
/// Return the member named key if it exist, defaultValue otherwise.
822925
/// \note deep copy
823926
/// \param key may contain embedded nulls.
824-
Value get(const std::string& key, const Value& defaultValue) const;
927+
Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
825928
#ifdef JSON_USE_CPPTL
826929
/// Return the member named key if it exist, defaultValue otherwise.
827930
/// \note deep copy
@@ -846,7 +949,7 @@ Json::Value obj_value(Json::objectValue); // {}
846949
/// Same as removeMember(const char*)
847950
/// \param key may contain embedded nulls.
848951
/// \deprecated
849-
Value removeMember(const std::string& key);
952+
Value removeMember(const JSONCPP_STRING& key);
850953
/// Same as removeMember(const char* begin, const char* end, Value* removed),
851954
/// but 'key' is null-terminated.
852955
bool removeMember(const char* key, Value* removed);
@@ -856,8 +959,8 @@ Json::Value obj_value(Json::objectValue); // {}
856959
\param key may contain embedded nulls.
857960
\return true iff removed (no exceptions)
858961
*/
859-
bool removeMember(std::string const& key, Value* removed);
860-
/// Same as removeMember(std::string const& key, Value* removed)
962+
bool removeMember(JSONCPP_STRING const& key, Value* removed);
963+
/// Same as removeMember(JSONCPP_STRING const& key, Value* removed)
861964
bool removeMember(const char* begin, const char* end, Value* removed);
862965
/** \brief Remove the indexed array element.
863966
@@ -872,8 +975,8 @@ Json::Value obj_value(Json::objectValue); // {}
872975
bool isMember(const char* key) const;
873976
/// Return true if the object has a member named key.
874977
/// \param key may contain embedded nulls.
875-
bool isMember(const std::string& key) const;
876-
/// Same as isMember(std::string const& key)const
978+
bool isMember(const JSONCPP_STRING& key) const;
979+
/// Same as isMember(JSONCPP_STRING const& key)const
877980
bool isMember(const char* begin, const char* end) const;
878981
#ifdef JSON_USE_CPPTL
879982
/// Return true if the object has a member named key.
@@ -893,24 +996,31 @@ Json::Value obj_value(Json::objectValue); // {}
893996
//# endif
894997

895998
/// \deprecated Always pass len.
896-
JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
999+
JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
8971000
void setComment(const char* comment, CommentPlacement placement);
8981001
/// Comments must be //... or /* ... */
8991002
void setComment(const char* comment, size_t len, CommentPlacement placement);
9001003
/// Comments must be //... or /* ... */
901-
void setComment(const std::string& comment, CommentPlacement placement);
1004+
void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
9021005
bool hasComment(CommentPlacement placement) const;
9031006
/// Include delimiters and embedded newlines.
904-
std::string getComment(CommentPlacement placement) const;
1007+
JSONCPP_STRING getComment(CommentPlacement placement) const;
9051008

906-
std::string toStyledString() const;
1009+
JSONCPP_STRING toStyledString() const;
9071010

9081011
const_iterator begin() const;
9091012
const_iterator end() const;
9101013

9111014
iterator begin();
9121015
iterator end();
9131016

1017+
// Accessors for the [start, limit) range of bytes within the JSON text from
1018+
// which this value was parsed, if any.
1019+
void setOffsetStart(ptrdiff_t start);
1020+
void setOffsetLimit(ptrdiff_t limit);
1021+
ptrdiff_t getOffsetStart() const;
1022+
ptrdiff_t getOffsetLimit() const;
1023+
9141024
private:
9151025
void initBasic(ValueType type, bool allocated = false);
9161026

@@ -947,6 +1057,11 @@ Json::Value obj_value(Json::objectValue); // {}
9471057
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
9481058
// If not allocated_, string_ must be null-terminated.
9491059
CommentInfo* comments_;
1060+
1061+
// [start, limit) byte offsets in the source JSON text from which this Value
1062+
// was extracted.
1063+
ptrdiff_t start_;
1064+
ptrdiff_t limit_;
9501065
};
9511066

9521067
/** \brief Experimental and untested: represents an element of the "path" to
@@ -959,15 +1074,15 @@ class JSON_API PathArgument {
9591074
PathArgument();
9601075
PathArgument(ArrayIndex index);
9611076
PathArgument(const char* key);
962-
PathArgument(const std::string& key);
1077+
PathArgument(const JSONCPP_STRING& key);
9631078

9641079
private:
9651080
enum Kind {
9661081
kindNone = 0,
9671082
kindIndex,
9681083
kindKey
9691084
};
970-
std::string key_;
1085+
JSONCPP_STRING key_;
9711086
ArrayIndex index_;
9721087
Kind kind_;
9731088
};
@@ -985,7 +1100,7 @@ class JSON_API PathArgument {
9851100
*/
9861101
class JSON_API Path {
9871102
public:
988-
Path(const std::string& path,
1103+
Path(const JSONCPP_STRING& path,
9891104
const PathArgument& a1 = PathArgument(),
9901105
const PathArgument& a2 = PathArgument(),
9911106
const PathArgument& a3 = PathArgument(),
@@ -1002,12 +1117,12 @@ class JSON_API Path {
10021117
typedef std::vector<const PathArgument*> InArgs;
10031118
typedef std::vector<PathArgument> Args;
10041119

1005-
void makePath(const std::string& path, const InArgs& in);
1006-
void addPathInArg(const std::string& path,
1120+
void makePath(const JSONCPP_STRING& path, const InArgs& in);
1121+
void addPathInArg(const JSONCPP_STRING& path,
10071122
const InArgs& in,
10081123
InArgs::const_iterator& itInArg,
10091124
PathArgument::Kind kind);
1010-
void invalidPath(const std::string& path, int location);
1125+
void invalidPath(const JSONCPP_STRING& path, int location);
10111126

10121127
Args args_;
10131128
};
@@ -1040,7 +1155,7 @@ class JSON_API ValueIteratorBase {
10401155
/// Return the member name of the referenced Value, or "" if it is not an
10411156
/// objectValue.
10421157
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
1043-
std::string name() const;
1158+
JSONCPP_STRING name() const;
10441159

10451160
/// Return the member name of the referenced Value. "" if it is not an
10461161
/// objectValue.
@@ -1092,6 +1207,7 @@ class JSON_API ValueConstIterator : public ValueIteratorBase {
10921207
typedef ValueConstIterator SelfType;
10931208

10941209
ValueConstIterator();
1210+
ValueConstIterator(ValueIterator const& other);
10951211

10961212
private:
10971213
/*! \internal Use by Value to create an iterator.
@@ -1141,7 +1257,7 @@ class JSON_API ValueIterator : public ValueIteratorBase {
11411257
typedef ValueIterator SelfType;
11421258

11431259
ValueIterator();
1144-
ValueIterator(const ValueConstIterator& other);
1260+
explicit ValueIterator(const ValueConstIterator& other);
11451261
ValueIterator(const ValueIterator& other);
11461262

11471263
private:
@@ -1187,6 +1303,7 @@ template<>
11871303
inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
11881304
}
11891305

1306+
#pragma pack(pop)
11901307

11911308
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
11921309
#pragma warning(pop)
@@ -1232,6 +1349,8 @@ inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
12321349
#pragma warning(disable : 4251)
12331350
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
12341351

1352+
#pragma pack(push, 8)
1353+
12351354
namespace Json {
12361355

12371356
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
@@ -1244,6 +1363,18 @@ class JSON_API Reader {
12441363
typedef char Char;
12451364
typedef const Char* Location;
12461365

1366+
/** \brief An error tagged with where in the JSON text it was encountered.
1367+
*
1368+
* The offsets give the [start, limit) range of bytes within the text. Note
1369+
* that this is bytes, not codepoints.
1370+
*
1371+
*/
1372+
struct StructuredError {
1373+
ptrdiff_t offset_start;
1374+
ptrdiff_t offset_limit;
1375+
JSONCPP_STRING message;
1376+
};
1377+
12471378
/** \brief Constructs a Reader allowing all features
12481379
* for parsing.
12491380
*/
@@ -1296,7 +1427,7 @@ class JSON_API Reader {
12961427

12971428
/// \brief Parse from input stream.
12981429
/// \see Json::operator>>(std::istream&, Json::Value&).
1299-
bool parse(std::istream& is, Value& root, bool collectComments = true);
1430+
bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
13001431

13011432
/** \brief Returns a user friendly string that list errors in the parsed
13021433
* document.
@@ -1308,7 +1439,7 @@ class JSON_API Reader {
13081439
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
13091440
*/
13101441
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
1311-
std::string getFormatedErrorMessages() const;
1442+
JSONCPP_STRING getFormatedErrorMessages() const;
13121443

13131444
/** \brief Returns a user friendly string that list errors in the parsed
13141445
* document.
@@ -1318,7 +1449,39 @@ class JSON_API Reader {
13181449
* occurred
13191450
* during parsing.
13201451
*/
1321-
std::string getFormattedErrorMessages() const;
1452+
JSONCPP_STRING getFormattedErrorMessages() const;
1453+
1454+
/** \brief Returns a vector of structured erros encounted while parsing.
1455+
* \return A (possibly empty) vector of StructuredError objects. Currently
1456+
* only one error can be returned, but the caller should tolerate
1457+
* multiple
1458+
* errors. This can occur if the parser recovers from a non-fatal
1459+
* parse error and then encounters additional errors.
1460+
*/
1461+
std::vector<StructuredError> getStructuredErrors() const;
1462+
1463+
/** \brief Add a semantic error message.
1464+
* \param value JSON Value location associated with the error
1465+
* \param message The error message.
1466+
* \return \c true if the error was successfully added, \c false if the
1467+
* Value offset exceeds the document size.
1468+
*/
1469+
bool pushError(const Value& value, const JSONCPP_STRING& message);
1470+
1471+
/** \brief Add a semantic error message with extra context.
1472+
* \param value JSON Value location associated with the error
1473+
* \param message The error message.
1474+
* \param extra Additional JSON Value location to contextualize the error
1475+
* \return \c true if the error was successfully added, \c false if either
1476+
* Value offset exceeds the document size.
1477+
*/
1478+
bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
1479+
1480+
/** \brief Return whether there are any errors.
1481+
* \return \c true if there are no errors to report \c false if
1482+
* errors have occurred.
1483+
*/
1484+
bool good() const;
13221485

13231486
private:
13241487
enum TokenType {
@@ -1348,7 +1511,7 @@ class JSON_API Reader {
13481511
class ErrorInfo {
13491512
public:
13501513
Token token_;
1351-
std::string message_;
1514+
JSONCPP_STRING message_;
13521515
Location extra_;
13531516
};
13541517

@@ -1368,7 +1531,7 @@ class JSON_API Reader {
13681531
bool decodeNumber(Token& token);
13691532
bool decodeNumber(Token& token, Value& decoded);
13701533
bool decodeString(Token& token);
1371-
bool decodeString(Token& token, std::string& decoded);
1534+
bool decodeString(Token& token, JSONCPP_STRING& decoded);
13721535
bool decodeDouble(Token& token);
13731536
bool decodeDouble(Token& token, Value& decoded);
13741537
bool decodeUnicodeCodePoint(Token& token,
@@ -1379,30 +1542,30 @@ class JSON_API Reader {
13791542
Location& current,
13801543
Location end,
13811544
unsigned int& unicode);
1382-
bool addError(const std::string& message, Token& token, Location extra = 0);
1545+
bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
13831546
bool recoverFromError(TokenType skipUntilToken);
1384-
bool addErrorAndRecover(const std::string& message,
1547+
bool addErrorAndRecover(const JSONCPP_STRING& message,
13851548
Token& token,
13861549
TokenType skipUntilToken);
13871550
void skipUntilSpace();
13881551
Value& currentValue();
13891552
Char getNextChar();
13901553
void
13911554
getLocationLineAndColumn(Location location, int& line, int& column) const;
1392-
std::string getLocationLineAndColumn(Location location) const;
1555+
JSONCPP_STRING getLocationLineAndColumn(Location location) const;
13931556
void addComment(Location begin, Location end, CommentPlacement placement);
13941557
void skipCommentTokens(Token& token);
13951558

13961559
typedef std::stack<Value*> Nodes;
13971560
Nodes nodes_;
13981561
Errors errors_;
1399-
std::string document_;
1562+
JSONCPP_STRING document_;
14001563
Location begin_;
14011564
Location end_;
14021565
Location current_;
14031566
Location lastValueEnd_;
14041567
Value* lastValue_;
1405-
std::string commentsBefore_;
1568+
JSONCPP_STRING commentsBefore_;
14061569
Features features_;
14071570
bool collectComments_;
14081571
}; // Reader
@@ -1431,9 +1594,9 @@ class JSON_API CharReader {
14311594
*/
14321595
virtual bool parse(
14331596
char const* beginDoc, char const* endDoc,
1434-
Value* root, std::string* errs) = 0;
1597+
Value* root, JSONCPP_STRING* errs) = 0;
14351598

1436-
class Factory {
1599+
class JSON_API Factory {
14371600
public:
14381601
virtual ~Factory() {}
14391602
/** \brief Allocate a CharReader via operator new().
@@ -1451,7 +1614,7 @@ class JSON_API CharReader {
14511614
CharReaderBuilder builder;
14521615
builder["collectComments"] = false;
14531616
Value value;
1454-
std::string errs;
1617+
JSONCPP_STRING errs;
14551618
bool ok = parseFromStream(builder, std::cin, &value, &errs);
14561619
\endcode
14571620
*/
@@ -1487,7 +1650,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory {
14871650
- `"rejectDupKeys": false or true`
14881651
- If true, `parse()` returns false when a key is duplicated within an object.
14891652
- `"allowSpecialFloats": false or true`
1490-
- If true, special float values (NaNs and infinities) are allowed
1653+
- If true, special float values (NaNs and infinities) are allowed
14911654
and their values are lossfree restorable.
14921655
14931656
You can examine 'settings_` yourself
@@ -1498,9 +1661,9 @@ class JSON_API CharReaderBuilder : public CharReader::Factory {
14981661
Json::Value settings_;
14991662

15001663
CharReaderBuilder();
1501-
virtual ~CharReaderBuilder();
1664+
~CharReaderBuilder() JSONCPP_OVERRIDE;
15021665

1503-
virtual CharReader* newCharReader() const;
1666+
CharReader* newCharReader() const JSONCPP_OVERRIDE;
15041667

15051668
/** \return true if 'settings' are legal and consistent;
15061669
* otherwise, indicate bad settings via 'invalid'.
@@ -1509,7 +1672,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory {
15091672

15101673
/** A simple way to update a specific setting.
15111674
*/
1512-
Value& operator[](std::string key);
1675+
Value& operator[](JSONCPP_STRING key);
15131676

15141677
/** Called by ctor, but you can use this to reset settings_.
15151678
* \pre 'settings' != NULL (but Json::null is fine)
@@ -1531,7 +1694,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory {
15311694
*/
15321695
bool JSON_API parseFromStream(
15331696
CharReader::Factory const&,
1534-
std::istream&,
1697+
JSONCPP_ISTREAM&,
15351698
Value* root, std::string* errs);
15361699

15371700
/** \brief Read from 'sin' into 'root'.
@@ -1558,10 +1721,12 @@ bool JSON_API parseFromStream(
15581721
\throw std::exception on parse error.
15591722
\see Json::operator<<()
15601723
*/
1561-
JSON_API std::istream& operator>>(std::istream&, Value&);
1724+
JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
15621725

15631726
} // namespace Json
15641727

1728+
#pragma pack(pop)
1729+
15651730
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
15661731
#pragma warning(pop)
15671732
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
@@ -1603,6 +1768,8 @@ JSON_API std::istream& operator>>(std::istream&, Value&);
16031768
#pragma warning(disable : 4251)
16041769
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
16051770

1771+
#pragma pack(push, 8)
1772+
16061773
namespace Json {
16071774

16081775
class Value;
@@ -1622,7 +1789,7 @@ class Value;
16221789
*/
16231790
class JSON_API StreamWriter {
16241791
protected:
1625-
std::ostream* sout_; // not owned; will not delete
1792+
JSONCPP_OSTREAM* sout_; // not owned; will not delete
16261793
public:
16271794
StreamWriter();
16281795
virtual ~StreamWriter();
@@ -1632,7 +1799,7 @@ class JSON_API StreamWriter {
16321799
\return zero on success (For now, we always return zero, so check the stream instead.)
16331800
\throw std::exception possibly, depending on configuration
16341801
*/
1635-
virtual int write(Value const& root, std::ostream* sout) = 0;
1802+
virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
16361803

16371804
/** \brief A simple abstract factory.
16381805
*/
@@ -1649,7 +1816,7 @@ class JSON_API StreamWriter {
16491816
/** \brief Write into stringstream, then return string, for convenience.
16501817
* A StreamWriter will be created from the factory, used, and then deleted.
16511818
*/
1652-
std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
1819+
JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
16531820

16541821

16551822
/** \brief Build a StreamWriter implementation.
@@ -1695,20 +1862,20 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
16951862
Json::Value settings_;
16961863

16971864
StreamWriterBuilder();
1698-
virtual ~StreamWriterBuilder();
1865+
~StreamWriterBuilder() JSONCPP_OVERRIDE;
16991866

17001867
/**
17011868
* \throw std::exception if something goes wrong (e.g. invalid settings)
17021869
*/
1703-
virtual StreamWriter* newStreamWriter() const;
1870+
StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE;
17041871

17051872
/** \return true if 'settings' are legal and consistent;
17061873
* otherwise, indicate bad settings via 'invalid'.
17071874
*/
17081875
bool validate(Json::Value* invalid) const;
17091876
/** A simple way to update a specific setting.
17101877
*/
1711-
Value& operator[](std::string key);
1878+
Value& operator[](JSONCPP_STRING key);
17121879

17131880
/** Called by ctor, but you can use this to reset settings_.
17141881
* \pre 'settings' != NULL (but Json::null is fine)
@@ -1725,7 +1892,7 @@ class JSON_API Writer {
17251892
public:
17261893
virtual ~Writer();
17271894

1728-
virtual std::string write(const Value& root) = 0;
1895+
virtual JSONCPP_STRING write(const Value& root) = 0;
17291896
};
17301897

17311898
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
@@ -1741,18 +1908,29 @@ class JSON_API FastWriter : public Writer {
17411908

17421909
public:
17431910
FastWriter();
1744-
virtual ~FastWriter() {}
1911+
~FastWriter() JSONCPP_OVERRIDE {}
17451912

17461913
void enableYAMLCompatibility();
17471914

1915+
/** \brief Drop the "null" string from the writer's output for nullValues.
1916+
* Strictly speaking, this is not valid JSON. But when the output is being
1917+
* fed to a browser's Javascript, it makes for smaller output and the
1918+
* browser can handle the output just fine.
1919+
*/
1920+
void dropNullPlaceholders();
1921+
1922+
void omitEndingLineFeed();
1923+
17481924
public: // overridden from Writer
1749-
virtual std::string write(const Value& root);
1925+
JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
17501926

17511927
private:
17521928
void writeValue(const Value& value);
17531929

1754-
std::string document_;
1930+
JSONCPP_STRING document_;
17551931
bool yamlCompatiblityEnabled_;
1932+
bool dropNullPlaceholders_;
1933+
bool omitEndingLineFeed_;
17561934
};
17571935

17581936
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
@@ -1782,36 +1960,36 @@ class JSON_API FastWriter : public Writer {
17821960
class JSON_API StyledWriter : public Writer {
17831961
public:
17841962
StyledWriter();
1785-
virtual ~StyledWriter() {}
1963+
~StyledWriter() JSONCPP_OVERRIDE {}
17861964

17871965
public: // overridden from Writer
17881966
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
17891967
* \param root Value to serialize.
17901968
* \return String containing the JSON document that represents the root value.
17911969
*/
1792-
virtual std::string write(const Value& root);
1970+
JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
17931971

17941972
private:
17951973
void writeValue(const Value& value);
17961974
void writeArrayValue(const Value& value);
17971975
bool isMultineArray(const Value& value);
1798-
void pushValue(const std::string& value);
1976+
void pushValue(const JSONCPP_STRING& value);
17991977
void writeIndent();
1800-
void writeWithIndent(const std::string& value);
1978+
void writeWithIndent(const JSONCPP_STRING& value);
18011979
void indent();
18021980
void unindent();
18031981
void writeCommentBeforeValue(const Value& root);
18041982
void writeCommentAfterValueOnSameLine(const Value& root);
18051983
bool hasCommentForValue(const Value& value);
1806-
static std::string normalizeEOL(const std::string& text);
1984+
static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
18071985

1808-
typedef std::vector<std::string> ChildValues;
1986+
typedef std::vector<JSONCPP_STRING> ChildValues;
18091987

18101988
ChildValues childValues_;
1811-
std::string document_;
1812-
std::string indentString_;
1813-
int rightMargin_;
1814-
int indentSize_;
1989+
JSONCPP_STRING document_;
1990+
JSONCPP_STRING indentString_;
1991+
unsigned int rightMargin_;
1992+
unsigned int indentSize_;
18151993
bool addChildValues_;
18161994
};
18171995

@@ -1843,7 +2021,7 @@ class JSON_API StyledWriter : public Writer {
18432021
*/
18442022
class JSON_API StyledStreamWriter {
18452023
public:
1846-
StyledStreamWriter(std::string indentation = "\t");
2024+
StyledStreamWriter(JSONCPP_STRING indentation = "\t");
18472025
~StyledStreamWriter() {}
18482026

18492027
public:
@@ -1853,49 +2031,51 @@ class JSON_API StyledStreamWriter {
18532031
* \note There is no point in deriving from Writer, since write() should not
18542032
* return a value.
18552033
*/
1856-
void write(std::ostream& out, const Value& root);
2034+
void write(JSONCPP_OSTREAM& out, const Value& root);
18572035

18582036
private:
18592037
void writeValue(const Value& value);
18602038
void writeArrayValue(const Value& value);
18612039
bool isMultineArray(const Value& value);
1862-
void pushValue(const std::string& value);
2040+
void pushValue(const JSONCPP_STRING& value);
18632041
void writeIndent();
1864-
void writeWithIndent(const std::string& value);
2042+
void writeWithIndent(const JSONCPP_STRING& value);
18652043
void indent();
18662044
void unindent();
18672045
void writeCommentBeforeValue(const Value& root);
18682046
void writeCommentAfterValueOnSameLine(const Value& root);
18692047
bool hasCommentForValue(const Value& value);
1870-
static std::string normalizeEOL(const std::string& text);
2048+
static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
18712049

1872-
typedef std::vector<std::string> ChildValues;
2050+
typedef std::vector<JSONCPP_STRING> ChildValues;
18732051

18742052
ChildValues childValues_;
1875-
std::ostream* document_;
1876-
std::string indentString_;
1877-
int rightMargin_;
1878-
std::string indentation_;
2053+
JSONCPP_OSTREAM* document_;
2054+
JSONCPP_STRING indentString_;
2055+
unsigned int rightMargin_;
2056+
JSONCPP_STRING indentation_;
18792057
bool addChildValues_ : 1;
18802058
bool indented_ : 1;
18812059
};
18822060

18832061
#if defined(JSON_HAS_INT64)
1884-
std::string JSON_API valueToString(Int value);
1885-
std::string JSON_API valueToString(UInt value);
2062+
JSONCPP_STRING JSON_API valueToString(Int value);
2063+
JSONCPP_STRING JSON_API valueToString(UInt value);
18862064
#endif // if defined(JSON_HAS_INT64)
1887-
std::string JSON_API valueToString(LargestInt value);
1888-
std::string JSON_API valueToString(LargestUInt value);
1889-
std::string JSON_API valueToString(double value);
1890-
std::string JSON_API valueToString(bool value);
1891-
std::string JSON_API valueToQuotedString(const char* value);
2065+
JSONCPP_STRING JSON_API valueToString(LargestInt value);
2066+
JSONCPP_STRING JSON_API valueToString(LargestUInt value);
2067+
JSONCPP_STRING JSON_API valueToString(double value);
2068+
JSONCPP_STRING JSON_API valueToString(bool value);
2069+
JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
18922070

18932071
/// \brief Output using the StyledStreamWriter.
18942072
/// \see Json::operator>>()
1895-
JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
2073+
JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
18962074

18972075
} // namespace Json
18982076

2077+
#pragma pack(pop)
2078+
18992079
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
19002080
#pragma warning(pop)
19012081
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
@@ -1942,7 +2122,7 @@ JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
19422122

19432123
# define JSON_FAIL_MESSAGE(message) \
19442124
{ \
1945-
std::ostringstream oss; oss << message; \
2125+
JSONCPP_OSTRINGSTREAM oss; oss << message; \
19462126
Json::throwLogicError(oss.str()); \
19472127
abort(); \
19482128
}
@@ -1955,7 +2135,7 @@ JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
19552135
// release builds we abort, for a core-dump or debugger.
19562136
# define JSON_FAIL_MESSAGE(message) \
19572137
{ \
1958-
std::ostringstream oss; oss << message; \
2138+
JSONCPP_OSTRINGSTREAM oss; oss << message; \
19592139
assert(false && oss.str().c_str()); \
19602140
abort(); \
19612141
}

‎lib/jsoncpp/jsoncpp.cpp

+697-323
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.