DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
prettywriter.h
00001 // Tencent is pleased to support the open source community by making RapidJSON available. 00002 // 00003 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 00004 // 00005 // Licensed under the MIT License (the "License"); you may not use this file except 00006 // in compliance with the License. You may obtain a copy of the License at 00007 // 00008 // http://opensource.org/licenses/MIT 00009 // 00010 // Unless required by applicable law or agreed to in writing, software distributed 00011 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00012 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 00013 // specific language governing permissions and limitations under the License. 00014 00015 #ifndef RAPIDJSON_PRETTYWRITER_H_ 00016 #define RAPIDJSON_PRETTYWRITER_H_ 00017 00018 #include "writer.h" 00019 00020 #ifdef __GNUC__ 00021 RAPIDJSON_DIAG_PUSH 00022 RAPIDJSON_DIAG_OFF(effc++) 00023 #endif 00024 00025 #if defined(__clang__) 00026 RAPIDJSON_DIAG_PUSH 00027 RAPIDJSON_DIAG_OFF(c++98-compat) 00028 #endif 00029 00030 RAPIDJSON_NAMESPACE_BEGIN 00031 00032 //! Combination of PrettyWriter format flags. 00033 /*! \see PrettyWriter::SetFormatOptions 00034 */ 00035 enum PrettyFormatOptions { 00036 kFormatDefault = 0, //!< Default pretty formatting. 00037 kFormatSingleLineArray = 1 //!< Format arrays on a single line. 00038 }; 00039 00040 //! Writer with indentation and spacing. 00041 /*! 00042 \tparam OutputStream Type of ouptut os. 00043 \tparam SourceEncoding Encoding of source string. 00044 \tparam TargetEncoding Encoding of output stream. 00045 \tparam StackAllocator Type of allocator for allocating memory of stack. 00046 */ 00047 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> 00048 class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> { 00049 public: 00050 typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base; 00051 typedef typename Base::Ch Ch; 00052 00053 //! Constructor 00054 /*! \param os Output stream. 00055 \param allocator User supplied allocator. If it is null, it will create a private one. 00056 \param levelDepth Initial capacity of stack. 00057 */ 00058 explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 00059 Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} 00060 00061 00062 explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 00063 Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} 00064 00065 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 00066 PrettyWriter(PrettyWriter&& rhs) : 00067 Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {} 00068 #endif 00069 00070 //! Set custom indentation. 00071 /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). 00072 \param indentCharCount Number of indent characters for each indentation level. 00073 \note The default indentation is 4 spaces. 00074 */ 00075 PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { 00076 RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); 00077 indentChar_ = indentChar; 00078 indentCharCount_ = indentCharCount; 00079 return *this; 00080 } 00081 00082 //! Set pretty writer formatting options. 00083 /*! \param options Formatting options. 00084 */ 00085 PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { 00086 formatOptions_ = options; 00087 return *this; 00088 } 00089 00090 /*! @name Implementation of Handler 00091 \see Handler 00092 */ 00093 //@{ 00094 00095 bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } 00096 bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } 00097 bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } 00098 bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } 00099 bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } 00100 bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } 00101 bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } 00102 00103 bool RawNumber(const Ch* str, SizeType length, bool copy = false) { 00104 RAPIDJSON_ASSERT(str != 0); 00105 (void)copy; 00106 PrettyPrefix(kNumberType); 00107 return Base::WriteString(str, length); 00108 } 00109 00110 bool String(const Ch* str, SizeType length, bool copy = false) { 00111 RAPIDJSON_ASSERT(str != 0); 00112 (void)copy; 00113 PrettyPrefix(kStringType); 00114 return Base::WriteString(str, length); 00115 } 00116 00117 #if RAPIDJSON_HAS_STDSTRING 00118 bool String(const std::basic_string<Ch>& str) { 00119 return String(str.data(), SizeType(str.size())); 00120 } 00121 #endif 00122 00123 bool StartObject() { 00124 PrettyPrefix(kObjectType); 00125 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false); 00126 return Base::WriteStartObject(); 00127 } 00128 00129 bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } 00130 00131 #if RAPIDJSON_HAS_STDSTRING 00132 bool Key(const std::basic_string<Ch>& str) { 00133 return Key(str.data(), SizeType(str.size())); 00134 } 00135 #endif 00136 00137 bool EndObject(SizeType memberCount = 0) { 00138 (void)memberCount; 00139 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 00140 RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); 00141 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; 00142 00143 if (!empty) { 00144 Base::os_->Put('\n'); 00145 WriteIndent(); 00146 } 00147 bool ret = Base::WriteEndObject(); 00148 (void)ret; 00149 RAPIDJSON_ASSERT(ret == true); 00150 if (Base::level_stack_.Empty()) // end of json text 00151 Base::os_->Flush(); 00152 return true; 00153 } 00154 00155 bool StartArray() { 00156 PrettyPrefix(kArrayType); 00157 new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true); 00158 return Base::WriteStartArray(); 00159 } 00160 00161 bool EndArray(SizeType memberCount = 0) { 00162 (void)memberCount; 00163 RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 00164 RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray); 00165 bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; 00166 00167 if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { 00168 Base::os_->Put('\n'); 00169 WriteIndent(); 00170 } 00171 bool ret = Base::WriteEndArray(); 00172 (void)ret; 00173 RAPIDJSON_ASSERT(ret == true); 00174 if (Base::level_stack_.Empty()) // end of json text 00175 Base::os_->Flush(); 00176 return true; 00177 } 00178 00179 //@} 00180 00181 /*! @name Convenience extensions */ 00182 //@{ 00183 00184 //! Simpler but slower overload. 00185 bool String(const Ch* str) { return String(str, internal::StrLen(str)); } 00186 bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } 00187 00188 //@} 00189 00190 //! Write a raw JSON value. 00191 /*! 00192 For user to write a stringified JSON as a value. 00193 00194 \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. 00195 \param length Length of the json. 00196 \param type Type of the root of json. 00197 \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. 00198 */ 00199 bool RawValue(const Ch* json, size_t length, Type type) { 00200 RAPIDJSON_ASSERT(json != 0); 00201 PrettyPrefix(type); 00202 return Base::WriteRawValue(json, length); 00203 } 00204 00205 protected: 00206 void PrettyPrefix(Type type) { 00207 (void)type; 00208 if (Base::level_stack_.GetSize() != 0) { // this value is not at root 00209 typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>(); 00210 00211 if (level->inArray) { 00212 if (level->valueCount > 0) { 00213 Base::os_->Put(','); // add comma if it is not the first element in array 00214 if (formatOptions_ & kFormatSingleLineArray) 00215 Base::os_->Put(' '); 00216 } 00217 00218 if (!(formatOptions_ & kFormatSingleLineArray)) { 00219 Base::os_->Put('\n'); 00220 WriteIndent(); 00221 } 00222 } 00223 else { // in object 00224 if (level->valueCount > 0) { 00225 if (level->valueCount % 2 == 0) { 00226 Base::os_->Put(','); 00227 Base::os_->Put('\n'); 00228 } 00229 else { 00230 Base::os_->Put(':'); 00231 Base::os_->Put(' '); 00232 } 00233 } 00234 else 00235 Base::os_->Put('\n'); 00236 00237 if (level->valueCount % 2 == 0) 00238 WriteIndent(); 00239 } 00240 if (!level->inArray && level->valueCount % 2 == 0) 00241 RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name 00242 level->valueCount++; 00243 } 00244 else { 00245 RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. 00246 Base::hasRoot_ = true; 00247 } 00248 } 00249 00250 void WriteIndent() { 00251 size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; 00252 PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count); 00253 } 00254 00255 Ch indentChar_; 00256 unsigned indentCharCount_; 00257 PrettyFormatOptions formatOptions_; 00258 00259 private: 00260 // Prohibit copy constructor & assignment operator. 00261 PrettyWriter(const PrettyWriter&); 00262 PrettyWriter& operator=(const PrettyWriter&); 00263 }; 00264 00265 RAPIDJSON_NAMESPACE_END 00266 00267 #if defined(__clang__) 00268 RAPIDJSON_DIAG_POP 00269 #endif 00270 00271 #ifdef __GNUC__ 00272 RAPIDJSON_DIAG_POP 00273 #endif 00274 00275 #endif // RAPIDJSON_RAPIDJSON_H_
Generated on Tue Jul 12 2022 12:06:49 by 1.7.2