Index: third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp |
diff --git a/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp b/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp |
index 65b80bb57f24fd2b79b42d806b99db30182bea19..3d4bd00f6b3d11f7ed7d126ebf38c6f33678cb60 100644 |
--- a/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp |
+++ b/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp |
@@ -45,12 +45,23 @@ |
#include "wtf/text/Base64.h" |
#include "wtf/text/StringBuilder.h" |
-namespace blink { |
+ |
+namespace { |
const char* const quotedPrintable = "quoted-printable"; |
const char* const base64 = "base64"; |
const char* const binary = "binary"; |
+enum class Encoding { |
+ QuotedPrintable, |
+ Base64, |
+ Binary, |
+}; |
+ |
+} |
+ |
+namespace blink { |
+ |
static String replaceNonPrintableCharacters(const String& text) |
{ |
StringBuilder stringBuilder; |
@@ -108,7 +119,7 @@ bool MHTMLArchive::canLoadArchive(const KURL& url) |
void MHTMLArchive::generateMHTMLHeader( |
const String& boundary, const String& title, const String& mimeType, |
- SharedBuffer& outputBuffer) |
+ std::vector<char>& outputBuffer) |
{ |
ASSERT(!boundary.isEmpty()); |
ASSERT(!mimeType.isEmpty()); |
@@ -141,7 +152,8 @@ void MHTMLArchive::generateMHTMLHeader( |
ASSERT(stringBuilder.toString().containsOnlyASCII()); |
CString asciiString = stringBuilder.toString().utf8(); |
- outputBuffer.append(asciiString.data(), asciiString.length()); |
+ outputBuffer.reserve(outputBuffer.size() + asciiString.length()); |
+ outputBuffer.insert(outputBuffer.end(), asciiString.data(), asciiString.data() + asciiString.length()); |
} |
void MHTMLArchive::generateMHTMLPart( |
@@ -149,7 +161,7 @@ void MHTMLArchive::generateMHTMLPart( |
const String& contentID, |
EncodingPolicy encodingPolicy, |
const SerializedResource& resource, |
- SharedBuffer& outputBuffer) |
+ std::vector<char>& outputBuffer) |
{ |
ASSERT(!boundary.isEmpty()); |
ASSERT(contentID.isEmpty() || contentID[0] == '<'); |
@@ -169,16 +181,20 @@ void MHTMLArchive::generateMHTMLPart( |
stringBuilder.append("\r\n"); |
} |
- const char* contentEncoding = 0; |
- if (encodingPolicy == UseBinaryEncoding) |
- contentEncoding = binary; |
- else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(resource.mimeType) || MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType)) |
- contentEncoding = quotedPrintable; |
- else |
- contentEncoding = base64; |
+ const char* contentEncodingText = 0; |
+ Encoding encoding = Encoding::Base64; |
+ if (encodingPolicy == UseBinaryEncoding) { |
+ contentEncodingText = binary; |
+ encoding = Encoding::Binary; |
+ } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(resource.mimeType) || MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType)) { |
+ contentEncodingText = quotedPrintable; |
+ encoding = Encoding::QuotedPrintable; |
+ } else { |
+ contentEncodingText = base64; |
+ } |
stringBuilder.append("Content-Transfer-Encoding: "); |
- stringBuilder.append(contentEncoding); |
+ stringBuilder.append(contentEncodingText); |
stringBuilder.append("\r\n"); |
if (!resource.url.protocolIsAbout()) { |
@@ -190,13 +206,24 @@ void MHTMLArchive::generateMHTMLPart( |
stringBuilder.append("\r\n"); |
CString asciiString = stringBuilder.toString().utf8(); |
- outputBuffer.append(asciiString.data(), asciiString.length()); |
- if (!strcmp(contentEncoding, binary)) { |
+ // Best guess for a reserved size. It should work well for binary and base64 |
+ // (see https://en.wikipedia.org/wiki/Base64#MIME); not so much for |
+ // quoted-printable which is harder to estimate. |
+ std::size_t expectedFinalSize = outputBuffer.size() + asciiString.length(); |
+ if (encoding == Encoding::Base64) |
+ expectedFinalSize += static_cast<std::size_t>(resource.data->size() * 1.37); |
+ else |
+ expectedFinalSize += resource.data->size(); |
+ outputBuffer.reserve(expectedFinalSize); |
+ |
+ outputBuffer.insert(outputBuffer.end(), asciiString.data(), asciiString.data() + asciiString.length()); |
+ |
+ if (encoding == Encoding::Binary) { |
const char* data; |
size_t position = 0; |
while (size_t length = resource.data->getSomeData(data, position)) { |
- outputBuffer.append(data, length); |
+ outputBuffer.insert(outputBuffer.end(), data, data + length); |
position += length; |
} |
} else { |
@@ -204,12 +231,13 @@ void MHTMLArchive::generateMHTMLPart( |
const char* data = resource.data->data(); |
size_t dataLength = resource.data->size(); |
Vector<char> encodedData; |
- if (!strcmp(contentEncoding, quotedPrintable)) { |
+ if (encoding == Encoding::QuotedPrintable) { |
quotedPrintableEncode(data, dataLength, encodedData); |
- outputBuffer.append(encodedData.data(), encodedData.size()); |
- outputBuffer.append("\r\n", 2u); |
+ outputBuffer.insert(outputBuffer.end(), encodedData.data(), encodedData.data() + encodedData.size()); |
+ outputBuffer.push_back('\r'); |
+ outputBuffer.push_back('\n'); |
} else { |
- ASSERT(!strcmp(contentEncoding, base64)); |
+ DCHECK(encoding == Encoding::Base64); |
carlosk
2016/10/03 23:51:05
I replaced ASSERT with DCHECK here as I understand
|
// We are not specifying insertLFs = true below as it would cut the lines with LFs and MHTML requires CRLFs. |
base64Encode(data, dataLength, encodedData); |
const size_t maximumLineLength = 76; |
@@ -217,8 +245,9 @@ void MHTMLArchive::generateMHTMLPart( |
size_t encodedDataLength = encodedData.size(); |
do { |
size_t lineLength = std::min(encodedDataLength - index, maximumLineLength); |
- outputBuffer.append(encodedData.data() + index, lineLength); |
- outputBuffer.append("\r\n", 2u); |
+ outputBuffer.insert(outputBuffer.end(), encodedData.data() + index, encodedData.data() + index + lineLength); |
+ outputBuffer.push_back('\r'); |
+ outputBuffer.push_back('\n'); |
index += maximumLineLength; |
} while (index < encodedDataLength); |
} |
@@ -227,11 +256,12 @@ void MHTMLArchive::generateMHTMLPart( |
void MHTMLArchive::generateMHTMLFooter( |
const String& boundary, |
- SharedBuffer& outputBuffer) |
+ std::vector<char>& outputBuffer) |
{ |
ASSERT(!boundary.isEmpty()); |
CString asciiString = String("--" + boundary + "--\r\n").utf8(); |
- outputBuffer.append(asciiString.data(), asciiString.length()); |
+ outputBuffer.reserve(outputBuffer.size() + asciiString.length()); |
+ outputBuffer.insert(outputBuffer.end(), asciiString.data(), asciiString.data() + asciiString.length()); |
} |
void MHTMLArchive::setMainResource(ArchiveResource* mainResource) |