Line data Source code
1 : #ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 : #define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 : 4 : #if defined(_MSC_VER) || \ 5 : (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 : (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 : #pragma once 8 : #endif 9 : 10 : #include <cmath> 11 : #include <cstddef> 12 : #include <limits> 13 : #include <memory> 14 : #include <sstream> 15 : #include <string> 16 : #include <type_traits> 17 : 18 : #include "yaml-cpp/binary.h" 19 : #include "yaml-cpp/dll.h" 20 : #include "yaml-cpp/emitterdef.h" 21 : #include "yaml-cpp/emittermanip.h" 22 : #include "yaml-cpp/null.h" 23 : #include "yaml-cpp/ostream_wrapper.h" 24 : 25 : namespace YAML { 26 : class Binary; 27 : struct _Null; 28 : } // namespace YAML 29 : 30 : namespace YAML { 31 : class EmitterState; 32 : 33 : class YAML_CPP_API Emitter { 34 : public: 35 : Emitter(); 36 : explicit Emitter(std::ostream& stream); 37 : Emitter(const Emitter&) = delete; 38 : Emitter& operator=(const Emitter&) = delete; 39 : ~Emitter(); 40 : 41 : // output 42 : const char* c_str() const; 43 : std::size_t size() const; 44 : 45 : // state checking 46 : bool good() const; 47 : const std::string GetLastError() const; 48 : 49 : // global setters 50 : bool SetOutputCharset(EMITTER_MANIP value); 51 : bool SetStringFormat(EMITTER_MANIP value); 52 : bool SetBoolFormat(EMITTER_MANIP value); 53 : bool SetNullFormat(EMITTER_MANIP value); 54 : bool SetIntBase(EMITTER_MANIP value); 55 : bool SetSeqFormat(EMITTER_MANIP value); 56 : bool SetMapFormat(EMITTER_MANIP value); 57 : bool SetIndent(std::size_t n); 58 : bool SetPreCommentIndent(std::size_t n); 59 : bool SetPostCommentIndent(std::size_t n); 60 : bool SetFloatPrecision(std::size_t n); 61 : bool SetDoublePrecision(std::size_t n); 62 : void RestoreGlobalModifiedSettings(); 63 : 64 : // local setters 65 : Emitter& SetLocalValue(EMITTER_MANIP value); 66 : Emitter& SetLocalIndent(const _Indent& indent); 67 : Emitter& SetLocalPrecision(const _Precision& precision); 68 : 69 : // overloads of write 70 : Emitter& Write(const std::string& str); 71 : Emitter& Write(bool b); 72 : Emitter& Write(char ch); 73 : Emitter& Write(const _Alias& alias); 74 : Emitter& Write(const _Anchor& anchor); 75 : Emitter& Write(const _Tag& tag); 76 : Emitter& Write(const _Comment& comment); 77 : Emitter& Write(const _Null& n); 78 : Emitter& Write(const Binary& binary); 79 : 80 : template <typename T> 81 : Emitter& WriteIntegralType(T value); 82 : 83 : template <typename T> 84 : Emitter& WriteStreamable(T value); 85 : 86 : private: 87 : template <typename T> 88 : void SetStreamablePrecision(std::stringstream&) {} 89 : std::size_t GetFloatPrecision() const; 90 : std::size_t GetDoublePrecision() const; 91 : 92 : void PrepareIntegralStream(std::stringstream& stream) const; 93 : void StartedScalar(); 94 : 95 : private: 96 : void EmitBeginDoc(); 97 : void EmitEndDoc(); 98 : void EmitBeginSeq(); 99 : void EmitEndSeq(); 100 : void EmitBeginMap(); 101 : void EmitEndMap(); 102 : void EmitNewline(); 103 : void EmitKindTag(); 104 : void EmitTag(bool verbatim, const _Tag& tag); 105 : 106 : void PrepareNode(EmitterNodeType::value child); 107 : void PrepareTopNode(EmitterNodeType::value child); 108 : void FlowSeqPrepareNode(EmitterNodeType::value child); 109 : void BlockSeqPrepareNode(EmitterNodeType::value child); 110 : 111 : void FlowMapPrepareNode(EmitterNodeType::value child); 112 : 113 : void FlowMapPrepareLongKey(EmitterNodeType::value child); 114 : void FlowMapPrepareLongKeyValue(EmitterNodeType::value child); 115 : void FlowMapPrepareSimpleKey(EmitterNodeType::value child); 116 : void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child); 117 : 118 : void BlockMapPrepareNode(EmitterNodeType::value child); 119 : 120 : void BlockMapPrepareLongKey(EmitterNodeType::value child); 121 : void BlockMapPrepareLongKeyValue(EmitterNodeType::value child); 122 : void BlockMapPrepareSimpleKey(EmitterNodeType::value child); 123 : void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); 124 : 125 : void SpaceOrIndentTo(bool requireSpace, std::size_t indent); 126 : 127 : const char* ComputeFullBoolName(bool b) const; 128 : const char* ComputeNullName() const; 129 : bool CanEmitNewline() const; 130 : 131 : private: 132 : std::unique_ptr<EmitterState> m_pState; 133 : ostream_wrapper m_stream; 134 : }; 135 : 136 : template <typename T> 137 15542 : inline Emitter& Emitter::WriteIntegralType(T value) { 138 15542 : if (!good()) 139 0 : return *this; 140 : 141 15542 : PrepareNode(EmitterNodeType::Scalar); 142 : 143 15542 : std::stringstream stream; 144 15542 : PrepareIntegralStream(stream); 145 15542 : stream << value; 146 15542 : m_stream << stream.str(); 147 : 148 15542 : StartedScalar(); 149 : 150 15542 : return *this; 151 15542 : } 152 : 153 : template <typename T> 154 2884 : inline Emitter& Emitter::WriteStreamable(T value) { 155 2884 : if (!good()) 156 0 : return *this; 157 : 158 2884 : PrepareNode(EmitterNodeType::Scalar); 159 : 160 2884 : std::stringstream stream; 161 2884 : SetStreamablePrecision<T>(stream); 162 : 163 2884 : bool special = false; 164 : if (std::is_floating_point<T>::value) { 165 2884 : if ((std::numeric_limits<T>::has_quiet_NaN || 166 : std::numeric_limits<T>::has_signaling_NaN) && 167 2884 : std::isnan(value)) { 168 0 : special = true; 169 0 : stream << ".nan"; 170 2884 : } else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) { 171 0 : special = true; 172 0 : if (std::signbit(value)) { 173 0 : stream << "-.inf"; 174 : } else { 175 0 : stream << ".inf"; 176 : } 177 : } 178 : } 179 : 180 2884 : if (!special) { 181 2884 : stream << value; 182 : } 183 2884 : m_stream << stream.str(); 184 : 185 2884 : StartedScalar(); 186 : 187 2884 : return *this; 188 2884 : } 189 : 190 : template <> 191 : inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) { 192 : stream.precision(static_cast<std::streamsize>(GetFloatPrecision())); 193 : } 194 : 195 : template <> 196 2884 : inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) { 197 2884 : stream.precision(static_cast<std::streamsize>(GetDoublePrecision())); 198 2884 : } 199 : 200 : // overloads of insertion 201 39844 : inline Emitter& operator<<(Emitter& emitter, const std::string& v) { 202 39844 : return emitter.Write(v); 203 : } 204 22035 : inline Emitter& operator<<(Emitter& emitter, bool v) { 205 22035 : return emitter.Write(v); 206 : } 207 : inline Emitter& operator<<(Emitter& emitter, char v) { 208 : return emitter.Write(v); 209 : } 210 : inline Emitter& operator<<(Emitter& emitter, unsigned char v) { 211 : return emitter.Write(static_cast<char>(v)); 212 : } 213 : inline Emitter& operator<<(Emitter& emitter, const _Alias& v) { 214 : return emitter.Write(v); 215 : } 216 : inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) { 217 : return emitter.Write(v); 218 : } 219 : inline Emitter& operator<<(Emitter& emitter, const _Tag& v) { 220 : return emitter.Write(v); 221 : } 222 : inline Emitter& operator<<(Emitter& emitter, const _Comment& v) { 223 : return emitter.Write(v); 224 : } 225 : inline Emitter& operator<<(Emitter& emitter, const _Null& v) { 226 : return emitter.Write(v); 227 : } 228 706 : inline Emitter& operator<<(Emitter& emitter, const Binary& b) { 229 706 : return emitter.Write(b); 230 : } 231 : 232 100126 : inline Emitter& operator<<(Emitter& emitter, const char* v) { 233 100126 : return emitter.Write(std::string(v)); 234 : } 235 : 236 14644 : inline Emitter& operator<<(Emitter& emitter, int v) { 237 14644 : return emitter.WriteIntegralType(v); 238 : } 239 224 : inline Emitter& operator<<(Emitter& emitter, unsigned int v) { 240 224 : return emitter.WriteIntegralType(v); 241 : } 242 : inline Emitter& operator<<(Emitter& emitter, short v) { 243 : return emitter.WriteIntegralType(v); 244 : } 245 674 : inline Emitter& operator<<(Emitter& emitter, unsigned short v) { 246 674 : return emitter.WriteIntegralType(v); 247 : } 248 : inline Emitter& operator<<(Emitter& emitter, long v) { 249 : return emitter.WriteIntegralType(v); 250 : } 251 : inline Emitter& operator<<(Emitter& emitter, unsigned long v) { 252 : return emitter.WriteIntegralType(v); 253 : } 254 : inline Emitter& operator<<(Emitter& emitter, long long v) { 255 : return emitter.WriteIntegralType(v); 256 : } 257 : inline Emitter& operator<<(Emitter& emitter, unsigned long long v) { 258 : return emitter.WriteIntegralType(v); 259 : } 260 : 261 : inline Emitter& operator<<(Emitter& emitter, float v) { 262 : return emitter.WriteStreamable(v); 263 : } 264 2884 : inline Emitter& operator<<(Emitter& emitter, double v) { 265 2884 : return emitter.WriteStreamable(v); 266 : } 267 : 268 247682 : inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) { 269 247682 : return emitter.SetLocalValue(value); 270 : } 271 : 272 : inline Emitter& operator<<(Emitter& emitter, _Indent indent) { 273 : return emitter.SetLocalIndent(indent); 274 : } 275 : 276 : inline Emitter& operator<<(Emitter& emitter, _Precision precision) { 277 : return emitter.SetLocalPrecision(precision); 278 : } 279 : } // namespace YAML 280 : 281 : #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66