From cb1f04481a47fa82395dc0b799084bc698dc8125 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 21 Mar 2014 07:44:22 -0700 Subject: [PATCH] Use read_file_mapping for reading attachments --- build/libaegisub/libaegisub.vcxproj | 1 - build/libaegisub/libaegisub.vcxproj.filters | 3 - libaegisub/Makefile | 1 - libaegisub/ass/uuencode.cpp | 58 ------------ libaegisub/include/libaegisub/ass/uuencode.h | 94 ++++++++++++++------ src/ass_attachment.cpp | 12 +-- 6 files changed, 70 insertions(+), 99 deletions(-) delete mode 100644 libaegisub/ass/uuencode.cpp diff --git a/build/libaegisub/libaegisub.vcxproj b/build/libaegisub/libaegisub.vcxproj index a38601917..dd935e6d9 100644 --- a/build/libaegisub/libaegisub.vcxproj +++ b/build/libaegisub/libaegisub.vcxproj @@ -87,7 +87,6 @@ lagi_pre.h - diff --git a/build/libaegisub/libaegisub.vcxproj.filters b/build/libaegisub/libaegisub.vcxproj.filters index 0856f727c..978e44fe8 100644 --- a/build/libaegisub/libaegisub.vcxproj.filters +++ b/build/libaegisub/libaegisub.vcxproj.filters @@ -265,9 +265,6 @@ Source Files\Common - - ASS - Source Files\Common diff --git a/libaegisub/Makefile b/libaegisub/Makefile index 48d2cdeb6..f56f38dc5 100644 --- a/libaegisub/Makefile +++ b/libaegisub/Makefile @@ -15,7 +15,6 @@ unix/path.o: CXXFLAGS += -DP_DATA=\"$(P_DATA)\" -DP_DOC=\"$(P_DOC)\" -DP_LOCALE= SRC += \ common/parser.cpp \ ass/dialogue_parser.cpp \ - ass/uuencode.cpp \ common/cajun/elements.cpp \ common/cajun/reader.cpp \ common/cajun/writer.cpp \ diff --git a/libaegisub/ass/uuencode.cpp b/libaegisub/ass/uuencode.cpp deleted file mode 100644 index b899029e2..000000000 --- a/libaegisub/ass/uuencode.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2013, Thomas Goyne -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// Aegisub Project http://www.aegisub.org/ - -#include "../config.h" - -#include "libaegisub/ass/uuencode.h" - -// Despite being called uuencoding by ass_specs.doc, the format is actually -// somewhat different from real uuencoding. Each 3-byte chunk is split into 4 -// 6-bit pieces, then 33 is added to each piece. Lines are wrapped after 80 -// characters, and files with non-multiple-of-three lengths are padded with -// zero. - -namespace agi { namespace ass { - -std::string UUEncode(std::vector const& data) { - std::string ret; - ret.reserve((data.size() * 4 + 2) / 3 + data.size() / 80 * 2); - - size_t written = 0; - for (size_t pos = 0; pos < data.size(); pos += 3) { - unsigned char src[3] = { '\0', '\0', '\0' }; - memcpy(src, &data[pos], std::min(3u, data.size() - pos)); - - unsigned char dst[4] = { - static_cast(src[0] >> 2), - static_cast(((src[0] & 0x3) << 4) | ((src[1] & 0xF0) >> 4)), - static_cast(((src[1] & 0xF) << 2) | ((src[2] & 0xC0) >> 6)), - static_cast(src[2] & 0x3F) - }; - - for (size_t i = 0; i < std::min(data.size() - pos + 1, 4u); ++i) { - ret += dst[i] + 33; - - if (++written == 80 && pos + 3 < data.size()) { - written = 0; - ret += "\r\n"; - } - } - } - - return ret; -} - -} } diff --git a/libaegisub/include/libaegisub/ass/uuencode.h b/libaegisub/include/libaegisub/ass/uuencode.h index 51e005240..fbc957c3d 100644 --- a/libaegisub/include/libaegisub/ass/uuencode.h +++ b/libaegisub/include/libaegisub/ass/uuencode.h @@ -14,41 +14,79 @@ // // Aegisub Project http://www.aegisub.org/ +#include #include #include -namespace agi { - namespace ass { - /// Encode a blob of data, using ASS's nonstandard variant - std::string UUEncode(std::vector const& data); +// Despite being called uuencoding by ass_specs.doc, the format is actually +// somewhat different from real uuencoding. Each 3-byte chunk is split into 4 +// 6-bit pieces, then 33 is added to each piece. Lines are wrapped after 80 +// characters, and files with non-multiple-of-three lengths are padded with +// zero. - /// Decode an ASS uuencoded string - template - std::vector UUDecode(String const& str) { - std::vector ret; - size_t len = std::end(str) - std::begin(str); - ret.reserve(len * 3 / 4); +namespace agi { namespace ass { - for (size_t pos = 0; pos + 1 < len; ) { - size_t bytes = 0; - unsigned char src[4] = { '\0', '\0', '\0', '\0' }; - for (size_t i = 0; i < 4 && pos < len; ++pos) { - char c = str[pos]; - if (c && c != '\n' && c != '\r') { - src[i++] = c - 33; - ++bytes; - } - } +/// Encode a blob of data, using ASS's nonstandard variant +template +std::string UUEncode(RandomAccessRange const& data) { + using std::begin; + using std::end; - if (bytes > 1) - ret.push_back((src[0] << 2) | (src[1] >> 4)); - if (bytes > 2) - ret.push_back(((src[1] & 0xF) << 4) | (src[2] >> 2)); - if (bytes > 3) - ret.push_back(((src[2] & 0x3) << 6) | (src[3])); + size_t size = std::distance(begin(data), end(data)); + std::string ret; + ret.reserve((size * 4 + 2) / 3 + size / 80 * 2); + + size_t written = 0; + for (size_t pos = 0; pos < size; pos += 3) { + unsigned char src[3] = { '\0', '\0', '\0' }; + memcpy(src, &data[pos], std::min(3u, size - pos)); + + unsigned char dst[4] = { + static_cast(src[0] >> 2), + static_cast(((src[0] & 0x3) << 4) | ((src[1] & 0xF0) >> 4)), + static_cast(((src[1] & 0xF) << 2) | ((src[2] & 0xC0) >> 6)), + static_cast(src[2] & 0x3F) + }; + + for (size_t i = 0; i < std::min(size - pos + 1, 4u); ++i) { + ret += dst[i] + 33; + + if (++written == 80 && pos + 3 < size) { + written = 0; + ret += "\r\n"; } - - return ret; } } + + return ret; } + +/// Decode an ASS uuencoded string +template +std::vector UUDecode(String const& str) { + std::vector ret; + size_t len = std::end(str) - std::begin(str); + ret.reserve(len * 3 / 4); + + for (size_t pos = 0; pos + 1 < len; ) { + size_t bytes = 0; + unsigned char src[4] = { '\0', '\0', '\0', '\0' }; + for (size_t i = 0; i < 4 && pos < len; ++pos) { + char c = str[pos]; + if (c && c != '\n' && c != '\r') { + src[i++] = c - 33; + ++bytes; + } + } + + if (bytes > 1) + ret.push_back((src[0] << 2) | (src[1] >> 4)); + if (bytes > 2) + ret.push_back(((src[1] & 0xF) << 4) | (src[2] >> 2)); + if (bytes > 3) + ret.push_back(((src[2] & 0x3) << 6) | (src[3])); + } + + return ret; +} +} } diff --git a/src/ass_attachment.cpp b/src/ass_attachment.cpp index e0c482c84..10e0a5caa 100644 --- a/src/ass_attachment.cpp +++ b/src/ass_attachment.cpp @@ -19,6 +19,7 @@ #include "ass_attachment.h" #include +#include #include #include @@ -48,15 +49,10 @@ AssAttachment::AssAttachment(agi::fs::path const& name, AssEntryGroup group) if (boost::iends_with(filename.get(), ".ttf")) filename = filename.get().substr(0, filename.get().size() - 4) + "_0" + filename.get().substr(filename.get().size() - 4); - std::vector data; - std::unique_ptr file(agi::io::Open(name, true)); - file->seekg(0, std::ios::end); - data.resize(file->tellg()); - file->seekg(0, std::ios::beg); - file->read(&data[0], data.size()); - + agi::read_file_mapping file(name); + auto buff = file.read(0, file.size()); entry_data = (group == AssEntryGroup::FONT ? "fontname: " : "filename: ") + filename.get() + "\r\n"; - entry_data = entry_data.get() + agi::ass::UUEncode(data); + entry_data = entry_data.get() + agi::ass::UUEncode(boost::make_iterator_range(buff, buff + file.size())); } size_t AssAttachment::GetSize() const {