prettywriter.h
Go to the documentation of this file.
1 //Copyright (c) 2013-2023, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #ifndef RAPIDJSON_PRETTYWRITER_H_
27 #define RAPIDJSON_PRETTYWRITER_H_
28 
29 #include "writer.h"
30 
31 namespace rapidjson {
32 
34 
39 template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
40 class PrettyWriter : public Writer<Stream, Encoding, Allocator> {
41 public:
43  typedef typename Base::Ch Ch;
44 
46 
50  PrettyWriter(Stream& stream, int precision = 20, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
51  Base(stream, precision, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
52 
54 
58  PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
59  RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
60  indentChar_ = indentChar;
61  indentCharCount_ = indentCharCount;
62  return *this;
63  }
64 
65  //@name Implementation of Handler.
67 
69  PrettyWriter& Bool_(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool_(b); return *this; }
71  PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; }
72  PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; }
73  PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; }
74  PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; }
75 
76  PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) {
77  (void)copy;
79  Base::WriteString(str, length);
80  return *this;
81  }
82 
85  new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
87  return *this;
88  }
89 
90  PrettyWriter& EndObject(SizeType memberCount = 0) {
91  (void)memberCount;
92  RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
93  RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
94  bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
95 
96  if (!empty) {
97  Base::stream_.Put('\n');
98  WriteIndent();
99  }
101  return *this;
102  }
103 
106  new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
108  return *this;
109  }
110 
111  PrettyWriter& EndArray(SizeType memberCount = 0) {
112  (void)memberCount;
113  RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
114  RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
115  bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
116 
117  if (!empty) {
118  Base::stream_.Put('\n');
119  WriteIndent();
120  }
122  return *this;
123  }
124 
126 
128  PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); }
129 
130 protected:
131  void PrettyPrefix(Type type) {
132  (void)type;
133  if (Base::level_stack_.GetSize() != 0) { // this value is not at root
134  typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
135 
136  if (level->inArray) {
137  if (level->valueCount > 0) {
138  Base::stream_.Put(','); // add comma if it is not the first element in array
139  Base::stream_.Put('\n');
140  }
141  else
142  Base::stream_.Put('\n');
143  WriteIndent();
144  }
145  else { // in object
146  if (level->valueCount > 0) {
147  if (level->valueCount % 2 == 0) {
148  Base::stream_.Put(',');
149  Base::stream_.Put('\n');
150  }
151  else {
152  Base::stream_.Put(':');
153  Base::stream_.Put(' ');
154  }
155  }
156  else
157  Base::stream_.Put('\n');
158 
159  if (level->valueCount % 2 == 0)
160  WriteIndent();
161  }
162  if (!level->inArray && level->valueCount % 2 == 0)
163  RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
164  level->valueCount++;
165  }
166  else
167  RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
168  }
169 
170  void WriteIndent() {
171  size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
172  PutN(Base::stream_, indentChar_, count);
173  }
174 
177 };
178 
179 } // namespace rapidjson
180 
181 #endif // RAPIDJSON_RAPIDJSON_H_
Concept for allocating, resizing and freeing memory block.
Writer with indentation and spacing.
Definition: prettywriter.h:40
PrettyWriter & SetIndent(Ch indentChar, unsigned indentCharCount)
Set custom indentation.
Definition: prettywriter.h:58
PrettyWriter & Null_()
Definition: prettywriter.h:68
Writer< Stream, Encoding, Allocator > Base
Definition: prettywriter.h:42
PrettyWriter & EndObject(SizeType memberCount=0)
Definition: prettywriter.h:90
PrettyWriter & StartObject()
Definition: prettywriter.h:83
PrettyWriter & Uint64(uint64_t u64)
Definition: prettywriter.h:73
void WriteIndent()
Definition: prettywriter.h:170
PrettyWriter & Int(int i)
Definition: prettywriter.h:70
PrettyWriter & String(const Ch *str, SizeType length, bool copy=false)
Definition: prettywriter.h:76
unsigned indentCharCount_
Definition: prettywriter.h:176
Base::Ch Ch
Definition: prettywriter.h:43
PrettyWriter & String(const Ch *str)
Simpler but slower overload.
Definition: prettywriter.h:128
PrettyWriter(Stream &stream, int precision=20, Allocator *allocator=0, size_t levelDepth=Base::kDefaultLevelDepth)
Constructor.
Definition: prettywriter.h:50
PrettyWriter & Int64(int64_t i64)
Definition: prettywriter.h:72
Ch indentChar_
Definition: prettywriter.h:175
PrettyWriter & EndArray(SizeType memberCount=0)
Definition: prettywriter.h:111
PrettyWriter & Bool_(bool b)
Definition: prettywriter.h:69
PrettyWriter & Double(double d)
Definition: prettywriter.h:74
PrettyWriter & StartArray()
Definition: prettywriter.h:104
PrettyWriter & Uint(unsigned u)
Definition: prettywriter.h:71
void PrettyPrefix(Type type)
Definition: prettywriter.h:131
Concept for reading and writing characters.
JSON writer.
Definition: writer.h:58
void WriteStartArray()
Definition: writer.h:320
void WriteString(const Ch *str, SizeType length)
Definition: writer.h:285
static const size_t kDefaultLevelDepth
Definition: writer.h:145
void WriteDouble(double d)
Definition: writer.h:237
void WriteUint(unsigned u)
Definition: writer.h:168
void WriteInt64(int64_t i64)
Definition: writer.h:182
void WriteStartObject()
Definition: writer.h:318
Encoding::Ch Ch
Definition: writer.h:60
void WriteBool_(bool b)
Definition: writer.h:151
void WriteUint64(uint64_t u64)
Definition: writer.h:190
internal::Stack< Allocator > level_stack_
Definition: writer.h:342
Stream & stream_
Definition: writer.h:341
void WriteNull_()
Definition: writer.h:147
void WriteEndObject()
Definition: writer.h:319
void WriteInt(int i)
Definition: writer.h:160
void WriteEndArray()
Definition: writer.h:321
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:39
Definition: document.h:38
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:92
void PutN(GenericWriteStream &stream, char c, size_t n)
Definition: genericstream.h:113
Type
Type of JSON value.
Definition: rapidjson.h:538
@ kArrayType
array
Definition: rapidjson.h:543
@ kNull_Type
null
Definition: rapidjson.h:539
@ kTrueType
true
Definition: rapidjson.h:541
@ kFalseType
false
Definition: rapidjson.h:540
@ kNumberType
number
Definition: rapidjson.h:545
@ kObjectType
object
Definition: rapidjson.h:542
@ kStringType
string
Definition: rapidjson.h:544
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:105
Information for each nested level.
Definition: writer.h:139
size_t valueCount
number of values in this level
Definition: writer.h:142
bool inArray
true if in array, otherwise in object
Definition: writer.h:141