mirror of https://github.com/adamdruppe/arsd.git
Merge pull request #429 from Inkrementator/EMail_Remove_Allocation
Remove an allocation when decoding base64
This commit is contained in:
commit
ad7d0501e7
39
email.d
39
email.d
|
@ -10,6 +10,8 @@ import std.base64;
|
||||||
import std.string;
|
import std.string;
|
||||||
import std.range;
|
import std.range;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
|
import std.array;
|
||||||
|
import std.algorithm.iteration;
|
||||||
|
|
||||||
import arsd.characterencodings;
|
import arsd.characterencodings;
|
||||||
|
|
||||||
|
@ -876,18 +878,10 @@ class IncomingEmailMessage {
|
||||||
break;
|
break;
|
||||||
case "base64":
|
case "base64":
|
||||||
if(textMessageBody.length) {
|
if(textMessageBody.length) {
|
||||||
// alas, phobos' base64 decoder cannot accept ranges, so we have to allocate here
|
textMessageBody = textMessageBody.decodeBase64Mime.convertToUtf8Lossy(charset);
|
||||||
char[] mmb;
|
|
||||||
mmb.reserve(textMessageBody.length);
|
|
||||||
foreach (char ch; textMessageBody) if (ch > ' ' && ch < 127) mmb ~= ch;
|
|
||||||
textMessageBody = convertToUtf8Lossy(Base64.decode(mmb), charset);
|
|
||||||
}
|
}
|
||||||
if(htmlMessageBody.length) {
|
if(htmlMessageBody.length) {
|
||||||
// alas, phobos' base64 decoder cannot accept ranges, so we have to allocate here
|
htmlMessageBody = htmlMessageBody.decodeBase64Mime.convertToUtf8Lossy(charset);
|
||||||
char[] mmb;
|
|
||||||
mmb.reserve(htmlMessageBody.length);
|
|
||||||
foreach (char ch; htmlMessageBody) if (ch > ' ' && ch < 127) mmb ~= ch;
|
|
||||||
htmlMessageBody = convertToUtf8Lossy(Base64.decode(mmb), charset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1182,6 +1176,31 @@ string encodeBase64Mime(const(ubyte[]) content, string LINESEP = "\r\n") {
|
||||||
return cast(immutable(char[]))content.chunks(SOURCE_CHUNK_LENGTH).base64encode.join(LINESEP);
|
return cast(immutable(char[]))content.chunks(SOURCE_CHUNK_LENGTH).base64encode.join(LINESEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Base64 range decoder UFCS helper.
|
||||||
|
alias base64decode = Base64.decoder;
|
||||||
|
|
||||||
|
/// Base64 decoder, ignoring linebreaks which are mandated by RFC2045
|
||||||
|
immutable(ubyte[]) decodeBase64Mime(string encodedPart) {
|
||||||
|
return cast(immutable(ubyte[])) encodedPart
|
||||||
|
.byChar // prevent Autodecoding, which will break Base64 decoder. Since its base64, it's guarenteed to be 7bit ascii
|
||||||
|
.filter!((c) => (c != '\r') & (c != '\n'))
|
||||||
|
.base64decode
|
||||||
|
.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest {
|
||||||
|
// Mime base64 roundtrip
|
||||||
|
import std.algorithm.comparison;
|
||||||
|
string source = chain(
|
||||||
|
repeat('n', 1200), //long line
|
||||||
|
"\r\n",
|
||||||
|
"äöü\r\n",
|
||||||
|
"ඞ\rn",
|
||||||
|
).byChar.array;
|
||||||
|
assert( source.representation.encodeBase64Mime.decodeBase64Mime.equal(source));
|
||||||
|
}
|
||||||
|
|
||||||
unittest {
|
unittest {
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
|
Loading…
Reference in New Issue