diff --git a/src/subtitle_format_ass.cpp b/src/subtitle_format_ass.cpp index c5d1800df..e5261193a 100644 --- a/src/subtitle_format_ass.cpp +++ b/src/subtitle_format_ass.cpp @@ -68,7 +68,7 @@ void AssSubtitleFormat::ReadFile(AssFile *target, agi::fs::path const& filename, #endif namespace { -std::string format(AssEntryGroup group, bool ssa) { +const char *format(AssEntryGroup group, bool ssa) { if (group == AssEntryGroup::DIALOGUE) { if (ssa) return "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" LINEBREAK; @@ -83,14 +83,18 @@ std::string format(AssEntryGroup group, bool ssa) { return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" LINEBREAK; } - return ""; + return nullptr; } struct Writer { TextFileWriter file; - bool ssa; + bool ssa = false; AssEntryGroup group = AssEntryGroup::INFO; + Writer(std::ostream &ostr) : file(ostr) { + file.WriteLineToFile("[Script Info]"); + } + Writer(agi::fs::path const& filename, std::string const& encoding) : file(filename, encoding) , ssa(agi::fs::HasExtension(filename, "ssa")) @@ -108,7 +112,8 @@ struct Writer { file.WriteLineToFile(""); file.WriteLineToFile(line.GroupHeader(ssa)); - file.WriteLineToFile(format(line.Group(), ssa), false); + if (const char *str = format(line.Group(), ssa)) + file.WriteLineToFile(str, false); group = line.Group(); } @@ -135,9 +140,7 @@ struct Writer { // the inline_string encoding grew the data by more than uuencoding would // so base64 encode it instead line += "u"; // marker for uuencoding - encoded_data = agi::ass::UUEncode(edi.second.second, false); - printf("did uuencoding, original size=%lu, encoded size=%lu\n", edi.second.second.size(), encoded_data.size()); - line += encoded_data; + line += agi::ass::UUEncode(edi.second.second, false); } else { line += "e"; // marker for inline_string encoding (escaping) line += encoded_data; @@ -150,10 +153,16 @@ struct Writer { void AssSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& encoding) const { Writer writer(filename, encoding); - writer.Write(src->Info); writer.Write(src->Styles); writer.Write(src->Attachments); writer.Write(src->Events); writer.WriteExtradata(src->Extradata); } + +void AssSubtitleFormat::WriteToStream(const AssFile *src, std::ostream &ostr) { + Writer writer(ostr); + writer.Write(src->Info); + writer.Write(src->Styles); + writer.Write(src->Events); +} diff --git a/src/subtitle_format_ass.h b/src/subtitle_format_ass.h index 5a69e7dfa..3071276d8 100644 --- a/src/subtitle_format_ass.h +++ b/src/subtitle_format_ass.h @@ -46,4 +46,5 @@ public: void ReadFile(AssFile *target, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& forceEncoding) const override; void WriteFile(const AssFile *src, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& encoding) const override; + static void WriteToStream(const AssFile *src, std::ostream &ostr); }; diff --git a/src/subtitles_provider_libass.cpp b/src/subtitles_provider_libass.cpp index fe8dc4ebd..93b9de90a 100644 --- a/src/subtitles_provider_libass.cpp +++ b/src/subtitles_provider_libass.cpp @@ -40,6 +40,7 @@ #include "ass_style.h" #include "compat.h" #include "include/aegisub/subtitles_provider.h" +#include "subtitle_format_ass.h" #include "video_frame.h" #include @@ -50,6 +51,7 @@ #include #include +#include #include #include #include @@ -153,33 +155,13 @@ LibassSubtitlesProvider::~LibassSubtitlesProvider() { if (ass_track) ass_free_track(ass_track); } -struct Writer { - std::vector data; - AssEntryGroup group = AssEntryGroup::GROUP_MAX; - - template - void Write(T const& list) { - for (auto const& line : list) { - if (group != line.Group()) { - group = line.Group(); - boost::push_back(data, line.GroupHeader() + "\r\n"); - } - boost::push_back(data, line.GetEntryData() + "\r\n"); - } - } -}; - void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs) { - Writer writer; - - writer.data.reserve(0x4000); - - writer.Write(subs->Info); - writer.Write(subs->Styles); - writer.Write(subs->Events); + boost::interprocess::basic_ovectorstream> ostr; + ostr.reserve(0x4000); + AssSubtitleFormat::WriteToStream(subs, ostr); if (ass_track) ass_free_track(ass_track); - ass_track = ass_read_memory(library, &writer.data[0], writer.data.size(), nullptr); + ass_track = ass_read_memory(library, const_cast(ostr.vector().data()), ostr.vector().size(), nullptr); if (!ass_track) throw "libass failed to load subtitles."; } diff --git a/src/text_file_writer.cpp b/src/text_file_writer.cpp index 6ec301fc3..0e990927e 100644 --- a/src/text_file_writer.cpp +++ b/src/text_file_writer.cpp @@ -32,7 +32,7 @@ TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding) : file(new agi::io::Save(filename, true)) -, conv() +, ostr(file->Get()) { if (encoding.empty()) encoding = OPT_GET("App/Save Charset")->GetString(); @@ -48,11 +48,15 @@ TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encodi } } +TextFileWriter::TextFileWriter(std::ostream &ostr) : ostr(ostr) { + WriteLineToFile("\xEF\xBB\xBF", false); +} + TextFileWriter::~TextFileWriter() { // Explicit empty destructor required with a unique_ptr to an incomplete class } -void TextFileWriter::WriteLineToFile(std::string&& line, bool addLineBreak) { +void TextFileWriter::WriteLineToFile(std::string line, bool addLineBreak) { if (addLineBreak) #ifdef _WIN32 line += "\r\n"; @@ -62,5 +66,5 @@ void TextFileWriter::WriteLineToFile(std::string&& line, bool addLineBreak) { if (conv) line = conv->Convert(line); - file->Get().write(line.data(), line.size()); + ostr.write(line.data(), line.size()); } diff --git a/src/text_file_writer.h b/src/text_file_writer.h index e97c3770d..0f2ea0feb 100644 --- a/src/text_file_writer.h +++ b/src/text_file_writer.h @@ -32,11 +32,12 @@ namespace agi { class TextFileWriter { std::unique_ptr file; std::unique_ptr conv; + std::ostream &ostr; public: TextFileWriter(agi::fs::path const& filename, std::string encoding=""); + TextFileWriter(std::ostream &ostr); ~TextFileWriter(); - void WriteLineToFile(std::string const& line, bool addLineBreak=true) { WriteLineToFile(std::string(line), addLineBreak); } - void WriteLineToFile(std::string&& line, bool addLineBreak=true); + void WriteLineToFile(std::string line, bool addLineBreak=true); };