ian@0: // Copyright 2007-2010 Baptiste Lepilleur ian@0: // Distributed under MIT license, or public domain if desired and ian@0: // recognized in your jurisdiction. ian@0: // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE ian@0: ian@0: #ifndef JSON_WRITER_H_INCLUDED ian@0: # define JSON_WRITER_H_INCLUDED ian@0: ian@0: #if !defined(JSON_IS_AMALGAMATION) ian@0: # include "value.h" ian@0: #endif // if !defined(JSON_IS_AMALGAMATION) ian@0: # include ian@0: # include ian@0: # include ian@0: ian@0: namespace Json { ian@0: ian@0: class Value; ian@0: ian@0: /** \brief Abstract class for writers. ian@0: */ ian@0: class JSON_API Writer ian@0: { ian@0: public: ian@0: virtual ~Writer(); ian@0: ian@0: virtual std::string write( const Value &root ) = 0; ian@0: }; ian@0: ian@0: /** \brief Outputs a Value in JSON format without formatting (not human friendly). ian@0: * ian@0: * The JSON document is written in a single line. It is not intended for 'human' consumption, ian@0: * but may be usefull to support feature such as RPC where bandwith is limited. ian@0: * \sa Reader, Value ian@0: */ ian@0: class JSON_API FastWriter : public Writer ian@0: { ian@0: public: ian@0: FastWriter(); ian@0: virtual ~FastWriter(){} ian@0: ian@0: void enableYAMLCompatibility(); ian@0: ian@0: public: // overridden from Writer ian@0: virtual std::string write( const Value &root ); ian@0: ian@0: private: ian@0: void writeValue( const Value &value ); ian@0: ian@0: std::string document_; ian@0: bool yamlCompatiblityEnabled_; ian@0: }; ian@0: ian@0: /** \brief Writes a Value in JSON format in a human friendly way. ian@0: * ian@0: * The rules for line break and indent are as follow: ian@0: * - Object value: ian@0: * - if empty then print {} without indent and line break ian@0: * - if not empty the print '{', line break & indent, print one value per line ian@0: * and then unindent and line break and print '}'. ian@0: * - Array value: ian@0: * - if empty then print [] without indent and line break ian@0: * - if the array contains no object value, empty array or some other value types, ian@0: * and all the values fit on one lines, then print the array on a single line. ian@0: * - otherwise, it the values do not fit on one line, or the array contains ian@0: * object or non empty array, then print one value per line. ian@0: * ian@0: * If the Value have comments then they are outputed according to their #CommentPlacement. ian@0: * ian@0: * \sa Reader, Value, Value::setComment() ian@0: */ ian@0: class JSON_API StyledWriter: public Writer ian@0: { ian@0: public: ian@0: StyledWriter(); ian@0: virtual ~StyledWriter(){} ian@0: ian@0: public: // overridden from Writer ian@0: /** \brief Serialize a Value in JSON format. ian@0: * \param root Value to serialize. ian@0: * \return String containing the JSON document that represents the root value. ian@0: */ ian@0: virtual std::string write( const Value &root ); ian@0: ian@0: private: ian@0: void writeValue( const Value &value ); ian@0: void writeArrayValue( const Value &value ); ian@0: bool isMultineArray( const Value &value ); ian@0: void pushValue( const std::string &value ); ian@0: void writeIndent(); ian@0: void writeWithIndent( const std::string &value ); ian@0: void indent(); ian@0: void unindent(); ian@0: void writeCommentBeforeValue( const Value &root ); ian@0: void writeCommentAfterValueOnSameLine( const Value &root ); ian@0: bool hasCommentForValue( const Value &value ); ian@0: static std::string normalizeEOL( const std::string &text ); ian@0: ian@0: typedef std::vector ChildValues; ian@0: ian@0: ChildValues childValues_; ian@0: std::string document_; ian@0: std::string indentString_; ian@0: int rightMargin_; ian@0: int indentSize_; ian@0: bool addChildValues_; ian@0: }; ian@0: ian@0: /** \brief Writes a Value in JSON format in a human friendly way, ian@0: to a stream rather than to a string. ian@0: * ian@0: * The rules for line break and indent are as follow: ian@0: * - Object value: ian@0: * - if empty then print {} without indent and line break ian@0: * - if not empty the print '{', line break & indent, print one value per line ian@0: * and then unindent and line break and print '}'. ian@0: * - Array value: ian@0: * - if empty then print [] without indent and line break ian@0: * - if the array contains no object value, empty array or some other value types, ian@0: * and all the values fit on one lines, then print the array on a single line. ian@0: * - otherwise, it the values do not fit on one line, or the array contains ian@0: * object or non empty array, then print one value per line. ian@0: * ian@0: * If the Value have comments then they are outputed according to their #CommentPlacement. ian@0: * ian@0: * \param indentation Each level will be indented by this amount extra. ian@0: * \sa Reader, Value, Value::setComment() ian@0: */ ian@0: class JSON_API StyledStreamWriter ian@0: { ian@0: public: ian@0: StyledStreamWriter( std::string indentation="\t" ); ian@0: ~StyledStreamWriter(){} ian@0: ian@0: public: ian@0: /** \brief Serialize a Value in JSON format. ian@0: * \param out Stream to write to. (Can be ostringstream, e.g.) ian@0: * \param root Value to serialize. ian@0: * \note There is no point in deriving from Writer, since write() should not return a value. ian@0: */ ian@0: void write( std::ostream &out, const Value &root ); ian@0: ian@0: private: ian@0: void writeValue( const Value &value ); ian@0: void writeArrayValue( const Value &value ); ian@0: bool isMultineArray( const Value &value ); ian@0: void pushValue( const std::string &value ); ian@0: void writeIndent(); ian@0: void writeWithIndent( const std::string &value ); ian@0: void indent(); ian@0: void unindent(); ian@0: void writeCommentBeforeValue( const Value &root ); ian@0: void writeCommentAfterValueOnSameLine( const Value &root ); ian@0: bool hasCommentForValue( const Value &value ); ian@0: static std::string normalizeEOL( const std::string &text ); ian@0: ian@0: typedef std::vector ChildValues; ian@0: ian@0: ChildValues childValues_; ian@0: std::ostream* document_; ian@0: std::string indentString_; ian@0: int rightMargin_; ian@0: std::string indentation_; ian@0: bool addChildValues_; ian@0: }; ian@0: ian@0: # if defined(JSON_HAS_INT64) ian@0: std::string JSON_API valueToString( Int value ); ian@0: std::string JSON_API valueToString( UInt value ); ian@0: # endif // if defined(JSON_HAS_INT64) ian@0: std::string JSON_API valueToString( LargestInt value ); ian@0: std::string JSON_API valueToString( LargestUInt value ); ian@0: std::string JSON_API valueToString( double value ); ian@0: std::string JSON_API valueToString( bool value ); ian@0: std::string JSON_API valueToQuotedString( const char *value ); ian@0: ian@0: /// \brief Output using the StyledStreamWriter. ian@0: /// \see Json::operator>>() ian@0: std::ostream& operator<<( std::ostream&, const Value &root ); ian@0: ian@0: } // namespace Json ian@0: ian@0: ian@0: ian@0: #endif // JSON_WRITER_H_INCLUDED