diff --git a/src/emitter.cpp b/src/emitter.cpp index 5168cba89..085d1df86 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -976,8 +976,34 @@ Emitter& Emitter::Write(const Binary& binary) { if (!good()) return *this; + const StringFormat::value strFormat = binary.size() == 0 ? + Utils::ComputeStringFormat("", 0, m_pState->GetStringFormat(), + m_pState->CurGroupFlowType(), false) : + Utils::ComputeStringFormat("a", 1, m_pState->GetStringFormat(), + m_pState->CurGroupFlowType(), false); + + if (strFormat == StringFormat::Literal) + m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local); + PrepareNode(EmitterNodeType::Scalar); - Utils::WriteBinary(m_stream, binary); + + switch (strFormat) { + // case StringFormat::Plain: // to avoid changing the default behavior + // m_stream.write(EncodeBase64(binary.data(), binary.size())); + // break; + case StringFormat::SingleQuoted: + Utils::WriteSingleQuotedBinary(m_stream, binary); + break; + case StringFormat::Plain: + case StringFormat::DoubleQuoted: + Utils::WriteBinary(m_stream, binary); + break; + case StringFormat::Literal: + Utils::WriteLiteralBinary(m_stream, binary, + m_pState->CurIndent() + m_pState->GetIndent()); + break; + } + StartedScalar(); return *this; diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index ea96385a1..3f9bef1fc 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -516,5 +516,18 @@ bool WriteBinary(ostream_wrapper& out, const Binary& binary) { StringEscaping::None); return true; } + +bool WriteLiteralBinary(ostream_wrapper& out, const Binary& binary, std::size_t indent) { + std::string encoded = EncodeBase64(binary.data(), binary.size()); + WriteLiteralString(out, encoded.data(), encoded.size(), indent); + return true; +} + +bool WriteSingleQuotedBinary(ostream_wrapper& out, const Binary& binary) { + std::string encoded = EncodeBase64(binary.data(), binary.size()); + WriteSingleQuotedString(out, encoded.data(), encoded.size()); + return true; +} + } // namespace Utils } // namespace YAML diff --git a/src/emitterutils.h b/src/emitterutils.h index 0c0dcbb92..307b8ef07 100644 --- a/src/emitterutils.h +++ b/src/emitterutils.h @@ -49,6 +49,8 @@ bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag); bool WriteBinary(ostream_wrapper& out, const Binary& binary); +bool WriteSingleQuotedBinary(ostream_wrapper& out, const Binary& binary); +bool WriteLiteralBinary(ostream_wrapper& out, const Binary& binary, std::size_t indent); } } diff --git a/test/integration/emitter_test.cpp b/test/integration/emitter_test.cpp index 64cc999e6..1e67f2fca 100644 --- a/test/integration/emitter_test.cpp +++ b/test/integration/emitter_test.cpp @@ -1191,6 +1191,34 @@ TEST_F(EmitterTest, EmptyBinary) { ExpectEmit("!!binary \"\""); } +TEST_F(EmitterTest, BinaryStyles) { + Binary binary(reinterpret_cast("Hello, World!"), 13); + out << BeginMap; + out << Key << "auto"; + out << Value << Auto << binary; + out << Key << "single"; + out << Value << SingleQuoted << binary; + out << Key << "double"; + out << Value << DoubleQuoted << binary; + out << Key << "literal"; + out << Value << Literal << binary; + out << Key << "literal_empty"; + out << Value << Literal << Binary(reinterpret_cast(""), 0); + out << Key << "literal_indented"; + out << Value << Literal << Indent(8) << binary; + ExpectEmit( + "auto: !!binary \"SGVsbG8sIFdvcmxkIQ==\"\n" + "single: !!binary \'SGVsbG8sIFdvcmxkIQ==\'\n" + "double: !!binary \"SGVsbG8sIFdvcmxkIQ==\"\n" + "literal: !!binary |-\n" + " SGVsbG8sIFdvcmxkIQ==\n" + "literal_empty: !!binary |-\n" + "\n" + "literal_indented: !!binary |-\n" + " SGVsbG8sIFdvcmxkIQ==" + ); +} + TEST_F(EmitterTest, ColonAtEndOfScalar) { out << "a:"; ExpectEmit("\"a:\""); @@ -1468,8 +1496,8 @@ TEST_F(EmitterTest, Infinity) { out << YAML::EndMap; ExpectEmit( - "foo: .inf\n" - "bar: .inf"); + "foo: .inf\n" + "bar: .inf"); } TEST_F(EmitterTest, NegInfinity) { @@ -1481,8 +1509,8 @@ TEST_F(EmitterTest, NegInfinity) { out << YAML::EndMap; ExpectEmit( - "foo: -.inf\n" - "bar: -.inf"); + "foo: -.inf\n" + "bar: -.inf"); } TEST_F(EmitterTest, NaN) { @@ -1494,8 +1522,8 @@ TEST_F(EmitterTest, NaN) { out << YAML::EndMap; ExpectEmit( - "foo: .nan\n" - "bar: .nan"); + "foo: .nan\n" + "bar: .nan"); } TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLine) {