bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
prettywriter.h
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4//
5// Licensed under the MIT License (the "License"); you may not use this file except
6// in compliance with the License. You may obtain a copy of the License at
7//
8// http://opensource.org/licenses/MIT
9//
10// Unless required by applicable law or agreed to in writing, software distributed
11// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13// specific language governing permissions and limitations under the License.
14
15#ifndef RAPIDJSON_PRETTYWRITER_H_
16#define RAPIDJSON_PRETTYWRITER_H_
17
18#include "writer.h"
19
20#ifdef __GNUC__
21RAPIDJSON_DIAG_PUSH
22RAPIDJSON_DIAG_OFF(effc++)
23#endif
24
25#if defined(__clang__)
26RAPIDJSON_DIAG_PUSH
27RAPIDJSON_DIAG_OFF(c++98-compat)
28#endif
29
31
33
35enum PrettyFormatOptions {
36 kFormatDefault = 0,
37 kFormatSingleLineArray = 1
38};
39
41
47template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
48class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
49public:
51 typedef typename Base::Ch Ch;
52
54
58 explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
59 Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
60
61
62 explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
63 Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
64
65#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
67 Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
68#endif
69
71
75 PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
76 RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
77 indentChar_ = indentChar;
78 indentCharCount_ = indentCharCount;
79 return *this;
80 }
81
83
85 PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
86 formatOptions_ = options;
87 return *this;
88 }
89
94
95 bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); }
96 bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
97 bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
98 bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
99 bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
100 bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); }
101 bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
102
103 bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
104 RAPIDJSON_ASSERT(str != 0);
105 (void)copy;
106 PrettyPrefix(kNumberType);
107 return Base::EndValue(Base::WriteString(str, length));
108 }
109
110 bool String(const Ch* str, SizeType length, bool copy = false) {
111 RAPIDJSON_ASSERT(str != 0);
112 (void)copy;
113 PrettyPrefix(kStringType);
114 return Base::EndValue(Base::WriteString(str, length));
115 }
116
117#if RAPIDJSON_HAS_STDSTRING
118 bool String(const std::basic_string<Ch>& str) {
119 return String(str.data(), SizeType(str.size()));
120 }
121#endif
122
123 bool StartObject() {
124 PrettyPrefix(kObjectType);
125 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
126 return Base::WriteStartObject();
127 }
128
129 bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
130
131#if RAPIDJSON_HAS_STDSTRING
132 bool Key(const std::basic_string<Ch>& str) {
133 return Key(str.data(), SizeType(str.size()));
134 }
135#endif
136
137 bool EndObject(SizeType memberCount = 0) {
138 (void)memberCount;
139 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
140 RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
141 RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value
142
143 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
144
145 if (!empty) {
146 Base::os_->Put('\n');
147 WriteIndent();
148 }
149 bool ret = Base::EndValue(Base::WriteEndObject());
150 (void)ret;
151 RAPIDJSON_ASSERT(ret == true);
152 if (Base::level_stack_.Empty()) // end of json text
153 Base::Flush();
154 return true;
155 }
156
157 bool StartArray() {
158 PrettyPrefix(kArrayType);
159 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
160 return Base::WriteStartArray();
161 }
162
163 bool EndArray(SizeType memberCount = 0) {
164 (void)memberCount;
165 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
166 RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
167 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
168
169 if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
170 Base::os_->Put('\n');
171 WriteIndent();
172 }
173 bool ret = Base::EndValue(Base::WriteEndArray());
174 (void)ret;
175 RAPIDJSON_ASSERT(ret == true);
176 if (Base::level_stack_.Empty()) // end of json text
177 Base::Flush();
178 return true;
179 }
180
182
185
187 bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
188 bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
189
191
193
201 bool RawValue(const Ch* json, size_t length, Type type) {
202 RAPIDJSON_ASSERT(json != 0);
203 PrettyPrefix(type);
204 return Base::EndValue(Base::WriteRawValue(json, length));
205 }
206
207protected:
208 void PrettyPrefix(Type type) {
209 (void)type;
210 if (Base::level_stack_.GetSize() != 0) { // this value is not at root
211 typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
212
213 if (level->inArray) {
214 if (level->valueCount > 0) {
215 Base::os_->Put(','); // add comma if it is not the first element in array
216 if (formatOptions_ & kFormatSingleLineArray)
217 Base::os_->Put(' ');
218 }
219
220 if (!(formatOptions_ & kFormatSingleLineArray)) {
221 Base::os_->Put('\n');
222 WriteIndent();
223 }
224 }
225 else { // in object
226 if (level->valueCount > 0) {
227 if (level->valueCount % 2 == 0) {
228 Base::os_->Put(',');
229 Base::os_->Put('\n');
230 }
231 else {
232 Base::os_->Put(':');
233 Base::os_->Put(' ');
234 }
235 }
236 else
237 Base::os_->Put('\n');
238
239 if (level->valueCount % 2 == 0)
240 WriteIndent();
241 }
242 if (!level->inArray && level->valueCount % 2 == 0)
243 RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
244 level->valueCount++;
245 }
246 else {
247 RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
248 Base::hasRoot_ = true;
249 }
250 }
251
252 void WriteIndent() {
253 size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
254 PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);
255 }
256
257 Ch indentChar_;
258 unsigned indentCharCount_;
259 PrettyFormatOptions formatOptions_;
260
261private:
262 // Prohibit copy constructor & assignment operator.
264 PrettyWriter& operator=(const PrettyWriter&);
265};
266
268
269#if defined(__clang__)
270RAPIDJSON_DIAG_POP
271#endif
272
273#ifdef __GNUC__
274RAPIDJSON_DIAG_POP
275#endif
276
277#endif // RAPIDJSON_RAPIDJSON_H_
bool RawValue(const Ch *json, size_t length, Type type)
Write a raw JSON value.
bool String(const Ch *str)
Simpler but slower overload.
PrettyWriter(OutputStream &os, StackAllocator *allocator=0, size_t levelDepth=Base::kDefaultLevelDepth)
Constructor.
PrettyWriter & SetFormatOptions(PrettyFormatOptions options)
Set pretty writer formatting options.
PrettyWriter & SetIndent(Ch indentChar, unsigned indentCharCount)
Set custom indentation.
Writer(OutputStream &os, CrtAllocator *stackAllocator=0, size_t levelDepth=kDefaultLevelDepth)
Definition writer.h:102
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:406
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:124
Type
Type of JSON value.
Definition rapidjson.h:664
@ kFalseType
false
Definition rapidjson.h:666
@ kObjectType
object
Definition rapidjson.h:668
@ kTrueType
true
Definition rapidjson.h:667
@ kStringType
string
Definition rapidjson.h:670
@ kNullType
null
Definition rapidjson.h:665
@ kArrayType
array
Definition rapidjson.h:669
@ kNumberType
number
Definition rapidjson.h:671
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:384