Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / utils / 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
25 #if defined(__clang__)
26 RAPIDJSON_DIAG_PUSH
27 RAPIDJSON_DIAG_OFF(c++98-compat)
28 #endif
29
30 RAPIDJSON_NAMESPACE_BEGIN
31
32 //! Combination of PrettyWriter format flags.
33 /*! \see PrettyWriter::SetFormatOptions
34  */
35 enum PrettyFormatOptions {
36     kFormatDefault = 0,         //!< Default pretty formatting.
37     kFormatSingleLineArray = 1  //!< Format arrays on a single line.
38 };
39
40 //! Writer with indentation and spacing.
41 /*!
42     \tparam OutputStream Type of output os.
43     \tparam SourceEncoding Encoding of source string.
44     \tparam TargetEncoding Encoding of output stream.
45     \tparam StackAllocator Type of allocator for allocating memory of stack.
46 */
47 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
48 class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
49 public:
50     typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> Base;
51     typedef typename Base::Ch Ch;
52
53     //! Constructor
54     /*! \param os Output stream.
55         \param allocator User supplied allocator. If it is null, it will create a private one.
56         \param levelDepth Initial capacity of stack.
57     */
58     explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 
59         Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
60
61
62     explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 
63         Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
64
65 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
66     PrettyWriter(PrettyWriter&& rhs) :
67         Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
68 #endif
69
70     //! Set custom indentation.
71     /*! \param indentChar       Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
72         \param indentCharCount  Number of indent characters for each indentation level.
73         \note The default indentation is 4 spaces.
74     */
75     PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
76         RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
77         indentChar_ = indentChar;
78         indentCharCount_ = indentCharCount;
79         return *this;
80     }
81
82     //! Set pretty writer formatting options.
83     /*! \param options Formatting options.
84     */
85     PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
86         formatOptions_ = options;
87         return *this;
88     }
89
90     /*! @name Implementation of Handler
91         \see Handler
92     */
93     //@{
94
95     bool Null()                 { PrettyPrefix(kNullType);   return Base::EndValue(Base::WriteNull()); }
96     bool Bool(bool b)           { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
97     bool Int(int i)             { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
98     bool Uint(unsigned u)       { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
99     bool Int64(int64_t i64)     { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
100     bool Uint64(uint64_t u64)   { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64));  }
101     bool Double(double d)       { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
102
103     bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
104         RAPIDJSON_ASSERT(str != 0);
105         (void)copy;
106         PrettyPrefix(kNumberType);
107         return Base::EndValue(Base::WriteString(str, length));
108     }
109
110     bool String(const Ch* str, SizeType length, bool copy = false) {
111         RAPIDJSON_ASSERT(str != 0);
112         (void)copy;
113         PrettyPrefix(kStringType);
114         return Base::EndValue(Base::WriteString(str, length));
115     }
116
117 #if RAPIDJSON_HAS_STDSTRING
118     bool String(const std::basic_string<Ch>& str) {
119         return String(str.data(), SizeType(str.size()));
120     }
121 #endif
122
123     bool StartObject() {
124         PrettyPrefix(kObjectType);
125         new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
126         return Base::WriteStartObject();
127     }
128
129     bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
130
131 #if RAPIDJSON_HAS_STDSTRING
132     bool Key(const std::basic_string<Ch>& str) {
133         return Key(str.data(), SizeType(str.size()));
134     }
135 #endif
136         
137     bool EndObject(SizeType memberCount = 0) {
138         (void)memberCount;
139         RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
140         RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
141         RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value
142        
143         bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
144
145         if (!empty) {
146             Base::os_->Put('\n');
147             WriteIndent();
148         }
149         bool ret = Base::EndValue(Base::WriteEndObject());
150         (void)ret;
151         RAPIDJSON_ASSERT(ret == true);
152         if (Base::level_stack_.Empty()) // end of json text
153             Base::Flush();
154         return true;
155     }
156
157     bool StartArray() {
158         PrettyPrefix(kArrayType);
159         new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
160         return Base::WriteStartArray();
161     }
162
163     bool EndArray(SizeType memberCount = 0) {
164         (void)memberCount;
165         RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
166         RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
167         bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
168
169         if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
170             Base::os_->Put('\n');
171             WriteIndent();
172         }
173         bool ret = Base::EndValue(Base::WriteEndArray());
174         (void)ret;
175         RAPIDJSON_ASSERT(ret == true);
176         if (Base::level_stack_.Empty()) // end of json text
177             Base::Flush();
178         return true;
179     }
180
181     //@}
182
183     /*! @name Convenience extensions */
184     //@{
185
186     //! Simpler but slower overload.
187     bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
188     bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
189
190     //@}
191
192     //! Write a raw JSON value.
193     /*!
194         For user to write a stringified JSON as a value.
195
196         \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
197         \param length Length of the json.
198         \param type Type of the root of json.
199         \note When using PrettyWriter::RawValue(), the result json may not be indented correctly.
200     */
201     bool RawValue(const Ch* json, size_t length, Type type) {
202         RAPIDJSON_ASSERT(json != 0);
203         PrettyPrefix(type);
204         return Base::EndValue(Base::WriteRawValue(json, length));
205     }
206
207 protected:
208     void PrettyPrefix(Type type) {
209         (void)type;
210         if (Base::level_stack_.GetSize() != 0) { // this value is not at root
211             typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
212
213             if (level->inArray) {
214                 if (level->valueCount > 0) {
215                     Base::os_->Put(','); // add comma if it is not the first element in array
216                     if (formatOptions_ & kFormatSingleLineArray)
217                         Base::os_->Put(' ');
218                 }
219
220                 if (!(formatOptions_ & kFormatSingleLineArray)) {
221                     Base::os_->Put('\n');
222                     WriteIndent();
223                 }
224             }
225             else {  // in object
226                 if (level->valueCount > 0) {
227                     if (level->valueCount % 2 == 0) {
228                         Base::os_->Put(',');
229                         Base::os_->Put('\n');
230                     }
231                     else {
232                         Base::os_->Put(':');
233                         Base::os_->Put(' ');
234                     }
235                 }
236                 else
237                     Base::os_->Put('\n');
238
239                 if (level->valueCount % 2 == 0)
240                     WriteIndent();
241             }
242             if (!level->inArray && level->valueCount % 2 == 0)
243                 RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name
244             level->valueCount++;
245         }
246         else {
247             RAPIDJSON_ASSERT(!Base::hasRoot_);  // Should only has one and only one root.
248             Base::hasRoot_ = true;
249         }
250     }
251
252     void WriteIndent()  {
253         size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
254         PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);
255     }
256
257     Ch indentChar_;
258     unsigned indentCharCount_;
259     PrettyFormatOptions formatOptions_;
260
261 private:
262     // Prohibit copy constructor & assignment operator.
263     PrettyWriter(const PrettyWriter&);
264     PrettyWriter& operator=(const PrettyWriter&);
265 };
266
267 RAPIDJSON_NAMESPACE_END
268
269 #if defined(__clang__)
270 RAPIDJSON_DIAG_POP
271 #endif
272
273 #ifdef __GNUC__
274 RAPIDJSON_DIAG_POP
275 #endif
276
277 #endif // RAPIDJSON_RAPIDJSON_H_