summaryrefslogtreecommitdiffstats
path: root/lib/jsoncpp/src/lib_json/json_writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jsoncpp/src/lib_json/json_writer.cpp')
m---------lib/jsoncpp0
-rw-r--r--lib/jsoncpp/src/lib_json/json_writer.cpp829
2 files changed, 0 insertions, 829 deletions
diff --git a/lib/jsoncpp b/lib/jsoncpp
new file mode 160000
+Subproject 5256551b0307d3e85f453faf1b1822b1d859f94
diff --git a/lib/jsoncpp/src/lib_json/json_writer.cpp b/lib/jsoncpp/src/lib_json/json_writer.cpp
deleted file mode 100644
index eff3fabeb..000000000
--- a/lib/jsoncpp/src/lib_json/json_writer.cpp
+++ /dev/null
@@ -1,829 +0,0 @@
-#include "../../include/json/writer.h"
-#include <utility>
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-
-#if _MSC_VER >= 1400 // VC++ 8.0
-#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
-#endif
-
-namespace Json {
-
-static bool isControlCharacter(char ch)
-{
- return ch > 0 && ch <= 0x1F;
-}
-
-static bool containsControlCharacter( const char* str )
-{
- while ( *str )
- {
- if ( isControlCharacter( *(str++) ) )
- return true;
- }
- return false;
-}
-static void uintToString( unsigned int value,
- char *&current )
-{
- *--current = 0;
- do
- {
- *--current = (value % 10) + '0';
- value /= 10;
- }
- while ( value != 0 );
-}
-
-std::string valueToString( Int value )
-{
- char buffer[32];
- char *current = buffer + sizeof(buffer);
- bool isNegative = value < 0;
- if ( isNegative )
- value = -value;
- uintToString( UInt(value), current );
- if ( isNegative )
- *--current = '-';
- assert( current >= buffer );
- return current;
-}
-
-
-std::string valueToString( UInt value )
-{
- char buffer[32];
- char *current = buffer + sizeof(buffer);
- uintToString( value, current );
- assert( current >= buffer );
- return current;
-}
-
-std::string valueToString( double value )
-{
- char buffer[32];
-#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
- sprintf_s(buffer, sizeof(buffer), "%#.16g", value);
-#else
- sprintf(buffer, "%#.16g", value);
-#endif
- char* ch = buffer + strlen(buffer) - 1;
- if (*ch != '0') return buffer; // nothing to truncate, so save time
- while(ch > buffer && *ch == '0'){
- --ch;
- }
- char* last_nonzero = ch;
- while(ch >= buffer){
- switch(*ch){
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- --ch;
- continue;
- case '.':
- // Truncate zeroes to save bytes in output, but keep one.
- *(last_nonzero+2) = '\0';
- return buffer;
- default:
- return buffer;
- }
- }
- return buffer;
-}
-
-
-std::string valueToString( bool value )
-{
- return value ? "true" : "false";
-}
-
-std::string valueToQuotedString( const char *value )
-{
- // Not sure how to handle unicode...
- if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value ))
- return std::string("\"") + value + "\"";
- // We have to walk value and escape any special characters.
- // Appending to std::string is not efficient, but this should be rare.
- // (Note: forward slashes are *not* rare, but I am not escaping them.)
- unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
- std::string result;
- result.reserve(maxsize); // to avoid lots of mallocs
- result += "\"";
- for (const char* c=value; *c != 0; ++c)
- {
- switch(*c)
- {
- case '\"':
- result += "\\\"";
- break;
- case '\\':
- result += "\\\\";
- break;
- case '\b':
- result += "\\b";
- break;
- case '\f':
- result += "\\f";
- break;
- case '\n':
- result += "\\n";
- break;
- case '\r':
- result += "\\r";
- break;
- case '\t':
- result += "\\t";
- break;
- //case '/':
- // Even though \/ is considered a legal escape in JSON, a bare
- // slash is also legal, so I see no reason to escape it.
- // (I hope I am not misunderstanding something.
- // blep notes: actually escaping \/ may be useful in javascript to avoid </
- // sequence.
- // Should add a flag to allow this compatibility mode and prevent this
- // sequence from occurring.
- default:
- if ( isControlCharacter( *c ) )
- {
- std::ostringstream oss;
- oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c);
- result += oss.str();
- }
- else
- {
- result += *c;
- }
- break;
- }
- }
- result += "\"";
- return result;
-}
-
-// Class Writer
-// //////////////////////////////////////////////////////////////////
-Writer::~Writer()
-{
-}
-
-
-// Class FastWriter
-// //////////////////////////////////////////////////////////////////
-
-FastWriter::FastWriter()
- : yamlCompatiblityEnabled_( false )
-{
-}
-
-
-void
-FastWriter::enableYAMLCompatibility()
-{
- yamlCompatiblityEnabled_ = true;
-}
-
-
-std::string
-FastWriter::write( const Value &root )
-{
- document_ = "";
- writeValue( root );
- document_ += "\n";
- return document_;
-}
-
-
-void
-FastWriter::writeValue( const Value &value )
-{
- switch ( value.type() )
- {
- case nullValue:
- document_ += "null";
- break;
- case intValue:
- document_ += valueToString( value.asInt() );
- break;
- case uintValue:
- document_ += valueToString( value.asUInt() );
- break;
- case realValue:
- document_ += valueToString( value.asDouble() );
- break;
- case stringValue:
- document_ += valueToQuotedString( value.asCString() );
- break;
- case booleanValue:
- document_ += valueToString( value.asBool() );
- break;
- case arrayValue:
- {
- document_ += "[";
- int size = value.size();
- for ( int index =0; index < size; ++index )
- {
- if ( index > 0 )
- document_ += ",";
- writeValue( value[index] );
- }
- document_ += "]";
- }
- break;
- case objectValue:
- {
- Value::Members members( value.getMemberNames() );
- document_ += "{";
- for ( Value::Members::iterator it = members.begin();
- it != members.end();
- ++it )
- {
- const std::string &name = *it;
- if ( it != members.begin() )
- document_ += ",";
- document_ += valueToQuotedString( name.c_str() );
- document_ += yamlCompatiblityEnabled_ ? ": "
- : ":";
- writeValue( value[name] );
- }
- document_ += "}";
- }
- break;
- }
-}
-
-
-// Class StyledWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledWriter::StyledWriter()
- : rightMargin_( 74 )
- , indentSize_( 3 )
-{
-}
-
-
-std::string
-StyledWriter::write( const Value &root )
-{
- document_ = "";
- addChildValues_ = false;
- indentString_ = "";
- writeCommentBeforeValue( root );
- writeValue( root );
- writeCommentAfterValueOnSameLine( 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();
- Value::Members::iterator it = members.begin();
- while ( true )
- {
- const std::string &name = *it;
- const Value &childValue = value[name];
- writeCommentBeforeValue( childValue );
- writeWithIndent( valueToQuotedString( name.c_str() ) );
- document_ += " : ";
- writeValue( childValue );
- if ( ++it == members.end() )
- {
- writeCommentAfterValueOnSameLine( childValue );
- break;
- }
- document_ += ",";
- writeCommentAfterValueOnSameLine( childValue );
- }
- unindent();
- writeWithIndent( "}" );
- }
- }
- break;
- }
-}
-
-
-void
-StyledWriter::writeArrayValue( const Value &value )
-{
- unsigned size = value.size();
- if ( size == 0 )
- pushValue( "[]" );
- else
- {
- bool isArrayMultiLine = isMultineArray( value );
- if ( isArrayMultiLine )
- {
- writeWithIndent( "[" );
- indent();
- bool hasChildValue = !childValues_.empty();
- unsigned index =0;
- while ( true )
- {
- const Value &childValue = value[index];
- writeCommentBeforeValue( childValue );
- if ( hasChildValue )
- writeWithIndent( childValues_[index] );
- else
- {
- writeIndent();
- writeValue( childValue );
- }
- if ( ++index == size )
- {
- writeCommentAfterValueOnSameLine( childValue );
- break;
- }
- document_ += ",";
- writeCommentAfterValueOnSameLine( childValue );
- }
- unindent();
- writeWithIndent( "]" );
- }
- else // output on a single line
- {
- assert( childValues_.size() == size );
- document_ += "[ ";
- for ( unsigned 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() );
- isMultiLine = isMultiLine && hasCommentForValue( value[index] );
- }
- 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];
- if ( last == ' ' ) // already indented
- return;
- if ( last != '\n' ) // Comments may add new-line
- 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_ );
-}
-
-
-void
-StyledWriter::writeCommentBeforeValue( const Value &root )
-{
- if ( !root.hasComment( commentBefore ) )
- return;
- document_ += normalizeEOL( root.getComment( commentBefore ) );
- document_ += "\n";
-}
-
-
-void
-StyledWriter::writeCommentAfterValueOnSameLine( const Value &root )
-{
- if ( root.hasComment( commentAfterOnSameLine ) )
- document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
-
- if ( root.hasComment( commentAfter ) )
- {
- document_ += "\n";
- document_ += normalizeEOL( root.getComment( commentAfter ) );
- document_ += "\n";
- }
-}
-
-
-bool
-StyledWriter::hasCommentForValue( const Value &value )
-{
- return value.hasComment( commentBefore )
- || value.hasComment( commentAfterOnSameLine )
- || value.hasComment( commentAfter );
-}
-
-
-std::string
-StyledWriter::normalizeEOL( const std::string &text )
-{
- std::string normalized;
- normalized.reserve( text.length() );
- const char *begin = text.c_str();
- const char *end = begin + text.length();
- const char *current = begin;
- while ( current != end )
- {
- char c = *current++;
- if ( c == '\r' ) // mac or dos EOL
- {
- if ( *current == '\n' ) // convert dos EOL
- ++current;
- normalized += '\n';
- }
- else // handle unix EOL & other char
- normalized += c;
- }
- return normalized;
-}
-
-
-// Class StyledStreamWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledStreamWriter::StyledStreamWriter( std::string indentation )
- : document_(NULL)
- , rightMargin_( 74 )
- , indentation_( indentation )
-{
-}
-
-
-void
-StyledStreamWriter::write( std::ostream &out, const Value &root )
-{
- document_ = &out;
- addChildValues_ = false;
- indentString_ = "";
- writeCommentBeforeValue( root );
- writeValue( root );
- writeCommentAfterValueOnSameLine( root );
- *document_ << "\n";
- document_ = NULL; // Forget the stream, for safety.
-}
-
-
-void
-StyledStreamWriter::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();
- Value::Members::iterator it = members.begin();
- while ( true )
- {
- const std::string &name = *it;
- const Value &childValue = value[name];
- writeCommentBeforeValue( childValue );
- writeWithIndent( valueToQuotedString( name.c_str() ) );
- *document_ << " : ";
- writeValue( childValue );
- if ( ++it == members.end() )
- {
- writeCommentAfterValueOnSameLine( childValue );
- break;
- }
- *document_ << ",";
- writeCommentAfterValueOnSameLine( childValue );
- }
- unindent();
- writeWithIndent( "}" );
- }
- }
- break;
- }
-}
-
-
-void
-StyledStreamWriter::writeArrayValue( const Value &value )
-{
- unsigned size = value.size();
- if ( size == 0 )
- pushValue( "[]" );
- else
- {
- bool isArrayMultiLine = isMultineArray( value );
- if ( isArrayMultiLine )
- {
- writeWithIndent( "[" );
- indent();
- bool hasChildValue = !childValues_.empty();
- unsigned index =0;
- while ( true )
- {
- const Value &childValue = value[index];
- writeCommentBeforeValue( childValue );
- if ( hasChildValue )
- writeWithIndent( childValues_[index] );
- else
- {
- writeIndent();
- writeValue( childValue );
- }
- if ( ++index == size )
- {
- writeCommentAfterValueOnSameLine( childValue );
- break;
- }
- *document_ << ",";
- writeCommentAfterValueOnSameLine( childValue );
- }
- unindent();
- writeWithIndent( "]" );
- }
- else // output on a single line
- {
- assert( childValues_.size() == size );
- *document_ << "[ ";
- for ( unsigned index =0; index < size; ++index )
- {
- if ( index > 0 )
- *document_ << ", ";
- *document_ << childValues_[index];
- }
- *document_ << " ]";
- }
- }
-}
-
-
-bool
-StyledStreamWriter::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() );
- isMultiLine = isMultiLine && hasCommentForValue( value[index] );
- }
- addChildValues_ = false;
- isMultiLine = isMultiLine || lineLength >= rightMargin_;
- }
- return isMultiLine;
-}
-
-
-void
-StyledStreamWriter::pushValue( const std::string &value )
-{
- if ( addChildValues_ )
- childValues_.push_back( value );
- else
- *document_ << value;
-}
-
-
-void
-StyledStreamWriter::writeIndent()
-{
- /*
- Some comments in this method would have been nice. ;-)
-
- if ( !document_.empty() )
- {
- char last = document_[document_.length()-1];
- if ( last == ' ' ) // already indented
- return;
- if ( last != '\n' ) // Comments may add new-line
- *document_ << '\n';
- }
- */
- *document_ << '\n' << indentString_;
-}
-
-
-void
-StyledStreamWriter::writeWithIndent( const std::string &value )
-{
- writeIndent();
- *document_ << value;
-}
-
-
-void
-StyledStreamWriter::indent()
-{
- indentString_ += indentation_;
-}
-
-
-void
-StyledStreamWriter::unindent()
-{
- assert( indentString_.size() >= indentation_.size() );
- indentString_.resize( indentString_.size() - indentation_.size() );
-}
-
-
-void
-StyledStreamWriter::writeCommentBeforeValue( const Value &root )
-{
- if ( !root.hasComment( commentBefore ) )
- return;
- *document_ << normalizeEOL( root.getComment( commentBefore ) );
- *document_ << "\n";
-}
-
-
-void
-StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root )
-{
- if ( root.hasComment( commentAfterOnSameLine ) )
- *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
-
- if ( root.hasComment( commentAfter ) )
- {
- *document_ << "\n";
- *document_ << normalizeEOL( root.getComment( commentAfter ) );
- *document_ << "\n";
- }
-}
-
-
-bool
-StyledStreamWriter::hasCommentForValue( const Value &value )
-{
- return value.hasComment( commentBefore )
- || value.hasComment( commentAfterOnSameLine )
- || value.hasComment( commentAfter );
-}
-
-
-std::string
-StyledStreamWriter::normalizeEOL( const std::string &text )
-{
- std::string normalized;
- normalized.reserve( text.length() );
- const char *begin = text.c_str();
- const char *end = begin + text.length();
- const char *current = begin;
- while ( current != end )
- {
- char c = *current++;
- if ( c == '\r' ) // mac or dos EOL
- {
- if ( *current == '\n' ) // convert dos EOL
- ++current;
- normalized += '\n';
- }
- else // handle unix EOL & other char
- normalized += c;
- }
- return normalized;
-}
-
-
-std::ostream& operator<<( std::ostream &sout, const Value &root )
-{
- Json::StyledStreamWriter writer;
- writer.write(sout, root);
- return sout;
-}
-
-
-} // namespace Json