/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/). /// It is intended to be used with #include "json/json.h" // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: LICENSE // ////////////////////////////////////////////////////////////////////// /* The JsonCpp library's source code, including accompanying documentation, tests and demonstration applications, are licensed under the following conditions... Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all jurisdictions which recognize such a disclaimer. In such jurisdictions, this software is released into the Public Domain. In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and The JsonCpp Authors, and is released under the terms of the MIT License (see below). In jurisdictions which recognize Public Domain property, the user of this software may choose to accept it either as 1) Public Domain, 2) under the 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 and The JsonCpp Authors 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. */ // ////////////////////////////////////////////////////////////////////// // End of content of file: LICENSE // ////////////////////////////////////////////////////////////////////// #ifndef JSON_AMALGAMATED_H_INCLUDED # define JSON_AMALGAMATED_H_INCLUDED /// If defined, indicates that the source file is amalgamated /// to prevent private header inclusion. #define JSON_IS_AMALGAMATION // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/version.h // ////////////////////////////////////////////////////////////////////// #ifndef JSON_VERSION_H_INCLUDED #define JSON_VERSION_H_INCLUDED // Note: version must be updated in three places when doing a release. This // annoying process ensures that amalgamate, CMake, and meson all report the // correct version. // 1. /meson.build // 2. /include/json/version.h // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! #define JSONCPP_VERSION_STRING "1.9.4" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 #define JSONCPP_VERSION_PATCH 3 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ (JSONCPP_VERSION_PATCH << 8)) #ifdef JSONCPP_USING_SECURE_MEMORY #undef JSONCPP_USING_SECURE_MEMORY #endif #define JSONCPP_USING_SECURE_MEMORY 0 // If non-zero, the library zeroes any memory that it has allocated before // it frees its memory. #endif // JSON_VERSION_H_INCLUDED // ////////////////////////////////////////////////////////////////////// // End of content of file: include/json/version.h // ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/allocator.h // ////////////////////////////////////////////////////////////////////// // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #ifndef JSON_ALLOCATOR_H_INCLUDED #define JSON_ALLOCATOR_H_INCLUDED #include #include #pragma pack(push, 8) namespace Json { template class SecureAllocator { public: // Type definitions using value_type = T; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using size_type = std::size_t; using difference_type = std::ptrdiff_t; /** * Allocate memory for N items using the standard allocator. */ pointer allocate(size_type n) { // allocate using "global operator new" return static_cast(::operator new(n * sizeof(T))); } /** * Release memory which was allocated for N items at pointer P. * * The memory block is filled with zeroes before being released. * The pointer argument is tagged as "volatile" to prevent the * compiler optimizing out this critical step. */ void deallocate(volatile pointer p, size_type n) { std::memset(p, 0, n * sizeof(T)); // free using "global operator delete" ::operator delete(p); } /** * Construct an item in-place at pointer P. */ template void construct(pointer p, Args&&... args) { // construct using "placement new" and "perfect forwarding" ::new (static_cast(p)) T(std::forward(args)...); } size_type max_size() const { return size_t(-1) / sizeof(T); } pointer address(reference x) const { return std::addressof(x); } const_pointer address(const_reference x) const { return std::addressof(x); } /** * Destroy an item in-place at pointer P. */ void destroy(pointer p) { // destroy using "explicit destructor" p->~T(); } // Boilerplate SecureAllocator() {} template SecureAllocator(const SecureAllocator&) {} template struct rebind { using other = SecureAllocator; }; }; template bool operator==(const SecureAllocator&, const SecureAllocator&) { return true; } template bool operator!=(const SecureAllocator&, const SecureAllocator&) { return false; } } // namespace Json #pragma pack(pop) #endif // JSON_ALLOCATOR_H_INCLUDED // ////////////////////////////////////////////////////////////////////// // End of content of file: include/json/allocator.h // ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/config.h // ////////////////////////////////////////////////////////////////////// // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #ifndef JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED #include #include #include #include #include #include #include #include // If non-zero, the library uses exceptions to report bad input instead of C // assertion macros. The default is to use exceptions. #ifndef JSON_USE_EXCEPTION #define JSON_USE_EXCEPTION 1 #endif // Temporary, tracked for removal with issue #982. #ifndef JSON_USE_NULLREF #define JSON_USE_NULLREF 1 #endif /// If defined, indicates that the source file is amalgamated /// to prevent private header inclusion. /// Remarks: it is automatically defined in the generated amalgamated header. // #define JSON_IS_AMALGAMATION // Export macros for DLL visibility #if defined(JSON_DLL_BUILD) #if defined(_MSC_VER) || defined(__MINGW32__) #define JSON_API __declspec(dllexport) #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING #elif defined(__GNUC__) || defined(__clang__) #define JSON_API __attribute__((visibility("default"))) #endif // if defined(_MSC_VER) #elif defined(JSON_DLL) #if defined(_MSC_VER) || defined(__MINGW32__) #define JSON_API __declspec(dllimport) #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING #endif // if defined(_MSC_VER) #endif // ifdef JSON_DLL_BUILD #if !defined(JSON_API) #define JSON_API #endif #if defined(_MSC_VER) && _MSC_VER < 1800 #error \ "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" #endif #if defined(_MSC_VER) && _MSC_VER < 1900 // As recommended at // https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define jsoncpp_snprintf msvc_pre1900_c99_snprintf #else #define jsoncpp_snprintf std::snprintf #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 // JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. // C++11 should be used directly in JSONCPP. #define JSONCPP_OVERRIDE override #ifdef __clang__ #if __has_extension(attribute_deprecated_with_message) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #endif #elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) #endif // GNUC version #elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates // MSVC) #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) #endif // __clang__ || __GNUC__ || _MSC_VER #if !defined(JSONCPP_DEPRECATED) #define JSONCPP_DEPRECATED(message) #endif // if !defined(JSONCPP_DEPRECATED) #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6)) #define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif #if !defined(JSON_IS_AMALGAMATION) #include "allocator.h" #include "version.h" #endif // if !defined(JSON_IS_AMALGAMATION) namespace Json { using Int = int; using UInt = unsigned int; #if defined(JSON_NO_INT64) using LargestInt = int; using LargestUInt = unsigned int; #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 using Int64 = __int64; using UInt64 = unsigned __int64; #else // if defined(_MSC_VER) // Other platforms, use long long using Int64 = int64_t; using UInt64 = uint64_t; #endif // if defined(_MSC_VER) using LargestInt = Int64; using LargestUInt = UInt64; #define JSON_HAS_INT64 #endif // if defined(JSON_NO_INT64) template using Allocator = typename std::conditional, std::allocator>::type; using String = std::basic_string-- Test Nodes: Node property tests local S = minetest.get_translator("testnodes") -- Is supposed to fall when it doesn't rest on solid ground minetest.register_node("testnodes:falling", { description = S("Falling Node"), tiles = { "testnodes_node.png", "testnodes_node.png", "testnodes_node_falling.png", }, groups = { falling_node = 1, dig_immediate = 3 }, }) -- Same as falling node, but will stop falling on top of liquids minetest.register_node("testnodes:falling_float", { description = S("Falling+Floating Node"), groups = { falling_node = 1, float = 1, dig_immediate = 3 }, tiles = { "testnodes_node.png", "testnodes_node.png", "testnodes_node_falling.png", }, color = "cyan", }) -- This node attaches to the floor and drops as item -- when the floor is gone. minetest.register_node("testnodes:attached", { description = S("Floor-Attached Node"), tiles = { "testnodes_attached_top.png", "testnodes_attached_bottom.png", "testnodes_attached_side.png", }, groups = { attached_node = 1, dig_immediate = 3 }, }) -- This node attaches to the side of a node and drops as item -- when the node it attaches to is gone. minetest.register_node("testnodes:attached_wallmounted", { description = S("Wallmounted Attached Node"), paramtype2 = "wallmounted", tiles = { "testnodes_attachedw_top.png", "testnodes_attachedw_bottom.png", "testnodes_attachedw_side.png", }, groups = { attached_node = 1, dig_immediate = 3 }, }) -- Jump disabled minetest.register_node("testnodes:nojump", { description = S("Non-jumping Node"), groups = {disable_jump=1, dig_immediate=3}, tiles = {"testnodes_nojump_top.png", "testnodes_nojump_side.png"}, }) -- Jump disabled plant minetest.register_node("testnodes:nojump_walkable", { description = S("Non-jumping Plant Node"), drawtype = "plantlike", groups = {disable_jump=1, dig_immediate=3}, walkable = false, tiles = {"testnodes_nojump_top.png"}, }) -- Climbable up and down with jump and sneak keys minetest.register_node("testnodes:climbable", { description = S("Climbable Node"), climbable = true, walkable = false, paramtype = "light", sunlight_propagates = true, is_ground_content = false, tiles ={"testnodes_climbable_side.png"}, drawtype = "glasslike", groups = {dig_immediate=3}, }) -- Climbable only downwards with sneak key minetest.register_node("testnodes:climbable_nojump", { description = S("Downwards-climbable Node"), climbable = true, walkable = false, groups = {disable_jump=1, dig_immediate=3}, drawtype = "glasslike", tiles ={"testnodes_climbable_nojump_side.png"}, paramtype = "light", sunlight_propagates = true, }) -- A liquid in which you can't rise minetest.register_node("testnodes:liquid_nojump", { description = S("Non-jumping Liquid Source Node"), liquidtype = "source", liquid_range = 1, liquid_viscosity = 0, liquid_alternative_flowing = "testnodes:liquidflowing_nojump", liquid_alternative_source = "testnodes:liquid_nojump", liquid_renewable = false, groups = {disable_jump=1, dig_immediate=3}, walkable = false, drawtype = "liquid", tiles = {"testnodes_liquidsource.png^[colorize:#FF0000:127"}, special_tiles = { {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = false}, {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = true}, }, use_texture_alpha = "blend", paramtype = "light", pointable = false, liquids_pointable = true, buildable_to = true, is_ground_content = false, post_effect_color = {a = 70, r = 255, g = 0, b = 200}, }) -- A liquid in which you can't rise (flowing variant) minetest.register_node("testnodes:liquidflowing_nojump", { description = S("Non-jumping Flowing Liquid Node"), liquidtype = "flowing", liquid_range = 1, liquid_viscosity = 0, liquid_alternative_flowing = "testnodes:liquidflowing_nojump", liquid_alternative_source = "testnodes:liquid_nojump", liquid_renewable = false, groups = {disable_jump=1, dig_immediate=3}, walkable = false, drawtype = "flowingliquid", tiles = {"testnodes_liquidflowing.png^[colorize:#FF0000:127"}, special_tiles = { {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false}, {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false}, }, use_texture_alpha = "blend", paramtype = "light", paramtype2 = "flowingliquid", pointable = false, liquids_pointable = true, buildable_to = true, is_ground_content = false, post_effect_color = {a = 70, r = 255, g = 0, b = 200}, }) -- Nodes that modify fall damage (various damage modifiers) for i=-100, 100, 25 do if i ~= 0 then local subname, descnum if i < 0 then subname = "m"..math.abs(i) descnum = tostring(i) else subname = tostring(i) descnum = S("+@1", i) end local tex, color, desc if i > 0 then local val = math.floor((i/100)*255) tex = "testnodes_fall_damage_plus.png" color = { b=0, g=255-val, r=255, a=255 } desc = S("Fall Damage Node (+@1%)", i) else tex = "testnodes_fall_damage_minus.png" if i == -100 then color = { r=0, b=0, g=255, a=255 } else local val = math.floor((math.abs(i)/100)*255) color = { r=0, b=255, g=255-val, a=255 } end desc = S("Fall Damage Node (-@1%)", math.abs(i)) end minetest.register_node("testnodes:damage"..subname, { description = desc, groups = {fall_damage_add_percent=i, dig_immediate=3}, tiles = { tex }, is_ground_content = false, color = color, }) end end -- Bouncy nodes (various bounce levels) for i=20, 180, 20 do local val = math.floor(((i-20)/200)*255) minetest.register_node("testnodes:bouncy"..i, { description = S("Bouncy Node (@1%)", i), groups = {bouncy=i, dig_immediate=3}, tiles ={"testnodes_bouncy.png"}, is_ground_content = false, color = { r=255, g=255-val, b=val, a=255 }, }) end -- Slippery nodes (various slippery levels) for i=1, 5 do minetest.register_node("testnodes:slippery"..i, { description = S("Slippery Node (@1)", i), tiles ={"testnodes_slippery.png"}, is_ground_content = false, groups = {slippery=i, dig_immediate=3}, color = { r=0, g=255, b=math.floor((i/5)*255), a=255 }, }) end -- By placing something on the node, the node itself will be replaced minetest.register_node("testnodes:buildable_to", { description = S("Replacable Node"), buildable_to = true, tiles = {"testnodes_buildable_to.png"}, is_ground_content = false, groups = {dig_immediate=3}, }) -- Nodes that deal damage to players that are inside them. -- Negative damage nodes should heal. for d=-3,3 do if d ~= 0 then local sub, tile if d > 0 then sub = tostring(d) tile = "testnodes_damage.png" else sub = "m" .. tostring(math.abs(d)) tile = "testnodes_damage_neg.png" end if math.abs(d) == 2 then tile = tile .. "^[colorize:#000000:70" elseif math.abs(d) == 3 then tile = tile .. "^[colorize:#000000:140" end minetest.register_node("testnodes:damage_"..sub, { description = S("Damage Node (@1 damage per second)", d), damage_per_second = d, walkable = false, is_ground_content = false, drawtype = "allfaces", paramtype = "light", sunlight_propagates = true, tiles = { tile }, groups = {dig_immediate=3}, }) end end -- Causes drowning damage minetest.register_node("testnodes:drowning_1", { description = S("Drowning Node (@1 damage)", 1), drowning = 1, walkable = false, is_ground_content = false, drawtype = "allfaces", paramtype = "light", sunlight_propagates = true, tiles = { "testnodes_drowning.png" }, groups = {dig_immediate=3}, }) alue; public: using value_type = Value; using size_t = unsigned int; using difference_type = int; using reference = Value&; using pointer = Value*; using SelfType = ValueIterator; ValueIterator(); explicit ValueIterator(const ValueConstIterator& other); ValueIterator(const ValueIterator& other); private: /*! \internal Use by Value to create an iterator. */ explicit ValueIterator(const Value::ObjectValues::iterator& current); public: SelfType& operator=(const SelfType& other); SelfType operator++(int) { SelfType temp(*this); ++*this; return temp; } SelfType operator--(int) { SelfType temp(*this); --*this; return temp; } SelfType& operator--() { decrement(); return *this; } SelfType& operator++() { increment(); return *this; } /*! The return value of non-const iterators can be * changed, so the these functions are not const * because the returned references/pointers can be used * to change state of the base class. */ reference operator*() { return deref(); } pointer operator->() { return &deref(); } }; inline void swap(Value& a, Value& b) { a.swap(b); } } // namespace Json #pragma pack(pop) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma warning(pop) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // JSON_H_INCLUDED // ////////////////////////////////////////////////////////////////////// // End of content of file: include/json/value.h // ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/reader.h // ////////////////////////////////////////////////////////////////////// // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #ifndef JSON_READER_H_INCLUDED #define JSON_READER_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "json_features.h" #include "value.h" #endif // if !defined(JSON_IS_AMALGAMATION) #include #include #include #include #include // Disable warning C4251: : needs to have dll-interface to // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma warning(push) #pragma warning(disable : 4251) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma pack(push, 8) namespace Json { /** \brief Unserialize a JSON document into a * Value. * * \deprecated Use CharReader and CharReaderBuilder. */ class JSONCPP_DEPRECATED( "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { public: using Char = char; using Location = const Char*; /** \brief An error tagged with where in the JSON text it was encountered. * * The offsets give the [start, limit) range of bytes within the text. Note * that this is bytes, not codepoints. */ struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; String message; }; /** \brief Constructs a Reader allowing all features for parsing. */ JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set for parsing. */ JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON * document. * * \param document UTF-8 encoded string containing the document * to read. * \param[out] root 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 serialization, \c false to * discard comments. This parameter is ignored * if Features::allowComments_ is \c false. * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ bool parse(const std::string& document, Value& root, bool collectComments = true); /** \brief Read a Value from a JSON * 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[out] root 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 serialization, \c false to * discard comments. This parameter is ignored * if Features::allowComments_ is \c false. * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); /// \brief Parse from input stream. /// \see Json::operator>>(std::istream&, Json::Value&). bool parse(IStream& is, Value& root, bool collectComments = true); /** \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. * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") 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. */ String getFormattedErrorMessages() const; /** \brief Returns a vector of structured errors encountered while parsing. * * \return A (possibly empty) vector of StructuredError objects. Currently * only one error can be returned, but the caller should tolerate multiple * errors. This can occur if the parser recovers from a non-fatal parse * error and then encounters additional errors. */ std::vector getStructuredErrors() const; /** \brief Add a semantic error message. * * \param value JSON Value location associated with the error * \param message The error message. * \return \c true if the error was successfully added, \c false if the Value * offset exceeds the document size. */ bool pushError(const Value& value, const String& message); /** \brief Add a semantic error message with extra context. * * \param value JSON Value location associated with the error * \param message The error message. * \param extra Additional JSON Value location to contextualize the error * \return \c true if the error was successfully added, \c false if either * Value offset exceeds the document size. */ bool pushError(const Value& value, const String& message, const Value& extra); /** \brief Return whether there are any errors. * * \return \c true if there are no errors to report \c false if errors have * occurred. */ bool good() const; private: enum TokenType { tokenEndOfStream = 0, tokenObjectBegin, tokenObjectEnd, tokenArrayBegin, tokenArrayEnd, tokenString, tokenNumber, tokenTrue, tokenFalse, tokenNull, tokenArraySeparator, tokenMemberSeparator, tokenComment, tokenError }; class Token { public: TokenType type_; Location start_; Location end_; }; class ErrorInfo { public: Token token_; String message_; Location extra_; }; using Errors = std::deque; bool readToken(Token& token); void skipSpaces(); bool match(const Char* pattern, int patternLength); bool readComment(); bool readCStyleComment(); bool readCppStyleComment(); bool readString(); void readNumber(); bool readValue(); bool readObject(Token& token); bool readArray(Token& token); bool decodeNumber(Token& token); bool decodeNumber(Token& token, Value& decoded); bool decodeString(Token& token); bool decodeString(Token& token, String& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, unsigned int& unicode); bool decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, unsigned int& unicode); bool addError(const String& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); Value& currentValue(); Char getNextChar(); void getLocationLineAndColumn(Location location, int& line, int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); using Nodes = std::stack; Nodes nodes_; Errors errors_; String document_; Location begin_{}; Location end_{}; Location current_{}; Location lastValueEnd_{}; Value* lastValue_{}; String commentsBefore_; Features features_; bool collectComments_{}; }; // Reader /** Interface for reading JSON from a char array. */ class JSON_API CharReader { public: virtual ~CharReader() = default; /** \brief Read a Value from a JSON * document. The document must be a UTF-8 encoded string containing the * document to read. * * \param beginDoc Pointer on the beginning of the UTF-8 encoded string * of the document to read. * \param endDoc Pointer on the end of the UTF-8 encoded string of the * document to read. Must be >= beginDoc. * \param[out] root Contains the root value of the document if it was * successfully parsed. * \param[out] errs Formatted error messages (if not NULL) a user * friendly string that lists errors in the parsed * document. * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, String* errs) = 0; class JSON_API Factory { public: virtual ~Factory() = default; /** \brief Allocate a CharReader via operator new(). * \throw std::exception if something goes wrong (e.g. invalid settings) */ virtual CharReader* newCharReader() const = 0; }; // Factory }; // CharReader /** \brief Build a CharReader implementation. * * Usage: * \code * using namespace Json; * CharReaderBuilder builder; * builder["collectComments"] = false; * Value value; * String errs; * bool ok = parseFromStream(builder, std::cin, &value, &errs); * \endcode */ class JSON_API CharReaderBuilder : public CharReader::Factory { public: // Note: We use a Json::Value so that we can add data-members to this class // without a major version bump. /** Configuration of this builder. * These are case-sensitive. * Available settings (case-sensitive): * - `"collectComments": false or true` * - true to collect comment and allow writing them back during * serialization, false to discard comments. This parameter is ignored * if allowComments is false. * - `"allowComments": false or true` * - true if comments are allowed. * - `"allowTrailingCommas": false or true` * - true if trailing commas in objects and arrays are allowed. * - `"strictRoot": false or true` * - true if root must be either an array or an object value * - `"allowDroppedNullPlaceholders": false or true` * - true if dropped null placeholders are allowed. (See * StreamWriterBuilder.) * - `"allowNumericKeys": false or true` * - true if numeric object keys are allowed. * - `"allowSingleQuotes": false or true` * - true if '' are allowed for strings (both keys and values) * - `"stackLimit": integer` * - Exceeding stackLimit (recursive depth of `readValue()`) will cause an * exception. * - This is a security issue (seg-faults caused by deeply nested JSON), so * the default is low. * - `"failIfExtra": false or true` * - If true, `parse()` returns false when extra non-whitespace trails the * JSON value in the input string. * - `"rejectDupKeys": false or true` * - If true, `parse()` returns false when a key is duplicated within an * object. * - `"allowSpecialFloats": false or true` * - If true, special float values (NaNs and infinities) are allowed and * their values are lossfree restorable. * * You can examine 'settings_` yourself to see the defaults. You can also * write and read them just like any JSON Value. * \sa setDefaults() */ Json::Value settings_; CharReaderBuilder(); ~CharReaderBuilder() override; CharReader* newCharReader() const override; /** \return true if 'settings' are legal and consistent; * otherwise, indicate bad settings via 'invalid'. */ bool validate(Json::Value* invalid) const; /** A simple way to update a specific setting. */ Value& operator[](const String& key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) * \remark Defaults: * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults */ static void setDefaults(Json::Value* settings); /** Same as old Features::strictMode(). * \pre 'settings' != NULL (but Json::null is fine) * \remark Defaults: * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode */ static void strictMode(Json::Value* settings); }; /** Consume entire stream and use its begin/end. * Someday we might have a real StreamReader, but for now this * is convenient. */ bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root, String* errs); /** \brief Read from 'sin' into 'root'. * * Always keep comments from the input JSON. * * This can be used to read a file into a particular sub-object. * For example: * \code * Json::Value root; * cin >> root["dir"]["file"]; * cout << root; * \endcode * Result: * \verbatim * { * "dir": { * "file": { * // The input stream JSON would be nested here. * } * } * } * \endverbatim * \throw std::exception on parse error. * \see Json::operator<<() */ JSON_API IStream& operator>>(IStream&, Value&); } // namespace Json #pragma pack(pop) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma warning(pop) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // JSON_READER_H_INCLUDED // ////////////////////////////////////////////////////////////////////// // End of content of file: include/json/reader.h // ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/writer.h // ////////////////////////////////////////////////////////////////////// // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #ifndef JSON_WRITER_H_INCLUDED #define JSON_WRITER_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "value.h" #endif // if !defined(JSON_IS_AMALGAMATION) #include #include #include // Disable warning C4251: : needs to have dll-interface to // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4251) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma pack(push, 8) namespace Json { class Value; /** * * Usage: * \code * using namespace Json; * void writeToStdout(StreamWriter::Factory const& factory, Value const& value) * { std::unique_ptr const writer( factory.newStreamWriter()); * writer->write(value, &std::cout); * std::cout << std::endl; // add lf and flush * } * \endcode */ class JSON_API StreamWriter { protected: OStream* sout_; // not owned; will not delete public: StreamWriter(); virtual ~StreamWriter(); /** Write Value into document as configured in sub-class. * Do not take ownership of sout, but maintain a reference during function. * \pre sout != NULL * \return zero on success (For now, we always return zero, so check the * stream instead.) \throw std::exception possibly, depending on * configuration */ virtual int write(Value const& root, OStream* sout) = 0; /** \brief A simple abstract factory. */ class JSON_API Factory { public: virtual ~Factory(); /** \brief Allocate a CharReader via operator new(). * \throw std::exception if something goes wrong (e.g. invalid settings) */ virtual StreamWriter* newStreamWriter() const = 0; }; // Factory }; // StreamWriter /** \brief Write into stringstream, then return string, for convenience. * A StreamWriter will be created from the factory, used, and then deleted. */ String JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); /** \brief Build a StreamWriter implementation. * Usage: * \code * using namespace Json; * Value value = ...; * StreamWriterBuilder builder; * builder["commentStyle"] = "None"; * builder["indentation"] = " "; // or whatever you like * std::unique_ptr writer( * builder.newStreamWriter()); * writer->write(value, &std::cout); * std::cout << std::endl; // add lf and flush * \endcode */ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { public: // Note: We use a Json::Value so that we can add data-members to this class // without a major version bump. /** Configuration of this builder. * Available settings (case-sensitive): * - "commentStyle": "None" or "All" * - "indentation": "". * - Setting this to an empty string also omits newline characters. * - "enableYAMLCompatibility": false or true * - slightly change the whitespace around colons * - "dropNullPlaceholders": false or true * - Drop the "null" string from the writer's output for nullValues. * Strictly speaking, this is not valid JSON. But when the output is being * fed to a browser's JavaScript, it makes for smaller output and the * browser can handle the output just fine. * - "useSpecialFloats": false or true * - If true, outputs non-finite floating point values in the following way: * NaN values as "NaN", positive infinity as "Infinity", and negative * infinity as "-Infinity". * - "precision": int * - Number of precision digits for formatting of real values. * - "precisionType": "significant"(default) or "decimal" * - Type of precision for formatting of real values. * You can examine 'settings_` yourself * to see the defaults. You can also write and read them just like any * JSON Value. * \sa setDefaults() */ Json::Value settings_; StreamWriterBuilder(); ~StreamWriterBuilder() override; /** * \throw std::exception if something goes wrong (e.g. invalid settings) */ StreamWriter* newStreamWriter() const override; /** \return true if 'settings' are legal and consistent; * otherwise, indicate bad settings via 'invalid'. */ bool validate(Json::Value* invalid) const; /** A simple way to update a specific setting. */ Value& operator[](const String& key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) * \remark Defaults: * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults */ static void setDefaults(Json::Value* settings); }; /** \brief Abstract class for writers. * \deprecated Use StreamWriter. (And really, this is an implementation detail.) */ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { public: virtual ~Writer(); virtual String write(const Value& root) = 0; }; /** \brief Outputs a Value in JSON format *without formatting (not human friendly). * * The JSON document is written in a single line. It is not intended for 'human' *consumption, * but may be useful to support feature such as RPC where bandwidth is limited. * \sa Reader, Value * \deprecated Use StreamWriterBuilder. */ #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { public: FastWriter(); ~FastWriter() override = default; void enableYAMLCompatibility(); /** \brief Drop the "null" string from the writer's output for nullValues. * Strictly speaking, this is not valid JSON. But when the output is being * fed to a browser's JavaScript, it makes for smaller output and the * browser can handle the output just fine. */ void dropNullPlaceholders(); void omitEndingLineFeed(); public: // overridden from Writer String write(const Value& root) override; private: void writeValue(const Value& value); String document_; bool yamlCompatibilityEnabled_{false}; bool dropNullPlaceholders_{false}; bool omitEndingLineFeed_{false}; }; #if defined(_MSC_VER) #pragma warning(pop) #endif /** \brief Writes a Value in JSON format in a *human friendly way. * * The rules for line break and indent are as follow: * - Object value: * - if empty then print {} without indent and line break * - if not empty the print '{', line break & indent, print one value per *line * and then unindent and line break and print '}'. * - Array value: * - if empty then print [] without indent and line break * - if the array contains no object value, empty array or some other value *types, * and all the values fit on one lines, then print the array on a single *line. * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * * If the Value have comments then they are outputed according to their *#CommentPlacement. * * \sa Reader, Value, Value::setComment() * \deprecated Use StreamWriterBuilder. */ #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { public: StyledWriter(); ~StyledWriter() override = default; public: // overridden from Writer /** \brief Serialize a Value in JSON format. * \param root Value to serialize. * \return String containing the JSON document that represents the root value. */ String write(const Value& root) override; private: void writeValue(const Value& value); void writeArrayValue(const Value& value); bool isMultilineArray(const Value& value); void pushValue(const String& value); void writeIndent(); void writeWithIndent(const String& value); void indent(); void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); static bool hasCommentForValue(const Value& value); static String normalizeEOL(const String& text); using ChildValues = std::vector; ChildValues childValues_; String document_; String indentString_; unsigned int rightMargin_{74}; unsigned int indentSize_{3}; bool addChildValues_{false}; }; #if defined(_MSC_VER) #pragma warning(pop) #endif /** \brief Writes a Value in JSON format in a human friendly way, to a stream rather than to a string. * * The rules for line break and indent are as follow: * - Object value: * - if empty then print {} without indent and line break * - if not empty the print '{', line break & indent, print one value per line * and then unindent and line break and print '}'. * - Array value: * - if empty then print [] without indent and line break * - if the array contains no object value, empty array or some other value types, * and all the values fit on one lines, then print the array on a single line. * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * * If the Value have comments then they are outputed according to their #CommentPlacement. * * \sa Reader, Value, Value::setComment() * \deprecated Use StreamWriterBuilder. */ #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter { public: /** * \param indentation Each level will be indented by this amount extra. */ StyledStreamWriter(String indentation = "\t"); ~StyledStreamWriter() = default; public: /** \brief Serialize a Value in JSON format. * \param out Stream to write to. (Can be ostringstream, e.g.) * \param root Value to serialize. * \note There is no point in deriving from Writer, since write() should not * return a value. */ void write(OStream& out, const Value& root); private: void writeValue(const Value& value); void writeArrayValue(const Value& value); bool isMultilineArray(const Value& value); void pushValue(const String& value); void writeIndent(); void writeWithIndent(const String& value); void indent(); void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); static bool hasCommentForValue(const Value& value); static String normalizeEOL(const String& text); using ChildValues = std::vector; ChildValues childValues_; OStream* document_; String indentString_; unsigned int rightMargin_{74}; String indentation_; bool addChildValues_ : 1; bool indented_ : 1; }; #if defined(_MSC_VER) #pragma warning(pop) #endif #if defined(JSON_HAS_INT64) String JSON_API valueToString(Int value); String JSON_API valueToString(UInt value); #endif // if defined(JSON_HAS_INT64) String JSON_API valueToString(LargestInt value); String JSON_API valueToString(LargestUInt value); String JSON_API valueToString( double value, unsigned int precision = Value::defaultRealPrecision, PrecisionType precisionType = PrecisionType::significantDigits); String JSON_API valueToString(bool value); String JSON_API valueToQuotedString(const char* value); /// \brief Output using the StyledStreamWriter. /// \see Json::operator>>() JSON_API OStream& operator<<(OStream&, const Value& root); } // namespace Json #pragma pack(pop) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma warning(pop) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // JSON_WRITER_H_INCLUDED // ////////////////////////////////////////////////////////////////////// // End of content of file: include/json/writer.h // ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/assertions.h // ////////////////////////////////////////////////////////////////////// // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #ifndef JSON_ASSERTIONS_H_INCLUDED #define JSON_ASSERTIONS_H_INCLUDED #include #include #if !defined(JSON_IS_AMALGAMATION) #include "config.h" #endif // if !defined(JSON_IS_AMALGAMATION) /** It should not be possible for a maliciously designed file to * cause an abort() or seg-fault, so these macros are used only * for pre-condition violations and internal logic errors. */ #if JSON_USE_EXCEPTION // @todo <= add detail about condition in exception #define JSON_ASSERT(condition) \ do { \ if (!(condition)) { \ Json::throwLogicError("assert json failed"); \ } \ } while (0) #define JSON_FAIL_MESSAGE(message) \ do { \ OStringStream oss; \ oss << message; \ Json::throwLogicError(oss.str()); \ abort(); \ } while (0) #else // JSON_USE_EXCEPTION #define JSON_ASSERT(condition) assert(condition) // The call to assert() will show the failure message in debug builds. In // release builds we abort, for a core-dump or debugger. #define JSON_FAIL_MESSAGE(message) \ { \ OStringStream oss; \ oss << message; \ assert(false && oss.str().c_str()); \ abort(); \ } #endif #define JSON_ASSERT_MESSAGE(condition, message) \ do { \ if (!(condition)) { \ JSON_FAIL_MESSAGE(message); \ } \ } while (0) #endif // JSON_ASSERTIONS_H_INCLUDED // ////////////////////////////////////////////////////////////////////// // End of content of file: include/json/assertions.h // ////////////////////////////////////////////////////////////////////// #endif //ifndef JSON_AMALGAMATED_H_INCLUDED