Path: blob/master/Utilities/cmjsoncpp/include/json/writer.h
3156 views
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors1// Distributed under MIT license, or public domain if desired and2// recognized in your jurisdiction.3// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE45#ifndef JSON_WRITER_H_INCLUDED6#define JSON_WRITER_H_INCLUDED78#if !defined(JSON_IS_AMALGAMATION)9#include "value.h"10#endif // if !defined(JSON_IS_AMALGAMATION)11#include <ostream>12#include <string>13#include <vector>1415// Disable warning C4251: <data member>: <type> needs to have dll-interface to16// be used by...17#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)18#pragma warning(push)19#pragma warning(disable : 4251)20#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)2122#if !defined(__SUNPRO_CC)23#pragma pack(push)24#pragma pack()25#endif2627namespace Json {2829class Value;3031/**32*33* Usage:34* \code35* using namespace Json;36* void writeToStdout(StreamWriter::Factory const& factory, Value const& value)37* { std::unique_ptr<StreamWriter> const writer( factory.newStreamWriter());38* writer->write(value, &std::cout);39* std::cout << std::endl; // add lf and flush40* }41* \endcode42*/43class JSON_API StreamWriter {44protected:45OStream* sout_; // not owned; will not delete46public:47StreamWriter();48virtual ~StreamWriter();49/** Write Value into document as configured in sub-class.50* Do not take ownership of sout, but maintain a reference during function.51* \pre sout != NULL52* \return zero on success (For now, we always return zero, so check the53* stream instead.) \throw std::exception possibly, depending on54* configuration55*/56virtual int write(Value const& root, OStream* sout) = 0;5758/** \brief A simple abstract factory.59*/60class JSON_API Factory {61public:62virtual ~Factory();63/** \brief Allocate a CharReader via operator new().64* \throw std::exception if something goes wrong (e.g. invalid settings)65*/66virtual StreamWriter* newStreamWriter() const = 0;67}; // Factory68}; // StreamWriter6970/** \brief Write into stringstream, then return string, for convenience.71* A StreamWriter will be created from the factory, used, and then deleted.72*/73String JSON_API writeString(StreamWriter::Factory const& factory,74Value const& root);7576/** \brief Build a StreamWriter implementation.7778* Usage:79* \code80* using namespace Json;81* Value value = ...;82* StreamWriterBuilder builder;83* builder["commentStyle"] = "None";84* builder["indentation"] = " "; // or whatever you like85* std::unique_ptr<Json::StreamWriter> writer(86* builder.newStreamWriter());87* writer->write(value, &std::cout);88* std::cout << std::endl; // add lf and flush89* \endcode90*/91class JSON_API StreamWriterBuilder : public StreamWriter::Factory {92public:93// Note: We use a Json::Value so that we can add data-members to this class94// without a major version bump.95/** Configuration of this builder.96* Available settings (case-sensitive):97* - "commentStyle": "None" or "All"98* - "indentation": "<anything>".99* - Setting this to an empty string also omits newline characters.100* - "enableYAMLCompatibility": false or true101* - slightly change the whitespace around colons102* - "dropNullPlaceholders": false or true103* - Drop the "null" string from the writer's output for nullValues.104* Strictly speaking, this is not valid JSON. But when the output is being105* fed to a browser's JavaScript, it makes for smaller output and the106* browser can handle the output just fine.107* - "useSpecialFloats": false or true108* - If true, outputs non-finite floating point values in the following way:109* NaN values as "NaN", positive infinity as "Infinity", and negative110* infinity as "-Infinity".111* - "precision": int112* - Number of precision digits for formatting of real values.113* - "precisionType": "significant"(default) or "decimal"114* - Type of precision for formatting of real values.115* - "emitUTF8": false or true116* - If true, outputs raw UTF8 strings instead of escaping them.117118* You can examine 'settings_` yourself119* to see the defaults. You can also write and read them just like any120* JSON Value.121* \sa setDefaults()122*/123Json::Value settings_;124125StreamWriterBuilder();126~StreamWriterBuilder() override;127128/**129* \throw std::exception if something goes wrong (e.g. invalid settings)130*/131StreamWriter* newStreamWriter() const override;132133/** \return true if 'settings' are legal and consistent;134* otherwise, indicate bad settings via 'invalid'.135*/136bool validate(Json::Value* invalid) const;137/** A simple way to update a specific setting.138*/139Value& operator[](const String& key);140141/** Called by ctor, but you can use this to reset settings_.142* \pre 'settings' != NULL (but Json::null is fine)143* \remark Defaults:144* snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults145*/146static void setDefaults(Json::Value* settings);147};148149/** \brief Abstract class for writers.150* deprecated Use StreamWriter. (And really, this is an implementation detail.)151*/152class JSON_API Writer {153public:154virtual ~Writer();155156virtual String write(const Value& root) = 0;157};158159/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format160*without formatting (not human friendly).161*162* The JSON document is written in a single line. It is not intended for 'human'163*consumption,164* but may be useful to support feature such as RPC where bandwidth is limited.165* \sa Reader, Value166* deprecated Use StreamWriterBuilder.167*/168#if defined(_MSC_VER)169#pragma warning(push)170#pragma warning(disable : 4996) // Deriving from deprecated class171#endif172class JSON_API FastWriter : public Writer {173public:174FastWriter();175~FastWriter() override = default;176177void enableYAMLCompatibility();178179/** \brief Drop the "null" string from the writer's output for nullValues.180* Strictly speaking, this is not valid JSON. But when the output is being181* fed to a browser's JavaScript, it makes for smaller output and the182* browser can handle the output just fine.183*/184void dropNullPlaceholders();185186void omitEndingLineFeed();187188public: // overridden from Writer189String write(const Value& root) override;190191private:192void writeValue(const Value& value);193194String document_;195bool yamlCompatibilityEnabled_{false};196bool dropNullPlaceholders_{false};197bool omitEndingLineFeed_{false};198};199#if defined(_MSC_VER)200#pragma warning(pop)201#endif202203/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a204*human friendly way.205*206* The rules for line break and indent are as follow:207* - Object value:208* - if empty then print {} without indent and line break209* - if not empty the print '{', line break & indent, print one value per210*line211* and then unindent and line break and print '}'.212* - Array value:213* - if empty then print [] without indent and line break214* - if the array contains no object value, empty array or some other value215*types,216* and all the values fit on one lines, then print the array on a single217*line.218* - otherwise, it the values do not fit on one line, or the array contains219* object or non empty array, then print one value per line.220*221* If the Value have comments then they are outputted according to their222*#CommentPlacement.223*224* \sa Reader, Value, Value::setComment()225* deprecated Use StreamWriterBuilder.226*/227#if defined(_MSC_VER)228#pragma warning(push)229#pragma warning(disable : 4996) // Deriving from deprecated class230#endif231class JSON_API StyledWriter : public Writer {232public:233StyledWriter();234~StyledWriter() override = default;235236public: // overridden from Writer237/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.238* \param root Value to serialize.239* \return String containing the JSON document that represents the root value.240*/241String write(const Value& root) override;242243private:244void writeValue(const Value& value);245void writeArrayValue(const Value& value);246bool isMultilineArray(const Value& value);247void pushValue(const String& value);248void writeIndent();249void writeWithIndent(const String& value);250void indent();251void unindent();252void writeCommentBeforeValue(const Value& root);253void writeCommentAfterValueOnSameLine(const Value& root);254static bool hasCommentForValue(const Value& value);255static String normalizeEOL(const String& text);256257using ChildValues = std::vector<String>;258259ChildValues childValues_;260String document_;261String indentString_;262unsigned int rightMargin_{74};263unsigned int indentSize_{3};264bool addChildValues_{false};265};266#if defined(_MSC_VER)267#pragma warning(pop)268#endif269270/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a271human friendly way,272to a stream rather than to a string.273*274* The rules for line break and indent are as follow:275* - Object value:276* - if empty then print {} without indent and line break277* - if not empty the print '{', line break & indent, print one value per278line279* and then unindent and line break and print '}'.280* - Array value:281* - if empty then print [] without indent and line break282* - if the array contains no object value, empty array or some other value283types,284* and all the values fit on one lines, then print the array on a single285line.286* - otherwise, it the values do not fit on one line, or the array contains287* object or non empty array, then print one value per line.288*289* If the Value have comments then they are outputted according to their290#CommentPlacement.291*292* \sa Reader, Value, Value::setComment()293* deprecated Use StreamWriterBuilder.294*/295#if defined(_MSC_VER)296#pragma warning(push)297#pragma warning(disable : 4996) // Deriving from deprecated class298#endif299class JSON_API StyledStreamWriter {300public:301/**302* \param indentation Each level will be indented by this amount extra.303*/304StyledStreamWriter(String indentation = "\t");305~StyledStreamWriter() = default;306307public:308/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.309* \param out Stream to write to. (Can be ostringstream, e.g.)310* \param root Value to serialize.311* \note There is no point in deriving from Writer, since write() should not312* return a value.313*/314void write(OStream& out, const Value& root);315316private:317void writeValue(const Value& value);318void writeArrayValue(const Value& value);319bool isMultilineArray(const Value& value);320void pushValue(const String& value);321void writeIndent();322void writeWithIndent(const String& value);323void indent();324void unindent();325void writeCommentBeforeValue(const Value& root);326void writeCommentAfterValueOnSameLine(const Value& root);327static bool hasCommentForValue(const Value& value);328static String normalizeEOL(const String& text);329330using ChildValues = std::vector<String>;331332ChildValues childValues_;333OStream* document_;334String indentString_;335unsigned int rightMargin_{74};336String indentation_;337bool addChildValues_ : 1;338bool indented_ : 1;339};340#if defined(_MSC_VER)341#pragma warning(pop)342#endif343344#if defined(JSON_HAS_INT64)345String JSON_API valueToString(Int value);346String JSON_API valueToString(UInt value);347#endif // if defined(JSON_HAS_INT64)348String JSON_API valueToString(LargestInt value);349String JSON_API valueToString(LargestUInt value);350String JSON_API valueToString(351double value, unsigned int precision = Value::defaultRealPrecision,352PrecisionType precisionType = PrecisionType::significantDigits);353String JSON_API valueToString(bool value);354String JSON_API valueToQuotedString(const char* value);355String JSON_API valueToQuotedString(const char* value, size_t length);356357/// \brief Output using the StyledStreamWriter.358/// \see Json::operator>>()359JSON_API OStream& operator<<(OStream&, const Value& root);360361} // namespace Json362363#if !defined(__SUNPRO_CC)364#pragma pack(pop)365#endif366367#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)368#pragma warning(pop)369#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)370371#endif // JSON_WRITER_H_INCLUDED372373374