[geary/wip/save-sent-713263] Fix double-headers in outbox



commit a1859bafb9ad14848ec6934d3d58311e1be539ef
Author: Charles Lindsay <chaz yorba org>
Date:   Fri Jan 24 16:31:24 2014 -0800

    Fix double-headers in outbox

 po/POTFILES.in                              |    1 +
 src/CMakeLists.txt                          |    1 +
 src/engine/memory/memory-offset-buffer.vala |   40 +++++++++++++++++++++++++++
 src/engine/rfc822/rfc822-message.vala       |   27 +++++++++++++++++-
 4 files changed, 67 insertions(+), 2 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6279475..521a3d5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -277,6 +277,7 @@ src/engine/memory/memory-byte-buffer.vala
 src/engine/memory/memory-empty-buffer.vala
 src/engine/memory/memory-file-buffer.vala
 src/engine/memory/memory-growable-buffer.vala
+src/engine/memory/memory-offset-buffer.vala
 src/engine/memory/memory-string-buffer.vala
 src/engine/memory/memory-unowned-byte-array-buffer.vala
 src/engine/memory/memory-unowned-bytes-buffer.vala
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4c3a45a..4a04d92 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -218,6 +218,7 @@ engine/memory/memory-byte-buffer.vala
 engine/memory/memory-empty-buffer.vala
 engine/memory/memory-file-buffer.vala
 engine/memory/memory-growable-buffer.vala
+engine/memory/memory-offset-buffer.vala
 engine/memory/memory-string-buffer.vala
 engine/memory/memory-unowned-byte-array-buffer.vala
 engine/memory/memory-unowned-bytes-buffer.vala
diff --git a/src/engine/memory/memory-offset-buffer.vala b/src/engine/memory/memory-offset-buffer.vala
new file mode 100644
index 0000000..a7193ee
--- /dev/null
+++ b/src/engine/memory/memory-offset-buffer.vala
@@ -0,0 +1,40 @@
+/* Copyright 2011-2013 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.
+ */
+
+/**
+ * A buffer that's simply an offset into an existing buffer.
+ */
+
+public class Geary.Memory.OffsetBuffer : Geary.Memory.Buffer {
+    /**
+     * { inheritDoc}
+     */
+    public override size_t size { get { return buffer.size - offset; } }
+    
+    /**
+     * { inheritDoc}
+     */
+    public override size_t allocated_size { get { return size; } }
+    
+    private Geary.Memory.Buffer buffer;
+    private size_t offset;
+    private Bytes? bytes = null;
+    
+    public OffsetBuffer(Geary.Memory.Buffer buffer, size_t offset) {
+        assert(offset < buffer.size);
+        this.buffer = buffer;
+        this.offset = offset;
+    }
+    
+    /**
+     * { inheritDoc}
+     */
+    public override Bytes get_bytes() {
+        if (bytes == null)
+            bytes = new Bytes.from_bytes(buffer.get_bytes(), offset, buffer.size - offset);
+        return bytes;
+    }
+}
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index 16117fc..eba1aef 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -33,6 +33,13 @@ public class Geary.RFC822.Message : BaseObject {
     
     private GMime.Message message;
     
+    // Since GMime.Message does a bad job of separating the headers and body (GMime.Message.get_body()
+    // returns the full message, headers and all), we keep a buffer around that points to the body
+    // part from the source.  This is only needed by get_email().  Unfortunately, we can't always
+    // set these easily, so sometimes get_email() won't work.
+    private Memory.Buffer? body_buffer = null;
+    private size_t? body_offset = null;
+    
     public Message(Full full) throws RFC822Error {
         GMime.Parser parser = new GMime.Parser.with_stream(Utils.create_stream_mem(full.buffer));
         
@@ -40,6 +47,10 @@ public class Geary.RFC822.Message : BaseObject {
         if (message == null)
             throw new RFC822Error.INVALID("Unable to parse RFC 822 message");
         
+        // See the declaration of these fields for why we do this.
+        body_buffer = full.buffer;
+        body_offset = (size_t) parser.get_headers_end();
+        
         stock_from_gmime();
     }
     
@@ -70,6 +81,9 @@ public class Geary.RFC822.Message : BaseObject {
         if (message == null)
             throw new RFC822Error.INVALID("Unable to parse RFC 822 message");
         
+        body_buffer = body.buffer;
+        body_offset = 0;
+        
         stock_from_gmime();
     }
 
@@ -239,7 +253,16 @@ public class Geary.RFC822.Message : BaseObject {
         return part;
     }
     
+    /**
+     * Construct a Geary.Email from a Message.  NOTE: this requires you to have created
+     * the Message in such a way that its body_buffer and body_offset fields will be filled
+     * out.  See the various constructors for details.  (Otherwise, we don't have a way
+     * to get the body part directly, because of GMime's shortcomings.)
+     */
     public Geary.Email get_email(Geary.EmailIdentifier id) throws Error {
+        assert(body_buffer != null);
+        assert(body_offset != null);
+        
         Geary.Email email = new Geary.Email(id);
         
         email.set_message_header(new Geary.RFC822.Header(new Geary.Memory.StringBuffer(
@@ -249,8 +272,8 @@ public class Geary.RFC822.Message : BaseObject {
         email.set_receivers(to, cc, bcc);
         email.set_full_references(null, in_reply_to, references);
         email.set_message_subject(subject);
-        email.set_message_body(new Geary.RFC822.Text(new Geary.Memory.StringBuffer(
-            message.get_body().to_string())));
+        email.set_message_body(new Geary.RFC822.Text(new Geary.Memory.OffsetBuffer(
+            body_buffer, body_offset)));
         email.set_message_preview(new Geary.RFC822.PreviewText.from_string(get_preview()));
         
         return email;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]