File indexing completed on 2025-01-18 10:10:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef RAPIDJSON_PRETTYWRITER_H_
0016 #define RAPIDJSON_PRETTYWRITER_H_
0017
0018 #include "writer.h"
0019
0020 #ifdef __GNUC__
0021 RAPIDJSON_DIAG_PUSH
0022 RAPIDJSON_DIAG_OFF(effc++)
0023 #endif
0024
0025 #if defined(__clang__)
0026 RAPIDJSON_DIAG_PUSH
0027 RAPIDJSON_DIAG_OFF(c++98-compat)
0028 #endif
0029
0030 RAPIDJSON_NAMESPACE_BEGIN
0031
0032
0033
0034
0035 enum PrettyFormatOptions {
0036 kFormatDefault = 0,
0037 kFormatSingleLineArray = 1
0038 };
0039
0040
0041
0042
0043
0044
0045
0046
0047 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
0048 class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
0049 public:
0050 typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> Base;
0051 typedef typename Base::Ch Ch;
0052
0053
0054
0055
0056
0057
0058 explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
0059 Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
0060
0061
0062 explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
0063 Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
0064
0065 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
0066 PrettyWriter(PrettyWriter&& rhs) :
0067 Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
0068 #endif
0069
0070
0071
0072
0073
0074
0075 PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
0076 RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
0077 indentChar_ = indentChar;
0078 indentCharCount_ = indentCharCount;
0079 return *this;
0080 }
0081
0082
0083
0084
0085 PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
0086 formatOptions_ = options;
0087 return *this;
0088 }
0089
0090
0091
0092
0093
0094
0095 bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); }
0096 bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
0097 bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
0098 bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
0099 bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
0100 bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); }
0101 bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
0102
0103 bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
0104 RAPIDJSON_ASSERT(str != 0);
0105 (void)copy;
0106 PrettyPrefix(kNumberType);
0107 return Base::EndValue(Base::WriteString(str, length));
0108 }
0109
0110 bool String(const Ch* str, SizeType length, bool copy = false) {
0111 RAPIDJSON_ASSERT(str != 0);
0112 (void)copy;
0113 PrettyPrefix(kStringType);
0114 return Base::EndValue(Base::WriteString(str, length));
0115 }
0116
0117 #if RAPIDJSON_HAS_STDSTRING
0118 bool String(const std::basic_string<Ch>& str) {
0119 return String(str.data(), SizeType(str.size()));
0120 }
0121 #endif
0122
0123 bool StartObject() {
0124 PrettyPrefix(kObjectType);
0125 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
0126 return Base::WriteStartObject();
0127 }
0128
0129 bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
0130
0131 #if RAPIDJSON_HAS_STDSTRING
0132 bool Key(const std::basic_string<Ch>& str) {
0133 return Key(str.data(), SizeType(str.size()));
0134 }
0135 #endif
0136
0137 bool EndObject(SizeType memberCount = 0) {
0138 (void)memberCount;
0139 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
0140 RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
0141 RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2);
0142
0143 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
0144
0145 if (!empty) {
0146 Base::os_->Put('\n');
0147 WriteIndent();
0148 }
0149 bool ret = Base::EndValue(Base::WriteEndObject());
0150 (void)ret;
0151 RAPIDJSON_ASSERT(ret == true);
0152 if (Base::level_stack_.Empty())
0153 Base::Flush();
0154 return true;
0155 }
0156
0157 bool StartArray() {
0158 PrettyPrefix(kArrayType);
0159 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
0160 return Base::WriteStartArray();
0161 }
0162
0163 bool EndArray(SizeType memberCount = 0) {
0164 (void)memberCount;
0165 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
0166 RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
0167 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
0168
0169 if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
0170 Base::os_->Put('\n');
0171 WriteIndent();
0172 }
0173 bool ret = Base::EndValue(Base::WriteEndArray());
0174 (void)ret;
0175 RAPIDJSON_ASSERT(ret == true);
0176 if (Base::level_stack_.Empty())
0177 Base::Flush();
0178 return true;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187 bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
0188 bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 bool RawValue(const Ch* json, size_t length, Type type) {
0202 RAPIDJSON_ASSERT(json != 0);
0203 PrettyPrefix(type);
0204 return Base::EndValue(Base::WriteRawValue(json, length));
0205 }
0206
0207 protected:
0208 void PrettyPrefix(Type type) {
0209 (void)type;
0210 if (Base::level_stack_.GetSize() != 0) {
0211 typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
0212
0213 if (level->inArray) {
0214 if (level->valueCount > 0) {
0215 Base::os_->Put(',');
0216 if (formatOptions_ & kFormatSingleLineArray)
0217 Base::os_->Put(' ');
0218 }
0219
0220 if (!(formatOptions_ & kFormatSingleLineArray)) {
0221 Base::os_->Put('\n');
0222 WriteIndent();
0223 }
0224 }
0225 else {
0226 if (level->valueCount > 0) {
0227 if (level->valueCount % 2 == 0) {
0228 Base::os_->Put(',');
0229 Base::os_->Put('\n');
0230 }
0231 else {
0232 Base::os_->Put(':');
0233 Base::os_->Put(' ');
0234 }
0235 }
0236 else
0237 Base::os_->Put('\n');
0238
0239 if (level->valueCount % 2 == 0)
0240 WriteIndent();
0241 }
0242 if (!level->inArray && level->valueCount % 2 == 0)
0243 RAPIDJSON_ASSERT(type == kStringType);
0244 level->valueCount++;
0245 }
0246 else {
0247 RAPIDJSON_ASSERT(!Base::hasRoot_);
0248 Base::hasRoot_ = true;
0249 }
0250 }
0251
0252 void WriteIndent() {
0253 size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
0254 PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);
0255 }
0256
0257 Ch indentChar_;
0258 unsigned indentCharCount_;
0259 PrettyFormatOptions formatOptions_;
0260
0261 private:
0262
0263 PrettyWriter(const PrettyWriter&);
0264 PrettyWriter& operator=(const PrettyWriter&);
0265 };
0266
0267 RAPIDJSON_NAMESPACE_END
0268
0269 #if defined(__clang__)
0270 RAPIDJSON_DIAG_POP
0271 #endif
0272
0273 #ifdef __GNUC__
0274 RAPIDJSON_DIAG_POP
0275 #endif
0276
0277 #endif