bes  Updated for version 3.20.6
dmrpp_module/xml2json/include/rapidjson/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__
21 RAPIDJSON_DIAG_PUSH
22 RAPIDJSON_DIAG_OFF(effc++)
23 #endif
24 
26 
28 
30 enum PrettyFormatOptions {
31  kFormatDefault = 0,
32  kFormatSingleLineArray = 1
33 };
34 
36 
42 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
43 class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
44 public:
46  typedef typename Base::Ch Ch;
47 
49 
53  explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
54  Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
55 
56 
57  explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
58  Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
59 
61 
65  PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
66  RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
67  indentChar_ = indentChar;
68  indentCharCount_ = indentCharCount;
69  return *this;
70  }
71 
73 
75  PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
76  formatOptions_ = options;
77  return *this;
78  }
79 
84 
85  bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
86  bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
87  bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
88  bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
89  bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
90  bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
91  bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
92 
93  bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
94  RAPIDJSON_ASSERT(str != 0);
95  (void)copy;
96  PrettyPrefix(kNumberType);
97  return Base::WriteString(str, length);
98  }
99 
100  bool String(const Ch* str, SizeType length, bool copy = false) {
101  RAPIDJSON_ASSERT(str != 0);
102  (void)copy;
103  PrettyPrefix(kStringType);
104  return Base::WriteString(str, length);
105  }
106 
107 #if RAPIDJSON_HAS_STDSTRING
108  bool String(const std::basic_string<Ch>& str) {
109  return String(str.data(), SizeType(str.size()));
110  }
111 #endif
112 
113  bool StartObject() {
114  PrettyPrefix(kObjectType);
115  new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
116  return Base::WriteStartObject();
117  }
118 
119  bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
120 
121 #if RAPIDJSON_HAS_STDSTRING
122  bool Key(const std::basic_string<Ch>& str) {
123  return Key(str.data(), SizeType(str.size()));
124  }
125 #endif
126 
127  bool EndObject(SizeType memberCount = 0) {
128  (void)memberCount;
129  RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
130  RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
131  bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
132 
133  if (!empty) {
134  Base::os_->Put('\n');
135  WriteIndent();
136  }
137  bool ret = Base::WriteEndObject();
138  (void)ret;
139  RAPIDJSON_ASSERT(ret == true);
140  if (Base::level_stack_.Empty()) // end of json text
141  Base::os_->Flush();
142  return true;
143  }
144 
145  bool StartArray() {
146  PrettyPrefix(kArrayType);
147  new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
148  return Base::WriteStartArray();
149  }
150 
151  bool EndArray(SizeType memberCount = 0) {
152  (void)memberCount;
153  RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
154  RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
155  bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
156 
157  if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
158  Base::os_->Put('\n');
159  WriteIndent();
160  }
161  bool ret = Base::WriteEndArray();
162  (void)ret;
163  RAPIDJSON_ASSERT(ret == true);
164  if (Base::level_stack_.Empty()) // end of json text
165  Base::os_->Flush();
166  return true;
167  }
168 
170 
173 
175  bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
176  bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
177 
179 
181 
189  bool RawValue(const Ch* json, size_t length, Type type) {
190  RAPIDJSON_ASSERT(json != 0);
191  PrettyPrefix(type);
192  return Base::WriteRawValue(json, length);
193  }
194 
195 protected:
196  void PrettyPrefix(Type type) {
197  (void)type;
198  if (Base::level_stack_.GetSize() != 0) { // this value is not at root
199  typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
200 
201  if (level->inArray) {
202  if (level->valueCount > 0) {
203  Base::os_->Put(','); // add comma if it is not the first element in array
204  if (formatOptions_ & kFormatSingleLineArray)
205  Base::os_->Put(' ');
206  }
207 
208  if (!(formatOptions_ & kFormatSingleLineArray)) {
209  Base::os_->Put('\n');
210  WriteIndent();
211  }
212  }
213  else { // in object
214  if (level->valueCount > 0) {
215  if (level->valueCount % 2 == 0) {
216  Base::os_->Put(',');
217  Base::os_->Put('\n');
218  }
219  else {
220  Base::os_->Put(':');
221  Base::os_->Put(' ');
222  }
223  }
224  else
225  Base::os_->Put('\n');
226 
227  if (level->valueCount % 2 == 0)
228  WriteIndent();
229  }
230  if (!level->inArray && level->valueCount % 2 == 0)
231  RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
232  level->valueCount++;
233  }
234  else {
235  RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
236  Base::hasRoot_ = true;
237  }
238  }
239 
240  void WriteIndent() {
241  size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
242  PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
243  }
244 
245  Ch indentChar_;
246  unsigned indentCharCount_;
247  PrettyFormatOptions formatOptions_;
248 
249 private:
250  // Prohibit copy constructor & assignment operator.
251  PrettyWriter(const PrettyWriter&);
252  PrettyWriter& operator=(const PrettyWriter&);
253 };
254 
256 
257 #ifdef __GNUC__
258 RAPIDJSON_DIAG_POP
259 #endif
260 
261 #endif // RAPIDJSON_RAPIDJSON_H_
kStringType
@ kStringType
string
Definition: cmr_module/rapidjson/rapidjson.h:609
PrettyWriter::PrettyWriter
PrettyWriter(OutputStream &os, StackAllocator *allocator=0, size_t levelDepth=Base::kDefaultLevelDepth)
Constructor.
Definition: dmrpp_module/xml2json/include/rapidjson/prettywriter.h:53
PrettyWriter
Writer with indentation and spacing.
Definition: cmr_module/rapidjson/fwd.h:100
kTrueType
@ kTrueType
true
Definition: cmr_module/rapidjson/rapidjson.h:606
kArrayType
@ kArrayType
array
Definition: cmr_module/rapidjson/rapidjson.h:608
Type
Type
Type of JSON value.
Definition: cmr_module/rapidjson/rapidjson.h:603
kObjectType
@ kObjectType
object
Definition: cmr_module/rapidjson/rapidjson.h:607
PrettyWriter::RawValue
bool RawValue(const Ch *json, size_t length, Type type)
Write a raw JSON value.
Definition: dmrpp_module/xml2json/include/rapidjson/prettywriter.h:189
kFalseType
@ kFalseType
false
Definition: cmr_module/rapidjson/rapidjson.h:605
kNumberType
@ kNumberType
number
Definition: cmr_module/rapidjson/rapidjson.h:610
SizeType
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: cmr_module/rapidjson/rapidjson.h:380
RAPIDJSON_ASSERT
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: cmr_module/rapidjson/rapidjson.h:402
kNullType
@ kNullType
null
Definition: cmr_module/rapidjson/rapidjson.h:604
PrettyWriter::SetIndent
PrettyWriter & SetIndent(Ch indentChar, unsigned indentCharCount)
Set custom indentation.
Definition: dmrpp_module/xml2json/include/rapidjson/prettywriter.h:65
PrettyWriter::String
bool String(const Ch *str)
Simpler but slower overload.
Definition: dmrpp_module/xml2json/include/rapidjson/prettywriter.h:175
RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: cmr_module/rapidjson/rapidjson.h:119
RAPIDJSON_NAMESPACE_BEGIN
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: cmr_module/rapidjson/rapidjson.h:116
Writer
JSON writer.
Definition: cmr_module/rapidjson/fwd.h:95
PrettyWriter::SetFormatOptions
PrettyWriter & SetFormatOptions(PrettyFormatOptions options)
Set pretty writer formatting options.
Definition: dmrpp_module/xml2json/include/rapidjson/prettywriter.h:75