mirror of https://github.com/odrling/Aegisub
Dynamically use either inline_string escaping or uuencoding for extradata
Since luabins generates binary data which grows up to 3x by escaping, it's more efficient to uuencode that instead. A marker is placed as the first character of the value field, either 'e' for inline_string escaped text, or 'u' for uuencoded binary data. The key is always inline_string escaped, as it will typically be human readable.
This commit is contained in:
parent
bcd41bd986
commit
f278c35f3f
|
@ -28,7 +28,7 @@ namespace agi { namespace ass {
|
|||
|
||||
/// Encode a blob of data, using ASS's nonstandard variant
|
||||
template<typename RandomAccessRange>
|
||||
std::string UUEncode(RandomAccessRange const& data) {
|
||||
std::string UUEncode(RandomAccessRange const& data, bool insert_linebreaks=true) {
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
|
@ -51,7 +51,7 @@ std::string UUEncode(RandomAccessRange const& data) {
|
|||
for (size_t i = 0; i < std::min<size_t>(size - pos + 1, 4u); ++i) {
|
||||
ret += dst[i] + 33;
|
||||
|
||||
if (++written == 80 && pos + 3 < size) {
|
||||
if (insert_linebreaks && ++written == 80 && pos + 3 < size) {
|
||||
written = 0;
|
||||
ret += "\r\n";
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "string_codec.h"
|
||||
#include "subtitle_format.h"
|
||||
|
||||
#include <libaegisub/ass/uuencode.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
@ -115,13 +117,25 @@ void AssParser::ParseGraphicsLine(std::string const& data) {
|
|||
}
|
||||
|
||||
void AssParser::ParseExtradataLine(std::string const &data) {
|
||||
static const boost::regex matcher("Data:[[:space:]]*(\\d+),([^,]+),(.*)");
|
||||
static const boost::regex matcher("Data:[[:space:]]*(\\d+),([^,]+),(.)(.*)");
|
||||
boost::match_results<std::string::const_iterator> mr;
|
||||
|
||||
if (boost::regex_match(data, mr, matcher)) {
|
||||
auto id = boost::lexical_cast<uint32_t>(mr.str(1));
|
||||
auto key = inline_string_decode(mr.str(2));
|
||||
auto value = inline_string_decode(mr.str(3));
|
||||
auto valuetype = mr.str(3);
|
||||
auto value = mr.str(4);
|
||||
if (valuetype == "e") {
|
||||
// escaped/inline_string encoded
|
||||
value = inline_string_decode(value);
|
||||
} else if (valuetype == "u") {
|
||||
// ass uuencoded
|
||||
auto valuedata = agi::ass::UUDecode(value);
|
||||
value = std::string(valuedata.begin(), valuedata.end());
|
||||
} else {
|
||||
// unknown, error?
|
||||
value = "";
|
||||
}
|
||||
|
||||
// ensure next_extradata_id is always at least 1 more than the largest existing id
|
||||
target->next_extradata_id = std::max(id+1, target->next_extradata_id);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "text_file_writer.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <libaegisub/ass/uuencode.h>
|
||||
#include <libaegisub/fs.h>
|
||||
|
||||
DEFINE_SIMPLE_EXCEPTION(AssParseError, SubtitleFormatParseError, "subtitle_io/parse/ass")
|
||||
|
@ -129,7 +130,18 @@ struct Writer {
|
|||
line += ",";
|
||||
line += inline_string_encode(edi.second.first);
|
||||
line += ",";
|
||||
line += inline_string_encode(edi.second.second);
|
||||
std::string encoded_data = inline_string_encode(edi.second.second);
|
||||
if (4*edi.second.second.size() < 3*encoded_data.size()) {
|
||||
// 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;
|
||||
} else {
|
||||
line += "e"; // marker for inline_string encoding (escaping)
|
||||
line += encoded_data;
|
||||
}
|
||||
file.WriteLineToFile(line);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue