prettywriter.h
Engine/source/persistence/rapidjson/prettywriter.h
Classes:
class
Writer with indentation and spacing.
Namespaces:
namespace
Detailed Description
1 2#ifndef RAPIDJSON_PRETTYWRITER_H_ 3#define RAPIDJSON_PRETTYWRITER_H_ 4 5#include "writer.h" 6 7namespace rapidjson { 8 9//! Writer with indentation and spacing. 10/*! 11 \tparam OutputStream Type of ouptut os. 12 \tparam Encoding Encoding of both source strings and output. 13 \tparam Allocator Type of allocator for allocating memory of stack. 14*/ 15template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > 16class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> { 17public: 18 typedef Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> Base; 19 typedef typename Base::Ch Ch; 20 21 //! Constructor 22 /*! \param os Output os. 23 \param allocator User supplied allocator. If it is null, it will create a private one. 24 \param levelDepth Initial capacity of 25 */ 26 PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 27 Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} 28 29 //! Set custom indentation. 30 /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r'). 31 \param indentCharCount Number of indent characters for each indentation level. 32 \note The default indentation is 4 spaces. 33 */ 34 PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { 35 RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); 36 indentChar_ = indentChar; 37 indentCharCount_ = indentCharCount; 38 return *this; 39 } 40 41 //@name Implementation of Handler. 42 //@{ 43 44 PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; } 45 PrettyWriter& Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; } 46 PrettyWriter& Int(int i) { PrettyPrefix(kNumberType); Base::WriteInt(i); return *this; } 47 PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; } 48 PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; } 49 PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; } 50 PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; } 51 52 PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { 53 (void)copy; 54 PrettyPrefix(kStringType); 55 Base::WriteString(str, length); 56 return *this; 57 } 58 59 PrettyWriter& StartObject() { 60 PrettyPrefix(kObjectType); 61 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false); 62 Base::WriteStartObject(); 63 return *this; 64 } 65 66 PrettyWriter& EndObject(SizeType memberCount = 0) { 67 (void)memberCount; 68 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 69 RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); 70 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; 71 72 if (!empty) { 73 Base::os_.Put('\n'); 74 WriteIndent(); 75 } 76 Base::WriteEndObject(); 77 if (Base::level_stack_.Empty()) // end of json text 78 Base::os_.flush(); 79 return *this; 80 } 81 82 PrettyWriter& StartArray() { 83 PrettyPrefix(kArrayType); 84 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true); 85 Base::WriteStartArray(); 86 return *this; 87 } 88 89 PrettyWriter& EndArray(SizeType memberCount = 0) { 90 (void)memberCount; 91 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 92 RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray); 93 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; 94 95 if (!empty) { 96 Base::os_.Put('\n'); 97 WriteIndent(); 98 } 99 Base::WriteEndArray(); 100 if (Base::level_stack_.Empty()) // end of json text 101 Base::os_.flush(); 102 return *this; 103 } 104 105 //@} 106 107 //! Simpler but slower overload. 108 PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); } 109 110protected: 111 void PrettyPrefix(Type type) { 112 (void)type; 113 if (Base::level_stack_.GetSize() != 0) { // this value is not at root 114 typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>(); 115 116 if (level->inArray) { 117 if (level->valueCount > 0) { 118 Base::os_.Put(','); // add comma if it is not the first element in array 119 Base::os_.Put('\n'); 120 } 121 else 122 Base::os_.Put('\n'); 123 WriteIndent(); 124 } 125 else { // in object 126 if (level->valueCount > 0) { 127 if (level->valueCount % 2 == 0) { 128 Base::os_.Put(','); 129 Base::os_.Put('\n'); 130 } 131 else { 132 Base::os_.Put(':'); 133 Base::os_.Put(' '); 134 } 135 } 136 else 137 Base::os_.Put('\n'); 138 139 if (level->valueCount % 2 == 0) 140 WriteIndent(); 141 } 142 if (!level->inArray && level->valueCount % 2 == 0) 143 RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name 144 level->valueCount++; 145 } 146 else 147 RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); 148 } 149 150 void WriteIndent() { 151 size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; 152 PutN(Base::os_, indentChar_, count); 153 } 154 155 Ch indentChar_; 156 unsigned indentCharCount_; 157}; 158 159} // namespace rapidjson 160 161#endif // RAPIDJSON_RAPIDJSON_H_ 162
