Forward attached emails properly: Closes #6842
This fix required adapting a filter from GMime, which is also licensed LGPL 2.1. A GMime VAPI change was also required.
This commit is contained in:
parent
bd4823afbd
commit
844963ed0e
4 changed files with 71 additions and 8 deletions
|
|
@ -966,7 +966,7 @@ namespace GMime {
|
|||
[CCode (cname = "g_mime_stream_printf")]
|
||||
public ssize_t printf (string fmt);
|
||||
[CCode (cname = "g_mime_stream_read")]
|
||||
public virtual ssize_t read (string buf, size_t len);
|
||||
public virtual ssize_t read (uint8[] buf);
|
||||
[CCode (cname = "g_mime_stream_reset")]
|
||||
public virtual int reset ();
|
||||
[CCode (cname = "g_mime_stream_seek")]
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ g_mime_part_get_content_part nullable="1"
|
|||
g_mime_signer_next name="get_next"
|
||||
g_mime_stream_mem_new_with_buffer.buffer is_array="1" array_length_pos="1.0" type_name="uint8[]"
|
||||
g_mime_stream_mem_new_with_buffer.len hidden="1"
|
||||
g_mime_stream_read.buf is_array="1" type_name="uint8[]"
|
||||
g_mime_stream_read.len hidden="1"
|
||||
g_mime_utils_decode_8bit transfer_ownership="1"
|
||||
g_mime_utils_header_decode_date type_name="time_t"
|
||||
g_mime_utils_header_decode_date.tz_offset is_out="1" nullable="1"
|
||||
|
|
|
|||
|
|
@ -112,28 +112,28 @@ public class Geary.RFC822.Message : BaseObject {
|
|||
// Body: text format (optional)
|
||||
GMime.Part? body_text = null;
|
||||
if (email.body_text != null) {
|
||||
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(
|
||||
new GMime.StreamMem.with_buffer(email.body_text.data),
|
||||
GMime.StreamMem stream = new GMime.StreamMem.with_buffer(email.body_text.data);
|
||||
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(stream,
|
||||
GMime.ContentEncoding.DEFAULT);
|
||||
|
||||
body_text = new GMime.Part();
|
||||
body_text.set_content_type(new GMime.ContentType.from_string("text/plain; charset=utf-8; format=flowed"));
|
||||
body_text.set_content_object(content);
|
||||
body_text.set_content_encoding(body_text.get_best_content_encoding(
|
||||
body_text.set_content_encoding(Geary.RFC822.Utils.get_best_content_encoding(stream,
|
||||
GMime.EncodingConstraint.7BIT));
|
||||
}
|
||||
|
||||
// Body: HTML format (also optional)
|
||||
GMime.Part? body_html = null;
|
||||
if (email.body_html != null) {
|
||||
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(
|
||||
new GMime.StreamMem.with_buffer(email.body_html.data),
|
||||
GMime.StreamMem stream = new GMime.StreamMem.with_buffer(email.body_html.data);
|
||||
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(stream,
|
||||
GMime.ContentEncoding.DEFAULT);
|
||||
|
||||
body_html = new GMime.Part();
|
||||
body_html.set_content_type(new GMime.ContentType.from_string("text/html; charset=utf-8"));
|
||||
body_html.set_content_object(content);
|
||||
body_html.set_content_encoding(body_html.get_best_content_encoding(
|
||||
body_html.set_content_encoding(Geary.RFC822.Utils.get_best_content_encoding(stream,
|
||||
GMime.EncodingConstraint.7BIT));
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +249,8 @@ public class Geary.RFC822.Message : BaseObject {
|
|||
part.set_content_object(new GMime.DataWrapper.with_stream(stream, GMime.ContentEncoding.BINARY));
|
||||
|
||||
// This encoding is the "Content-Transfer-Encoding", which GMime automatically converts to.
|
||||
part.set_content_encoding(part.get_best_content_encoding(GMime.EncodingConstraint.7BIT));
|
||||
part.set_content_encoding(Geary.RFC822.Utils.get_best_content_encoding(stream,
|
||||
GMime.EncodingConstraint.7BIT));
|
||||
|
||||
return part;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright 2011-2013 Yorba Foundation
|
||||
* Portions copyright (C) 2000-2013 Jeffrey Stedfast
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
|
|
@ -227,5 +228,64 @@ public bool comp_char_arr_slice(char[] array, uint start, string comp) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is adapted from the GMimeFilterBest source in the GMime
|
||||
* library (gmime-filter-best.c) by Jeffrey Stedfast, LGPL 2.1.
|
||||
*/
|
||||
public GMime.ContentEncoding get_best_content_encoding(GMime.Stream stream,
|
||||
GMime.EncodingConstraint constraint) {
|
||||
int count0 = 0, count8 = 0, linelen = 0, maxline = 0;
|
||||
size_t total = 0, readlen;
|
||||
uint8[] buffer = new uint8[1024];
|
||||
|
||||
while ((readlen = stream.read(buffer)) > 0) {
|
||||
total += readlen;
|
||||
for(int i = 0; i < readlen; i++) {
|
||||
char c = (char) buffer[i];
|
||||
if (c == '\n') {
|
||||
maxline = maxline > linelen ? maxline : linelen;
|
||||
linelen = 0;
|
||||
} else {
|
||||
linelen++;
|
||||
if (c == 0)
|
||||
count0++;
|
||||
else if ((c & 0x80) != 0)
|
||||
count8++;
|
||||
}
|
||||
}
|
||||
}
|
||||
maxline = maxline > linelen ? maxline : linelen;
|
||||
|
||||
GMime.ContentEncoding encoding = GMime.ContentEncoding.DEFAULT;
|
||||
switch (constraint) {
|
||||
case GMime.EncodingConstraint.7BIT:
|
||||
if (count0 > 0) {
|
||||
encoding = GMime.ContentEncoding.BASE64;
|
||||
} else if (count8 > 0) {
|
||||
if (count8 > (int) (total * 0.17))
|
||||
encoding = GMime.ContentEncoding.BASE64;
|
||||
else
|
||||
encoding = GMime.ContentEncoding.QUOTEDPRINTABLE;
|
||||
} else if (maxline > 998) {
|
||||
encoding = GMime.ContentEncoding.QUOTEDPRINTABLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case GMime.EncodingConstraint.8BIT:
|
||||
if (count0 > 0)
|
||||
encoding = GMime.ContentEncoding.BASE64;
|
||||
else if (maxline > 998)
|
||||
encoding = GMime.ContentEncoding.QUOTEDPRINTABLE;
|
||||
break;
|
||||
|
||||
case GMime.EncodingConstraint.BINARY:
|
||||
if (count0 + count8 > 0)
|
||||
encoding = GMime.ContentEncoding.BINARY;
|
||||
break;
|
||||
}
|
||||
|
||||
return encoding;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue