From 01e48c29ad46a03be54af4e8806b493e84091214 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 27 Aug 2024 14:53:18 +0300 Subject: [PATCH] Write strings containing binary data as base64 --- source/textwriter.cpp | 55 +++++++++++++++++++++++++++++++++++++++++-- source/textwriter.h | 4 ++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/source/textwriter.cpp b/source/textwriter.cpp index 04fccff..460bfb3 100644 --- a/source/textwriter.cpp +++ b/source/textwriter.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "output.h" #include "statement.h" @@ -10,7 +11,8 @@ namespace Msp { namespace DataFile { TextWriter::TextWriter(Output &o): - WriterMode(o) + WriterMode(o), + codec(make_unique()) { float_format.showpoint().precision(7); } @@ -34,7 +36,13 @@ void TextWriter::write_(const Statement &st, unsigned level) { out.put(' '); if(v.get_signature()==StringType::signature) - out.write(format("\"%s\"", c_escape(v.get(), false))); + { + StringType::Store str = v.get(); + if(codec->detect(str)) + out.write(format("\"%s\"", c_escape(str, false))); + else + out.write(format("=%s=", base64_encode(str))); + } else if(v.get_signature()==BoolType::signature) out.write(v.get() ? "true" : "false"); else if(v.get_signature()==IntType::signature) @@ -60,5 +68,48 @@ void TextWriter::write_(const Statement &st, unsigned level) out.write(";\n"); } +string TextWriter::base64_encode(const string &str) +{ + string b64; + b64.reserve(str.size()*4/3+3); + unsigned accum = 0; + unsigned a_bits = 0; + for(auto i=str.begin(); i!=str.end(); ) + { + accum = (accum<<8)|static_cast(*i); + a_bits += 8; + + ++i; + if(i==str.end() && a_bits%6) + { + accum <<= 4; + a_bits += 4; + } + + while(a_bits>=6) + { + unsigned d = (accum>>(a_bits-6))&63; + a_bits -= 6; + accum &= (1< +#include #include #include "writermode.h" @@ -11,6 +13,7 @@ class TextWriter: public WriterMode { private: Fmt float_format; + std::unique_ptr codec; public: TextWriter(Output &o); @@ -19,6 +22,7 @@ public: void write(const Statement &st) override; private: void write_(const Statement &st, unsigned); + std::string base64_encode(const std::string &); }; } // namespace DataFile -- 2.45.2