summaryrefslogtreecommitdiff
path: root/src/rapidjson/prettywriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rapidjson/prettywriter.h')
-rwxr-xr-xsrc/rapidjson/prettywriter.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/rapidjson/prettywriter.h b/src/rapidjson/prettywriter.h
new file mode 100755
index 0000000000..238ff5ff62
--- /dev/null
+++ b/src/rapidjson/prettywriter.h
@@ -0,0 +1,156 @@
+#ifndef RAPIDJSON_PRETTYWRITER_H_
+#define RAPIDJSON_PRETTYWRITER_H_
+
+#include "writer.h"
+
+namespace rapidjson {
+
+//! Writer with indentation and spacing.
+/*!
+ \tparam Stream Type of ouptut stream.
+ \tparam Encoding Encoding of both source strings and output.
+ \tparam Allocator Type of allocator for allocating memory of stack.
+*/
+template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
+class PrettyWriter : public Writer<Stream, Encoding, Allocator> {
+public:
+ typedef Writer<Stream, Encoding, Allocator> Base;
+ typedef typename Base::Ch Ch;
+
+ //! Constructor
+ /*! \param stream Output stream.
+ \param allocator User supplied allocator. If it is null, it will create a private one.
+ \param levelDepth Initial capacity of
+ */
+ PrettyWriter(Stream& stream, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
+ Base(stream, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
+
+ //! Set custom indentation.
+ /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r').
+ \param indentCharCount Number of indent characters for each indentation level.
+ \note The default indentation is 4 spaces.
+ */
+ PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
+ RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
+ indentChar_ = indentChar;
+ indentCharCount_ = indentCharCount;
+ return *this;
+ }
+
+ //@name Implementation of Handler.
+ //@{
+
+ PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; }
+ PrettyWriter& Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; }
+ PrettyWriter& Int(int i) { PrettyPrefix(kNumberType); Base::WriteInt(i); return *this; }
+ PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; }
+ PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; }
+ PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; }
+ PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; }
+
+ PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) {
+ (void)copy;
+ PrettyPrefix(kStringType);
+ Base::WriteString(str, length);
+ return *this;
+ }
+
+ PrettyWriter& StartObject() {
+ PrettyPrefix(kObjectType);
+ new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
+ Base::WriteStartObject();
+ return *this;
+ }
+
+ PrettyWriter& EndObject(SizeType memberCount = 0) {
+ (void)memberCount;
+ RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
+ RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
+ bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
+
+ if (!empty) {
+ Base::stream_.Put('\n');
+ WriteIndent();
+ }
+ Base::WriteEndObject();
+ return *this;
+ }
+
+ PrettyWriter& StartArray() {
+ PrettyPrefix(kArrayType);
+ new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
+ Base::WriteStartArray();
+ return *this;
+ }
+
+ PrettyWriter& EndArray(SizeType memberCount = 0) {
+ (void)memberCount;
+ RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
+ RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
+ bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
+
+ if (!empty) {
+ Base::stream_.Put('\n');
+ WriteIndent();
+ }
+ Base::WriteEndArray();
+ return *this;
+ }
+
+ //@}
+
+ //! Simpler but slower overload.
+ PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); }
+
+protected:
+ void PrettyPrefix(Type type) {
+ (void)type;
+ if (Base::level_stack_.GetSize() != 0) { // this value is not at root
+ typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
+
+ if (level->inArray) {
+ if (level->valueCount > 0) {
+ Base::stream_.Put(','); // add comma if it is not the first element in array
+ Base::stream_.Put('\n');
+ }
+ else
+ Base::stream_.Put('\n');
+ WriteIndent();
+ }
+ else { // in object
+ if (level->valueCount > 0) {
+ if (level->valueCount % 2 == 0) {
+ Base::stream_.Put(',');
+ Base::stream_.Put('\n');
+ }
+ else {
+ Base::stream_.Put(':');
+ Base::stream_.Put(' ');
+ }
+ }
+ else
+ Base::stream_.Put('\n');
+
+ if (level->valueCount % 2 == 0)
+ WriteIndent();
+ }
+ if (!level->inArray && level->valueCount % 2 == 0)
+ RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
+ level->valueCount++;
+ }
+ else
+ RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
+ }
+
+ void WriteIndent() {
+ size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
+ PutN(Base::stream_, indentChar_, count);
+ }
+
+ Ch indentChar_;
+ unsigned indentCharCount_;
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_RAPIDJSON_H_