NGL  6.5
The NCCA Graphics Library
prettywriter.h
Go to the documentation of this file.
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 
34 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator>
35 class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> {
36 public:
38  typedef typename Base::Ch Ch;
39 
41 
45  PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
46  Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
47 
49 
53  PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
54  RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
55  indentChar_ = indentChar;
56  indentCharCount_ = indentCharCount;
57  return *this;
58  }
59 
64 
65  bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
66  bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
67  bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
68  bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
69  bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
71  bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
72 
73  bool String(const Ch* str, SizeType length, bool copy = false) {
74  (void)copy;
76  return Base::WriteString(str, length);
77  }
78 
79 #if RAPIDJSON_HAS_STDSTRING
80  bool String(const std::basic_string<Ch>& str) {
81  return String(str.data(), SizeType(str.size()));
82  }
83 #endif
84 
85  bool StartObject() {
87  new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
88  return Base::WriteStartObject();
89  }
90 
91  bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
92 
93  bool EndObject(SizeType memberCount = 0) {
94  (void)memberCount;
95  RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
96  RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
97  bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
98 
99  if (!empty) {
100  Base::os_->Put('\n');
101  WriteIndent();
102  }
103  bool ret = Base::WriteEndObject();
104  (void)ret;
105  RAPIDJSON_ASSERT(ret == true);
106  if (Base::level_stack_.Empty()) // end of json text
107  Base::os_->Flush();
108  return true;
109  }
110 
111  bool StartArray() {
113  new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
114  return Base::WriteStartArray();
115  }
116 
117  bool EndArray(SizeType memberCount = 0) {
118  (void)memberCount;
119  RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
120  RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
121  bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
122 
123  if (!empty) {
124  Base::os_->Put('\n');
125  WriteIndent();
126  }
127  bool ret = Base::WriteEndArray();
128  (void)ret;
129  RAPIDJSON_ASSERT(ret == true);
130  if (Base::level_stack_.Empty()) // end of json text
131  Base::os_->Flush();
132  return true;
133  }
134 
136 
139 
141  bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
142  bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
143 
145 protected:
147  (void)type;
148  if (Base::level_stack_.GetSize() != 0) { // this value is not at root
149  typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
150 
151  if (level->inArray) {
152  if (level->valueCount > 0) {
153  Base::os_->Put(','); // add comma if it is not the first element in array
154  Base::os_->Put('\n');
155  }
156  else
157  Base::os_->Put('\n');
158  WriteIndent();
159  }
160  else { // in object
161  if (level->valueCount > 0) {
162  if (level->valueCount % 2 == 0) {
163  Base::os_->Put(',');
164  Base::os_->Put('\n');
165  }
166  else {
167  Base::os_->Put(':');
168  Base::os_->Put(' ');
169  }
170  }
171  else
172  Base::os_->Put('\n');
173 
174  if (level->valueCount % 2 == 0)
175  WriteIndent();
176  }
177  if (!level->inArray && level->valueCount % 2 == 0)
178  RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
179  level->valueCount++;
180  }
181  else {
182  RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
183  Base::hasRoot_ = true;
184  }
185  }
186 
187  void WriteIndent() {
188  size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
189  PutN(*Base::os_, indentChar_, count);
190  }
191 
194 
195 private:
196  // Prohibit copy constructor & assignment operator.
197  PrettyWriter(const PrettyWriter&);
199 };
200 
202 
203 #ifdef __GNUC__
204 RAPIDJSON_DIAG_POP
205 #endif
206 
207 #endif // RAPIDJSON_RAPIDJSON_H_
bool String(const Ch *str, SizeType length, bool copy=false)
Definition: prettywriter.h:73
PrettyWriter & SetIndent(Ch indentChar, unsigned indentCharCount)
Set custom indentation.
Definition: prettywriter.h:53
bool Int(int i)
Definition: prettywriter.h:67
internal::Stack< StackAllocator > level_stack_
Definition: writer.h:338
bool String(const Ch *str)
Simpler but slower overload.
Definition: prettywriter.h:141
bool StartArray()
Definition: prettywriter.h:111
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
GLint level
Definition: glew.h:1255
bool WriteInt(int i)
Definition: writer.h:204
object
Definition: rapidjson.h:646
bool WriteEndArray()
Definition: writer.h:315
bool WriteInt64(int64_t i64)
Definition: writer.h:220
Writer< OutputStream, SourceEncoding, TargetEncoding, StackAllocator > Base
Definition: prettywriter.h:37
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1256
void PutN(FileWriteStream &stream, char c, size_t n)
Implement specialized version of PutN() with memset() for better performance.
array
Definition: rapidjson.h:647
bool WriteStartObject()
Definition: writer.h:312
bool Uint(unsigned u)
Definition: prettywriter.h:68
bool EndArray(SizeType memberCount=0)
Definition: prettywriter.h:117
Base::Ch Ch
Definition: prettywriter.h:38
void WriteIndent()
Definition: prettywriter.h:187
false
Definition: rapidjson.h:644
bool WriteString(const Ch *str, SizeType length)
Definition: writer.h:244
bool StartObject()
Definition: prettywriter.h:85
bool Key(const Ch *str, SizeType length, bool copy=false)
Definition: prettywriter.h:91
void PrettyPrefix(Type type)
Definition: prettywriter.h:146
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
JSON writer.
Definition: writer.h:54
typedef void(GLAPIENTRY *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target
bool WriteStartArray()
Definition: writer.h:314
static const size_t kDefaultLevelDepth
Definition: writer.h:188
GLuint GLsizei GLsizei * length
Definition: glew.h:1828
bool EndObject(SizeType memberCount=0)
Definition: prettywriter.h:93
bool Double(double d)
Definition: prettywriter.h:71
bool WriteBool(bool b)
Definition: writer.h:194
GLdouble GLdouble GLdouble b
Definition: glew.h:9162
size_t GetSize() const
Definition: stack.h:146
bool Key(const Ch *str)
Definition: prettywriter.h:142
bool Uint64(uint64_t u64)
Definition: prettywriter.h:70
string
Definition: rapidjson.h:648
bool Int64(int64_t i64)
Definition: prettywriter.h:69
bool WriteUint64(uint64_t u64)
Definition: writer.h:228
size_t valueCount
number of values in this level
Definition: writer.h:184
unsigned indentCharCount_
Definition: prettywriter.h:193
GLuint GLuint GLsizei count
Definition: glew.h:1256
Writer with indentation and spacing.
Definition: prettywriter.h:35
unsigned __int64 uint64_t
Definition: stdint.h:136
number
Definition: rapidjson.h:649
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
bool WriteUint(unsigned u)
Definition: writer.h:212
PrettyWriter & operator=(const PrettyWriter &)
bool WriteNull()
Definition: writer.h:190
Information for each nested level.
Definition: writer.h:182
bool hasRoot_
Definition: writer.h:339
SourceEncoding::Ch Ch
Definition: writer.h:56
signed __int64 int64_t
Definition: stdint.h:135
bool Bool(bool b)
Definition: prettywriter.h:66
bool WriteDouble(double d)
Definition: writer.h:236
true
Definition: rapidjson.h:645
bool WriteEndObject()
Definition: writer.h:313
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:30
OutputStream * os_
Definition: writer.h:337
PrettyWriter(OutputStream &os, StackAllocator *allocator=0, size_t levelDepth=Base::kDefaultLevelDepth)
Constructor.
Definition: prettywriter.h:45
Type
Type of JSON value.
Definition: rapidjson.h:642
bool inArray
true if in array, otherwise in object
Definition: writer.h:185
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
null
Definition: rapidjson.h:643