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