diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e023bb71..b521ee7f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,6 +107,7 @@ engine/nonblocking/nonblocking-mutex.vala engine/nonblocking/nonblocking-variants.vala engine/rfc822/rfc822-error.vala +engine/rfc822/rfc822-gmime-filter-flowed.vala engine/rfc822/rfc822-mailbox-addresses.vala engine/rfc822/rfc822-mailbox-address.vala engine/rfc822/rfc822-message.vala diff --git a/src/engine/rfc822/rfc822-gmime-filter-flowed.vala b/src/engine/rfc822/rfc822-gmime-filter-flowed.vala new file mode 100644 index 00000000..597cc71f --- /dev/null +++ b/src/engine/rfc822/rfc822-gmime-filter-flowed.vala @@ -0,0 +1,57 @@ +/* Copyright 2012 Yorba Foundation +* +* This software is licensed under the GNU Lesser General Public License +* (version 2.1 or later). See the COPYING file in this distribution. +*/ + +class GMime.FilterFlowed : GMime.Filter { + public FilterFlowed() { + } + + public override GMime.Filter copy() { + return new FilterFlowed(); + } + + public override void filter(char[] inbuf, size_t prespace, out unowned char[] outbuf, out size_t outprespace) { + StringBuilder builder = new StringBuilder(); + string text = (string) inbuf; + string[] lines = text.split("\r\n"); + int cur_quote_level = 0; + bool was_flowed = false; + bool first_line = true; + foreach(string line in lines) { + int quote_level = 0; + while(line[quote_level] == '>') + quote_level++; + if(first_line) { + builder.append(line); + } else if (quote_level == cur_quote_level && was_flowed) { + builder.append(line[quote_level:line.length-1]); + } else { + builder.append("\r\n"); + builder.append(line); + } + was_flowed = line[line.length - 1] == ' ' && line != "-- "; + cur_quote_level = quote_level; + first_line = false; + } + + set_size(builder.str.length, false); + Memory.copy(this.outbuf, builder.str.data, builder.str.length); + + outbuf = this.outbuf; + outprespace = this.outpre; + } + + public override void complete(char[] inbuf, size_t prespace, out unowned char[] outbuf, out size_t outprespace) { + if(inbuf != null && inbuf.length != 0) { + this.filter (inbuf, prespace, out outbuf, out outprespace); + } else { + outbuf = this.outbuf; + outprespace = this.outpre; + } + } + + public override void reset() { + } +} diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala index 27154083..6b62f31c 100644 --- a/src/engine/rfc822/rfc822-message.vala +++ b/src/engine/rfc822/rfc822-message.vala @@ -465,6 +465,9 @@ public class Geary.RFC822.Message : Object { if (charset == null) charset = DEFAULT_ENCODING; stream_filter.add(new GMime.FilterCharset(charset, "UTF8")); + string? format = part.get_content_type_parameter("format"); + if (format == "flowed") + stream_filter.add(new GMime.FilterFlowed()); } wrapper.write_to_stream(stream_filter); diff --git a/vapi/gmime-2.6.vapi b/vapi/gmime-2.6.vapi index 4d4c200b..7d83a12e 100644 --- a/vapi/gmime-2.6.vapi +++ b/vapi/gmime-2.6.vapi @@ -291,24 +291,24 @@ namespace GMime { } [CCode (cheader_filename = "gmime/gmime.h")] public class Filter : GLib.Object { - public weak string backbuf; + public char* backbuf; public size_t backlen; public size_t backsize; - public weak string outbuf; + [CCode (array_length_cname = "outsize", array_length_type = "size_t")] + public char[] outbuf; public size_t outpre; - public weak string outptr; - public weak string outreal; - public size_t outsize; + public char* outptr; + public char* outreal; [CCode (has_construct_function = false)] protected Filter (); [CCode (cname = "g_mime_filter_backup")] - public void backup (string data, size_t length); + public void backup ([CCode (array_length_pos = 1.1, array_length_type = "size_t")] char[] data); [CCode (cname = "g_mime_filter_complete")] - public virtual void complete (string inbuf, size_t inlen, size_t prespace, out unowned string outbuf, size_t outlen, size_t outprespace); + public virtual void complete ([CCode (array_length_pos = 1.1, array_length_type = "size_t")] char[] inbuf, size_t prespace, [CCode (array_length_pos = 3.1, array_length_type = "size_t")] out unowned char[] outbuf, out size_t outprespace); [CCode (cname = "g_mime_filter_copy")] - public virtual unowned GMime.Filter copy (); + public virtual GMime.Filter copy (); [CCode (cname = "g_mime_filter_filter")] - public virtual void filter (string inbuf, size_t inlen, size_t prespace, out unowned string outbuf, size_t outlen, size_t outprespace); + public virtual void filter ([CCode (array_length_pos = 1.1, array_length_type = "size_t")] char[] inbuf, size_t prespace, [CCode (array_length_pos = 3.1, array_length_type = "size_t")] out unowned char[] outbuf, out size_t outprespace); [CCode (cname = "g_mime_filter_reset")] public virtual void reset (); [CCode (cname = "g_mime_filter_set_size")] diff --git a/vapi/gmime-2.6/gmime-2.6.metadata b/vapi/gmime-2.6/gmime-2.6.metadata index 3fae0051..b6986a8f 100644 --- a/vapi/gmime-2.6/gmime-2.6.metadata +++ b/vapi/gmime-2.6/gmime-2.6.metadata @@ -21,6 +21,30 @@ g_mime_utils_header_decode_date.tz_offset is_out="1" nullable="1" g_mime_utils_header_decode_phrase transfer_ownership="1" g_mime_utils_header_decode_text transfer_ownership="1" +# FIXME: there is no keyword "is_protected" +GMimeFilter.backbuf type_name="char*" is_protected="1" +GMimeFilter.backlen is_protected="1" +GMimeFilter.backsize is_protected="1" +GMimeFilter.outbuf is_array="1" type_name="char[]" array_length_cname="outsize" array_length_type="size_t" is_protected="1" +GMimeFilter.outpre is_protected="1" +GMimeFilter.outptr type_name="char*" is_protected="1" +GMimeFilter.outreal type_name="char*" is_protected="1" +GMimeFilter.outsize hidden="1" is_protected="1" + +g_mime_filter_backup.data is_array="1" array_length_pos="1.1" array_length_type="size_t" type_name="char[]" +g_mime_filter_backup.length hidden="1" +g_mime_filter_complete.inbuf is_array="1" array_length_pos="1.1" array_length_type="size_t" type_name="char[]" +g_mime_filter_complete.inlen hidden="1" +g_mime_filter_complete.outbuf is_array="1" array_length_pos="3.1" array_length_type="size_t" type_name="char[]" is_out="1" transfer_ownership="0" +g_mime_filter_complete.outlen hidden="1" +g_mime_filter_complete.outprespace is_out="1" +g_mime_filter_filter.inbuf is_array="1" array_length_pos="1.1" array_length_type="size_t" type_name="char[]" +g_mime_filter_filter.inlen hidden="1" +g_mime_filter_filter.outbuf is_array="1" array_length_pos="3.1" array_length_type="size_t" type_name="char[]" is_out="1" transfer_ownership="0" +g_mime_filter_filter.outlen hidden="1" +g_mime_filter_filter.outprespace is_out="1" +g_mime_filter_copy transfer_ownership="1" + InternetAddress hidden="1" internet_address_* hidden="1" InternetAddress.name hidden="1"