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