diff options
Diffstat (limited to 'jsoncpp-src-0.5.0/src/lib_json/json_writer.cpp')
-rw-r--r-- | jsoncpp-src-0.5.0/src/lib_json/json_writer.cpp | 829 |
1 files changed, 0 insertions, 829 deletions
diff --git a/jsoncpp-src-0.5.0/src/lib_json/json_writer.cpp b/jsoncpp-src-0.5.0/src/lib_json/json_writer.cpp deleted file mode 100644 index cdf4188f2..000000000 --- a/jsoncpp-src-0.5.0/src/lib_json/json_writer.cpp +++ /dev/null @@ -1,829 +0,0 @@ -#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 *¤t ) -{ - *--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 |