prettywriter.h (rapidjson-1.0.2) | : | prettywriter.h (rapidjson-1.1.0) | ||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
#include "writer.h" | #include "writer.h" | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
RAPIDJSON_DIAG_PUSH | RAPIDJSON_DIAG_PUSH | |||
RAPIDJSON_DIAG_OFF(effc++) | RAPIDJSON_DIAG_OFF(effc++) | |||
#endif | #endif | |||
RAPIDJSON_NAMESPACE_BEGIN | RAPIDJSON_NAMESPACE_BEGIN | |||
//! Combination of PrettyWriter format flags. | ||||
/*! \see PrettyWriter::SetFormatOptions | ||||
*/ | ||||
enum PrettyFormatOptions { | ||||
kFormatDefault = 0, //!< Default pretty formatting. | ||||
kFormatSingleLineArray = 1 //!< Format arrays on a single line. | ||||
}; | ||||
//! Writer with indentation and spacing. | //! Writer with indentation and spacing. | |||
/*! | /*! | |||
\tparam OutputStream Type of ouptut os. | \tparam OutputStream Type of ouptut os. | |||
\tparam SourceEncoding Encoding of source string. | \tparam SourceEncoding Encoding of source string. | |||
\tparam TargetEncoding Encoding of output stream. | \tparam TargetEncoding Encoding of output stream. | |||
\tparam StackAllocator Type of allocator for allocating memory of stack. | \tparam StackAllocator Type of allocator for allocating memory of stack. | |||
*/ | */ | |||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename Targe | template<typename OutputStream, typename SourceEncoding = UTF8<>, typename Targe | |||
tEncoding = UTF8<>, typename StackAllocator = CrtAllocator> | tEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags | |||
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, | = kWriteDefaultFlags> | |||
StackAllocator> { | class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, | |||
StackAllocator, writeFlags> { | ||||
public: | public: | |||
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base; | typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base; | |||
typedef typename Base::Ch Ch; | typedef typename Base::Ch Ch; | |||
//! Constructor | //! Constructor | |||
/*! \param os Output stream. | /*! \param os Output stream. | |||
\param allocator User supplied allocator. If it is null, it will create a private one. | \param allocator User supplied allocator. If it is null, it will create a private one. | |||
\param levelDepth Initial capacity of stack. | \param levelDepth Initial capacity of stack. | |||
*/ | */ | |||
PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDe | explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_ | |||
pth = Base::kDefaultLevelDepth) : | t levelDepth = Base::kDefaultLevelDepth) : | |||
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) { | Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), | |||
} | formatOptions_(kFormatDefault) {} | |||
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Bas | ||||
e::kDefaultLevelDepth) : | ||||
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} | ||||
//! Set custom indentation. | //! Set custom indentation. | |||
/*! \param indentChar Character for indentation. Must be whitespace ch aracter (' ', '\\t', '\\n', '\\r'). | /*! \param indentChar Character for indentation. Must be whitespace ch aracter (' ', '\\t', '\\n', '\\r'). | |||
\param indentCharCount Number of indent characters for each indentation level. | \param indentCharCount Number of indent characters for each indentation level. | |||
\note The default indentation is 4 spaces. | \note The default indentation is 4 spaces. | |||
*/ | */ | |||
PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { | PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { | |||
RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar = = '\n' || indentChar == '\r'); | RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar = = '\n' || indentChar == '\r'); | |||
indentChar_ = indentChar; | indentChar_ = indentChar; | |||
indentCharCount_ = indentCharCount; | indentCharCount_ = indentCharCount; | |||
return *this; | return *this; | |||
} | } | |||
//! Set pretty writer formatting options. | ||||
/*! \param options Formatting options. | ||||
*/ | ||||
PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { | ||||
formatOptions_ = options; | ||||
return *this; | ||||
} | ||||
/*! @name Implementation of Handler | /*! @name Implementation of Handler | |||
\see Handler | \see Handler | |||
*/ | */ | |||
//@{ | //@{ | |||
bool Null() { PrettyPrefix(kNullType); return Base::WriteN ull(); } | bool Null() { PrettyPrefix(kNullType); return Base::WriteN ull(); } | |||
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); retu rn Base::WriteBool(b); } | bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); retu rn Base::WriteBool(b); } | |||
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteI nt(i); } | bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteI nt(i); } | |||
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteU int(u); } | bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteU int(u); } | |||
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteI nt64(i64); } | bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteI nt64(i64); } | |||
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteU int64(u64); } | bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteU int64(u64); } | |||
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteD ouble(d); } | bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteD ouble(d); } | |||
bool RawNumber(const Ch* str, SizeType length, bool copy = false) { | ||||
(void)copy; | ||||
PrettyPrefix(kNumberType); | ||||
return Base::WriteString(str, length); | ||||
} | ||||
bool String(const Ch* str, SizeType length, bool copy = false) { | bool String(const Ch* str, SizeType length, bool copy = false) { | |||
(void)copy; | (void)copy; | |||
PrettyPrefix(kStringType); | PrettyPrefix(kStringType); | |||
return Base::WriteString(str, length); | return Base::WriteString(str, length); | |||
} | } | |||
#if RAPIDJSON_HAS_STDSTRING | #if RAPIDJSON_HAS_STDSTRING | |||
bool String(const std::basic_string<Ch>& str) { | bool String(const std::basic_string<Ch>& str) { | |||
return String(str.data(), SizeType(str.size())); | return String(str.data(), SizeType(str.size())); | |||
} | } | |||
#endif | #endif | |||
bool StartObject() { | bool StartObject() { | |||
PrettyPrefix(kObjectType); | PrettyPrefix(kObjectType); | |||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false); | new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false); | |||
return Base::WriteStartObject(); | return Base::WriteStartObject(); | |||
} | } | |||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String( str, length, copy); } | bool Key(const Ch* str, SizeType length, bool copy = false) { return String( str, length, copy); } | |||
#if RAPIDJSON_HAS_STDSTRING | ||||
bool Key(const std::basic_string<Ch>& str) { | ||||
return Key(str.data(), SizeType(str.size())); | ||||
} | ||||
#endif | ||||
bool EndObject(SizeType memberCount = 0) { | bool EndObject(SizeType memberCount = 0) { | |||
(void)memberCount; | (void)memberCount; | |||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::L evel)); | RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::L evel)); | |||
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>( )->inArray); | RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>( )->inArray); | |||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->v alueCount == 0; | bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->v alueCount == 0; | |||
if (!empty) { | if (!empty) { | |||
Base::os_->Put('\n'); | Base::os_->Put('\n'); | |||
WriteIndent(); | WriteIndent(); | |||
} | } | |||
skipping to change at line 123 | skipping to change at line 154 | |||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true); | new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true); | |||
return Base::WriteStartArray(); | return Base::WriteStartArray(); | |||
} | } | |||
bool EndArray(SizeType memberCount = 0) { | bool EndArray(SizeType memberCount = 0) { | |||
(void)memberCount; | (void)memberCount; | |||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::L evel)); | RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::L evel)); | |||
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>() ->inArray); | RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>() ->inArray); | |||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->v alueCount == 0; | bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->v alueCount == 0; | |||
if (!empty) { | if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { | |||
Base::os_->Put('\n'); | Base::os_->Put('\n'); | |||
WriteIndent(); | WriteIndent(); | |||
} | } | |||
bool ret = Base::WriteEndArray(); | bool ret = Base::WriteEndArray(); | |||
(void)ret; | (void)ret; | |||
RAPIDJSON_ASSERT(ret == true); | RAPIDJSON_ASSERT(ret == true); | |||
if (Base::level_stack_.Empty()) // end of json text | if (Base::level_stack_.Empty()) // end of json text | |||
Base::os_->Flush(); | Base::os_->Flush(); | |||
return true; | return true; | |||
} | } | |||
skipping to change at line 145 | skipping to change at line 176 | |||
//@} | //@} | |||
/*! @name Convenience extensions */ | /*! @name Convenience extensions */ | |||
//@{ | //@{ | |||
//! Simpler but slower overload. | //! Simpler but slower overload. | |||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); } | bool String(const Ch* str) { return String(str, internal::StrLen(str)); } | |||
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } | bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } | |||
//@} | //@} | |||
//! Write a raw JSON value. | ||||
/*! | ||||
For user to write a stringified JSON as a value. | ||||
\param json A well-formed JSON value. It should not contain null charact | ||||
er within [0, length - 1] range. | ||||
\param length Length of the json. | ||||
\param type Type of the root of json. | ||||
\note When using PrettyWriter::RawValue(), the result json may not be in | ||||
dented correctly. | ||||
*/ | ||||
bool RawValue(const Ch* json, size_t length, Type type) { PrettyPrefix(type) | ||||
; return Base::WriteRawValue(json, length); } | ||||
protected: | protected: | |||
void PrettyPrefix(Type type) { | void PrettyPrefix(Type type) { | |||
(void)type; | (void)type; | |||
if (Base::level_stack_.GetSize() != 0) { // this value is not at root | if (Base::level_stack_.GetSize() != 0) { // this value is not at root | |||
typename Base::Level* level = Base::level_stack_.template Top<typena me Base::Level>(); | typename Base::Level* level = Base::level_stack_.template Top<typena me Base::Level>(); | |||
if (level->inArray) { | if (level->inArray) { | |||
if (level->valueCount > 0) { | if (level->valueCount > 0) { | |||
Base::os_->Put(','); // add comma if it is not the first ele ment in array | Base::os_->Put(','); // add comma if it is not the first ele ment in array | |||
Base::os_->Put('\n'); | if (formatOptions_ & kFormatSingleLineArray) | |||
Base::os_->Put(' '); | ||||
} | } | |||
else | ||||
if (!(formatOptions_ & kFormatSingleLineArray)) { | ||||
Base::os_->Put('\n'); | Base::os_->Put('\n'); | |||
WriteIndent(); | WriteIndent(); | |||
} | ||||
} | } | |||
else { // in object | else { // in object | |||
if (level->valueCount > 0) { | if (level->valueCount > 0) { | |||
if (level->valueCount % 2 == 0) { | if (level->valueCount % 2 == 0) { | |||
Base::os_->Put(','); | Base::os_->Put(','); | |||
Base::os_->Put('\n'); | Base::os_->Put('\n'); | |||
} | } | |||
else { | else { | |||
Base::os_->Put(':'); | Base::os_->Put(':'); | |||
Base::os_->Put(' '); | Base::os_->Put(' '); | |||
skipping to change at line 189 | skipping to change at line 235 | |||
level->valueCount++; | level->valueCount++; | |||
} | } | |||
else { | else { | |||
RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. | RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. | |||
Base::hasRoot_ = true; | Base::hasRoot_ = true; | |||
} | } | |||
} | } | |||
void WriteIndent() { | void WriteIndent() { | |||
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Lev el)) * indentCharCount_; | size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Lev el)) * indentCharCount_; | |||
PutN(*Base::os_, indentChar_, count); | PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count); | |||
} | } | |||
Ch indentChar_; | Ch indentChar_; | |||
unsigned indentCharCount_; | unsigned indentCharCount_; | |||
PrettyFormatOptions formatOptions_; | ||||
private: | private: | |||
// Prohibit copy constructor & assignment operator. | // Prohibit copy constructor & assignment operator. | |||
PrettyWriter(const PrettyWriter&); | PrettyWriter(const PrettyWriter&); | |||
PrettyWriter& operator=(const PrettyWriter&); | PrettyWriter& operator=(const PrettyWriter&); | |||
}; | }; | |||
RAPIDJSON_NAMESPACE_END | RAPIDJSON_NAMESPACE_END | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
End of changes. 13 change blocks. | ||||
13 lines changed or deleted | 65 lines changed or added |