282 lines
7.7 KiB
C++
282 lines
7.7 KiB
C++
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
|
|
#if defined(_MSC_VER) || \
|
|
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
|
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
|
#pragma once
|
|
#endif
|
|
|
|
#include <cmath>
|
|
#include <cstddef>
|
|
#include <limits>
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
#include "yaml-cpp/binary.h"
|
|
#include "yaml-cpp/dll.h"
|
|
#include "yaml-cpp/emitterdef.h"
|
|
#include "yaml-cpp/emittermanip.h"
|
|
#include "yaml-cpp/null.h"
|
|
#include "yaml-cpp/ostream_wrapper.h"
|
|
|
|
namespace YAML {
|
|
class Binary;
|
|
struct _Null;
|
|
} // namespace YAML
|
|
|
|
namespace YAML {
|
|
class EmitterState;
|
|
|
|
class YAML_CPP_API Emitter {
|
|
public:
|
|
Emitter();
|
|
explicit Emitter(std::ostream& stream);
|
|
Emitter(const Emitter&) = delete;
|
|
Emitter& operator=(const Emitter&) = delete;
|
|
~Emitter();
|
|
|
|
// output
|
|
const char* c_str() const;
|
|
std::size_t size() const;
|
|
|
|
// state checking
|
|
bool good() const;
|
|
const std::string GetLastError() const;
|
|
|
|
// global setters
|
|
bool SetOutputCharset(EMITTER_MANIP value);
|
|
bool SetStringFormat(EMITTER_MANIP value);
|
|
bool SetBoolFormat(EMITTER_MANIP value);
|
|
bool SetNullFormat(EMITTER_MANIP value);
|
|
bool SetIntBase(EMITTER_MANIP value);
|
|
bool SetSeqFormat(EMITTER_MANIP value);
|
|
bool SetMapFormat(EMITTER_MANIP value);
|
|
bool SetIndent(std::size_t n);
|
|
bool SetPreCommentIndent(std::size_t n);
|
|
bool SetPostCommentIndent(std::size_t n);
|
|
bool SetFloatPrecision(std::size_t n);
|
|
bool SetDoublePrecision(std::size_t n);
|
|
void RestoreGlobalModifiedSettings();
|
|
|
|
// local setters
|
|
Emitter& SetLocalValue(EMITTER_MANIP value);
|
|
Emitter& SetLocalIndent(const _Indent& indent);
|
|
Emitter& SetLocalPrecision(const _Precision& precision);
|
|
|
|
// overloads of write
|
|
Emitter& Write(const std::string& str);
|
|
Emitter& Write(bool b);
|
|
Emitter& Write(char ch);
|
|
Emitter& Write(const _Alias& alias);
|
|
Emitter& Write(const _Anchor& anchor);
|
|
Emitter& Write(const _Tag& tag);
|
|
Emitter& Write(const _Comment& comment);
|
|
Emitter& Write(const _Null& n);
|
|
Emitter& Write(const Binary& binary);
|
|
|
|
template <typename T>
|
|
Emitter& WriteIntegralType(T value);
|
|
|
|
template <typename T>
|
|
Emitter& WriteStreamable(T value);
|
|
|
|
private:
|
|
template <typename T>
|
|
void SetStreamablePrecision(std::stringstream&) {}
|
|
std::size_t GetFloatPrecision() const;
|
|
std::size_t GetDoublePrecision() const;
|
|
|
|
void PrepareIntegralStream(std::stringstream& stream) const;
|
|
void StartedScalar();
|
|
|
|
private:
|
|
void EmitBeginDoc();
|
|
void EmitEndDoc();
|
|
void EmitBeginSeq();
|
|
void EmitEndSeq();
|
|
void EmitBeginMap();
|
|
void EmitEndMap();
|
|
void EmitNewline();
|
|
void EmitKindTag();
|
|
void EmitTag(bool verbatim, const _Tag& tag);
|
|
|
|
void PrepareNode(EmitterNodeType::value child);
|
|
void PrepareTopNode(EmitterNodeType::value child);
|
|
void FlowSeqPrepareNode(EmitterNodeType::value child);
|
|
void BlockSeqPrepareNode(EmitterNodeType::value child);
|
|
|
|
void FlowMapPrepareNode(EmitterNodeType::value child);
|
|
|
|
void FlowMapPrepareLongKey(EmitterNodeType::value child);
|
|
void FlowMapPrepareLongKeyValue(EmitterNodeType::value child);
|
|
void FlowMapPrepareSimpleKey(EmitterNodeType::value child);
|
|
void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child);
|
|
|
|
void BlockMapPrepareNode(EmitterNodeType::value child);
|
|
|
|
void BlockMapPrepareLongKey(EmitterNodeType::value child);
|
|
void BlockMapPrepareLongKeyValue(EmitterNodeType::value child);
|
|
void BlockMapPrepareSimpleKey(EmitterNodeType::value child);
|
|
void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child);
|
|
|
|
void SpaceOrIndentTo(bool requireSpace, std::size_t indent);
|
|
|
|
const char* ComputeFullBoolName(bool b) const;
|
|
const char* ComputeNullName() const;
|
|
bool CanEmitNewline() const;
|
|
|
|
private:
|
|
std::unique_ptr<EmitterState> m_pState;
|
|
ostream_wrapper m_stream;
|
|
};
|
|
|
|
template <typename T>
|
|
inline Emitter& Emitter::WriteIntegralType(T value) {
|
|
if (!good())
|
|
return *this;
|
|
|
|
PrepareNode(EmitterNodeType::Scalar);
|
|
|
|
std::stringstream stream;
|
|
PrepareIntegralStream(stream);
|
|
stream << value;
|
|
m_stream << stream.str();
|
|
|
|
StartedScalar();
|
|
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline Emitter& Emitter::WriteStreamable(T value) {
|
|
if (!good())
|
|
return *this;
|
|
|
|
PrepareNode(EmitterNodeType::Scalar);
|
|
|
|
std::stringstream stream;
|
|
SetStreamablePrecision<T>(stream);
|
|
|
|
bool special = false;
|
|
if (std::is_floating_point<T>::value) {
|
|
if ((std::numeric_limits<T>::has_quiet_NaN ||
|
|
std::numeric_limits<T>::has_signaling_NaN) &&
|
|
std::isnan(value)) {
|
|
special = true;
|
|
stream << ".nan";
|
|
} else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) {
|
|
special = true;
|
|
if (std::signbit(value)) {
|
|
stream << "-.inf";
|
|
} else {
|
|
stream << ".inf";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!special) {
|
|
stream << value;
|
|
}
|
|
m_stream << stream.str();
|
|
|
|
StartedScalar();
|
|
|
|
return *this;
|
|
}
|
|
|
|
template <>
|
|
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) {
|
|
stream.precision(static_cast<std::streamsize>(GetFloatPrecision()));
|
|
}
|
|
|
|
template <>
|
|
inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
|
|
stream.precision(static_cast<std::streamsize>(GetDoublePrecision()));
|
|
}
|
|
|
|
// overloads of insertion
|
|
inline Emitter& operator<<(Emitter& emitter, const std::string& v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, bool v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, char v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, unsigned char v) {
|
|
return emitter.Write(static_cast<char>(v));
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, const _Alias& v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, const _Tag& v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, const _Comment& v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, const _Null& v) {
|
|
return emitter.Write(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, const Binary& b) {
|
|
return emitter.Write(b);
|
|
}
|
|
|
|
inline Emitter& operator<<(Emitter& emitter, const char* v) {
|
|
return emitter.Write(std::string(v));
|
|
}
|
|
|
|
inline Emitter& operator<<(Emitter& emitter, int v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, unsigned int v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, short v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, unsigned short v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, long v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, unsigned long v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, long long v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, unsigned long long v) {
|
|
return emitter.WriteIntegralType(v);
|
|
}
|
|
|
|
inline Emitter& operator<<(Emitter& emitter, float v) {
|
|
return emitter.WriteStreamable(v);
|
|
}
|
|
inline Emitter& operator<<(Emitter& emitter, double v) {
|
|
return emitter.WriteStreamable(v);
|
|
}
|
|
|
|
inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) {
|
|
return emitter.SetLocalValue(value);
|
|
}
|
|
|
|
inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
|
|
return emitter.SetLocalIndent(indent);
|
|
}
|
|
|
|
inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
|
|
return emitter.SetLocalPrecision(precision);
|
|
}
|
|
} // namespace YAML
|
|
|
|
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|