[geary/mjog/rfc822-cleanup-part-n: 6/9] Geary.Email: Rework RFC822.Message.get_email into an Email constructor




commit 6af5b2f0e633e89052a51dc0e0154cee14519cf1
Author: Michael Gratton <mike vee net>
Date:   Tue Jun 30 14:36:49 2020 +1000

    Geary.Email: Rework RFC822.Message.get_email into an Email constructor
    
    This also allows us to remove the message buffer hack in Message.

 src/engine/api/geary-email.vala       | 58 ++++++++++++++++++++++++++---------
 src/engine/outbox/outbox-folder.vala  |  2 +-
 src/engine/rfc822/rfc822-message.vala | 44 +-------------------------
 3 files changed, 45 insertions(+), 59 deletions(-)
---
diff --git a/src/engine/api/geary-email.vala b/src/engine/api/geary-email.vala
index d6a0fe6de..ff75d21d1 100644
--- a/src/engine/api/geary-email.vala
+++ b/src/engine/api/geary-email.vala
@@ -326,12 +326,39 @@ public class Geary.Email : BaseObject, EmailHeaderSet {
      */
     public Geary.Email.Field fields { get; private set; default = Field.NONE; }
 
+
     private Geary.RFC822.Message? message = null;
 
+
+    /** Constructs a new, empty email with the given id. */
     public Email(Geary.EmailIdentifier id) {
         this.id = id;
     }
 
+    /**
+     * Construct a Geary.Email from a complete RFC822 message.
+     */
+    public Email.from_message(EmailIdentifier id,
+                              RFC822.Message message) throws GLib.Error {
+        this(id);
+        set_send_date(message.date);
+        set_originators(message.from, message.sender, message.reply_to);
+        set_receivers(message.to, message.cc, message.bcc);
+        set_full_references(
+            message.message_id, message.in_reply_to, message.references
+        );
+        set_message_subject(message.subject);
+        set_message_header(message.get_header());
+        set_message_body(message.get_body());
+        string preview = message.get_preview();
+        if (!String.is_empty_or_whitespace(preview)) {
+            set_message_preview(new RFC822.PreviewText.from_string(preview));
+        }
+
+        // Set this last as the methods above would reset it otherwise
+        this.message = message;
+    }
+
     /**
      * Determines if this message is unread from its flags.
      *
@@ -367,6 +394,7 @@ public class Geary.Email : BaseObject, EmailHeaderSet {
 
     public void set_send_date(Geary.RFC822.Date? date) {
         this.date = date;
+        this.message = null;
 
         fields |= Field.DATE;
     }
@@ -387,6 +415,7 @@ public class Geary.Email : BaseObject, EmailHeaderSet {
         this.from = from;
         this.sender = sender;
         this.reply_to = reply_to;
+        this.message = null;
 
         fields |= Field.ORIGINATORS;
     }
@@ -396,6 +425,7 @@ public class Geary.Email : BaseObject, EmailHeaderSet {
         this.to = to;
         this.cc = cc;
         this.bcc = bcc;
+        this.message = null;
 
         fields |= Field.RECEIVERS;
     }
@@ -405,30 +435,28 @@ public class Geary.Email : BaseObject, EmailHeaderSet {
         this.message_id = message_id;
         this.in_reply_to = in_reply_to;
         this.references = references;
+        this.message = null;
 
         fields |= Field.REFERENCES;
     }
 
     public void set_message_subject(Geary.RFC822.Subject? subject) {
         this.subject = subject;
+        this.message = null;
 
         fields |= Field.SUBJECT;
     }
 
     public void set_message_header(Geary.RFC822.Header header) {
         this.header = header;
-
-        // reset the message object, which is built from this text
-        message = null;
+        this.message = null;
 
         fields |= Field.HEADER;
     }
 
     public void set_message_body(Geary.RFC822.Text body) {
         this.body = body;
-
-        // reset the message object, which is built from this text
-        message = null;
+        this.message = null;
 
         fields |= Field.BODY;
     }
@@ -478,15 +506,15 @@ public class Geary.Email : BaseObject, EmailHeaderSet {
      * thrown.
      */
     public Geary.RFC822.Message get_message() throws EngineError, Error {
-        if (message != null)
-            return message;
-
-        if (!fields.fulfills(REQUIRED_FOR_MESSAGE))
-            throw new EngineError.INCOMPLETE_MESSAGE("Parsed email requires HEADER and BODY");
-
-        message = new Geary.RFC822.Message.from_parts(header, body);
-
-        return message;
+        if (this.message == null) {
+            if (!fields.fulfills(REQUIRED_FOR_MESSAGE)) {
+                throw new EngineError.INCOMPLETE_MESSAGE(
+                    "Parsed email requires HEADER and BODY"
+                );
+            }
+            this.message = new Geary.RFC822.Message.from_parts(header, body);
+        }
+        return this.message;
     }
 
     /**
diff --git a/src/engine/outbox/outbox-folder.vala b/src/engine/outbox/outbox-folder.vala
index 8a0835562..6e4024777 100644
--- a/src/engine/outbox/outbox-folder.vala
+++ b/src/engine/outbox/outbox-folder.vala
@@ -387,7 +387,7 @@ public class Geary.Outbox.Folder :
             email = new Email(row.outbox_id);
         } else {
             RFC822.Message message = new RFC822.Message.from_buffer(row.message);
-            email = message.get_email(row.outbox_id);
+            email = new Geary.Email.from_message(row.outbox_id, message);
 
             // TODO: Determine message's total size (header + body) to
             // store in Properties.
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index fc830839b..61a0f3d66 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -100,15 +100,9 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
     /** Value of the X-Mailer header. */
     public string? mailer { get; protected set; default = null; }
 
+    // The backing store for this message. Used to access body parts.
     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 Error {
         GMime.Parser parser = new GMime.Parser.with_stream(
@@ -120,10 +114,6 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
         }
 
         this.from_gmime_message(message);
-
-        // See the declaration of these fields for why we do this.
-        this.body_buffer = full.buffer;
-        this.body_offset = (size_t) parser.get_headers_end();
     }
 
     public Message.from_gmime_message(GMime.Message message)
@@ -203,10 +193,6 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
         }
 
         this.from_gmime_message(message);
-
-        // See the declaration of these fields for why we do this.
-        this.body_buffer = body.buffer;
-        this.body_offset = 0;
     }
 
     public async Message.from_composed_email(Geary.ComposedEmail email,
@@ -590,34 +576,6 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
         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 GLib.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(
-            message.get_headers(Geary.RFC822.get_format_options()))));
-        email.set_send_date(date);
-        email.set_originators(from, sender, reply_to);
-        email.set_receivers(to, cc, bcc);
-        email.set_full_references(message_id, in_reply_to, references);
-        email.set_message_subject(subject);
-        email.set_message_body(new Geary.RFC822.Text(new Geary.Memory.OffsetBuffer(
-            body_buffer, body_offset)));
-        string preview = get_preview();
-        if (preview != "") {
-            email.set_message_preview(new PreviewText.from_string(preview));
-        }
-        return email;
-    }
-
     /**
      * Generates a preview from the email's message body.
      *


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