From: Baptiste L. <bl...@us...> - 2005-07-28 08:21:20
|
Update of /cvsroot/jsoncpp/jsoncpp/src/lib_json In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23924/src/lib_json Modified Files: json_writer.cpp Log Message: * added implementation of StyledWriter which output JSON value formatted to be easy read by human. Index: json_writer.cpp =================================================================== RCS file: /cvsroot/jsoncpp/jsoncpp/src/lib_json/json_writer.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** json_writer.cpp 27 Jul 2005 22:28:08 -0000 1.2 --- json_writer.cpp 28 Jul 2005 08:21:11 -0000 1.3 *************** *** 132,135 **** --- 132,334 ---- + // Class StyledWriter + // ////////////////////////////////////////////////////////////////// + + StyledWriter::StyledWriter() + : rightMargin_( 74 ) + , indentSize_( 3 ) + { + } + + + std::string + StyledWriter::write( const Value &root ) + { + document_.clear(); + addChildValues_ = false; + indentString_.clear(); + writeValue( root ); + document_ += "\n"; + return document_; + } + + + void + StyledWriter::writeValue( const Value &value ) + { + switch ( value.type() ) + { + case nullValue: + pushValue( "null" ); + break; + case intValue: + pushValue( valueToString( value.asInt() ) ); + break; + case uintValue: + pushValue( valueToString( value.asUInt() ) ); + break; + case realValue: + pushValue( valueToString( value.asDouble() ) ); + break; + case stringValue: + pushValue( valueToQuotedString( value.asCString() ) ); + break; + case booleanValue: + pushValue( valueToString( value.asBool() ) ); + break; + case arrayValue: + writeArrayValue( value); + break; + case objectValue: + { + Value::Members members( value.getMemberNames() ); + if ( members.empty() ) + pushValue( "{}" ); + else + { + writeWithIndent( "{" ); + indent(); + for ( Value::Members::iterator it = members.begin(); + it != members.end(); + ++it ) + { + const std::string &name = *it; + if ( it != members.begin() ) + document_ += ","; + writeWithIndent( valueToQuotedString( name.c_str() ) ); + document_ += " : "; + writeValue( value[name] ); + } + unindent(); + writeWithIndent( "}" ); + } + } + break; + } + } + + + void + StyledWriter::writeArrayValue( const Value &value ) + { + int size = value.size(); + if ( size == 0 ) + pushValue( "[]" ); + else + { + bool isArrayMultiLine = isMultineArray( value ); + if ( isArrayMultiLine ) + { + writeWithIndent( "[" ); + indent(); + bool hasChildValue = !childValues_.empty(); + for ( int index =0; index < size; ++index ) + { + if ( index > 0 ) + document_ += ","; + if ( hasChildValue ) + writeWithIndent( childValues_[index] ); + else + { + writeIndent(); + writeValue( value[index] ); + } + } + unindent(); + writeWithIndent( "]" ); + } + else // output on a single line + { + assert( childValues_.size() == size ); + document_ += "[ "; + for ( int index =0; index < size; ++index ) + { + if ( index > 0 ) + document_ += ", "; + document_ += childValues_[index]; + } + document_ += " ]"; + } + } + } + + + bool + StyledWriter::isMultineArray( const Value &value ) + { + int size = value.size(); + bool isMultiLine = size*3 >= rightMargin_ ; + childValues_.clear(); + for ( int index =0; index < size && !isMultiLine; ++index ) + { + const Value &childValue = value[index]; + isMultiLine = isMultiLine || + ( (childValue.isArray() || childValue.isObject()) && + childValue.size() > 0 ); + } + if ( !isMultiLine ) // check if line length > max line length + { + childValues_.reserve( size ); + addChildValues_ = true; + int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]' + for ( int index =0; index < size && !isMultiLine; ++index ) + { + writeValue( value[index] ); + lineLength += int( childValues_[index].length() ); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; + } + + + void + StyledWriter::pushValue( const std::string &value ) + { + if ( addChildValues_ ) + childValues_.push_back( value ); + else + document_ += value; + } + + + void + StyledWriter::writeIndent() + { + if ( !document_.empty() ) + { + char last = document_[document_.length()-1]; + assert( last != '\n' ); + if ( last == ' ' ) // already indented + return; + document_ += '\n'; + } + document_ += indentString_; + } + + + void + StyledWriter::writeWithIndent( const std::string &value ) + { + writeIndent(); + document_ += value; + } + + + void + StyledWriter::indent() + { + indentString_ += std::string( indentSize_, ' ' ); + } + + + void + StyledWriter::unindent() + { + assert( int(indentString_.size()) >= indentSize_ ); + indentString_.resize( indentString_.size() - indentSize_ ); + } + } // namespace Json |