This source file includes following definitions.
- lengthOfLineEndingAtIndex
- quotedPrintableEncode
- quotedPrintableEncode
- quotedPrintableDecode
- quotedPrintableDecode
#include "config.h"
#include "platform/text/QuotedPrintable.h"
#include "wtf/ASCIICType.h"
namespace WebCore {
static const size_t maximumLineLength = 76;
static const char crlfLineEnding[] = "\r\n";
static size_t lengthOfLineEndingAtIndex(const char* input, size_t inputLength, size_t index)
{
ASSERT_WITH_SECURITY_IMPLICATION(index < inputLength);
if (input[index] == '\n')
return 1;
if (input[index] == '\r') {
if ((index + 1) == inputLength || input[index + 1] != '\n')
return 1;
return 2;
}
return 0;
}
void quotedPrintableEncode(const Vector<char>& in, Vector<char>& out)
{
quotedPrintableEncode(in.data(), in.size(), out);
}
void quotedPrintableEncode(const char* input, size_t inputLength, Vector<char>& out)
{
out.clear();
out.reserveCapacity(inputLength);
size_t currentLineLength = 0;
for (size_t i = 0; i < inputLength; ++i) {
bool isLastCharacter = (i == inputLength - 1);
char currentCharacter = input[i];
bool requiresEncoding = false;
if ((currentCharacter < ' ' || currentCharacter > '~' || currentCharacter == '=') && currentCharacter != '\t')
requiresEncoding = true;
if (!requiresEncoding && (currentCharacter == '\t' || currentCharacter == ' ') && (isLastCharacter || lengthOfLineEndingAtIndex(input, inputLength, i + 1)))
requiresEncoding = true;
if (!isLastCharacter) {
size_t lengthOfLineEnding = lengthOfLineEndingAtIndex(input, inputLength, i);
if (lengthOfLineEnding) {
out.append(crlfLineEnding, strlen(crlfLineEnding));
currentLineLength = 0;
i += (lengthOfLineEnding - 1);
continue;
}
}
size_t lengthOfEncodedCharacter = 1;
if (requiresEncoding)
lengthOfEncodedCharacter += 2;
if (!isLastCharacter)
lengthOfEncodedCharacter += 1;
if (currentLineLength + lengthOfEncodedCharacter > maximumLineLength) {
out.append('=');
out.append(crlfLineEnding, strlen(crlfLineEnding));
currentLineLength = 0;
}
if (requiresEncoding) {
out.append('=');
out.append(upperNibbleToASCIIHexDigit(currentCharacter));
out.append(lowerNibbleToASCIIHexDigit(currentCharacter));
currentLineLength += 3;
} else {
out.append(currentCharacter);
currentLineLength++;
}
}
}
void quotedPrintableDecode(const Vector<char>& in, Vector<char>& out)
{
quotedPrintableDecode(in.data(), in.size(), out);
}
void quotedPrintableDecode(const char* data, size_t dataLength, Vector<char>& out)
{
out.clear();
if (!dataLength)
return;
for (size_t i = 0; i < dataLength; ++i) {
char currentCharacter = data[i];
if (currentCharacter != '=') {
out.append(currentCharacter);
continue;
}
if (dataLength - i < 3) {
out.append(currentCharacter);
continue;
}
char upperCharacter = data[++i];
char lowerCharacter = data[++i];
if (upperCharacter == '\r' && lowerCharacter == '\n')
continue;
if (!isASCIIHexDigit(upperCharacter) || !isASCIIHexDigit(lowerCharacter)) {
out.append('=');
out.append(upperCharacter);
out.append(lowerCharacter);
continue;
}
out.append(static_cast<char>(toASCIIHexValue(upperCharacter, lowerCharacter)));
}
}
}