[gmime] Added a way to set the best encoding for a message



commit 6140b404331e6897d38b4053003fa595ee8cc273
Author: Jeffrey Stedfast <fejj gnome org>
Date:   Thu Oct 1 22:36:53 2009 -0400

    Added a way to set the best encoding for a message
    
    2009-10-01  Jeffrey Stedfast  <fejj novell com>
    
    	* gmime/gmime-filter-best.h: Moved GMimeEncodingConstraint to
    	gmime-encodings.h
    
    	* gmime/gmime-object.c (g_mime_object_encode): New method to
    	calculate and set the best Content-Transfer-Encoding on a mime
    	part and its children.
    
    	* gmime/gmime-part.c (mime_part_encode): Use a GMimeFilterBest to
    	make magic happen.
    
    	* gmime/gmime-message.c (message_encode): Encode our toplevel mime
    	part object.
    
    	* gmime/gmime-multipart.c (multipart_encode): Recurse over our
    	children and encode them.
    
    	* gmime/gmime-multipart-signed.c (multipart_signed_encode):
    	Prevent our base class implementation from iterating over our
    	children.

 ChangeLog                      |   22 ++++++++++++
 gmime/gmime-encodings.h        |   17 +++++++++
 gmime/gmime-filter-best.h      |   17 ---------
 gmime/gmime-message.c          |   12 ++++++
 gmime/gmime-message.h          |    5 ++-
 gmime/gmime-multipart-signed.c |   13 +++++++
 gmime/gmime-multipart.c        |   15 ++++++++
 gmime/gmime-multipart.h        |    3 ++
 gmime/gmime-object.c           |   75 +++++++++++++++++++++++++++-------------
 gmime/gmime-object.h           |    5 +++
 gmime/gmime-part.c             |   26 ++++++++++++++
 11 files changed, 168 insertions(+), 42 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6e75539..43b9bcc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2009-10-01  Jeffrey Stedfast  <fejj novell com>
+
+	* gmime/gmime-filter-best.h: Moved GMimeEncodingConstraint to
+	gmime-encodings.h
+
+	* gmime/gmime-object.c (g_mime_object_encode): New method to
+	calculate and set the best Content-Transfer-Encoding on a mime
+	part and its children.
+
+	* gmime/gmime-part.c (mime_part_encode): Use a GMimeFilterBest to
+	make magic happen.
+
+	* gmime/gmime-message.c (message_encode): Encode our toplevel mime
+	part object.
+
+	* gmime/gmime-multipart.c (multipart_encode): Recurse over our
+	children and encode them.
+
+	* gmime/gmime-multipart-signed.c (multipart_signed_encode):
+	Prevent our base class implementation from iterating over our
+	children.
+
 2009-09-30  Jeffrey Stedfast  <fejj novell com>
 
 	* build/vs2008/*: Made the Project/Solution tree much nicer.
diff --git a/gmime/gmime-encodings.h b/gmime/gmime-encodings.h
index 9ed90a8..fa69568 100644
--- a/gmime/gmime-encodings.h
+++ b/gmime/gmime-encodings.h
@@ -51,6 +51,23 @@ typedef enum {
 } GMimeContentEncoding;
 
 
+/**
+ * GMimeEncodingConstraint:
+ * @GMIME_ENCODING_CONSTRAINT_7BIT: The stream data must fit within the 7bit ASCII range.
+ * @GMIME_ENCODING_CONSTRAINT_8BIT: The stream data may have bytes with the high bit set, but no null bytes.
+ * @GMIME_ENCODING_CONSTRAINT_BINARY: The stream may contain any binary data.
+ *
+ * Used with g_mime_filter_best_encoding() as the 'constraint'
+ * argument. These values provide a means of letting the filter know
+ * what the encoding constraints are for the stream.
+ **/
+typedef enum {
+	GMIME_ENCODING_CONSTRAINT_7BIT,
+	GMIME_ENCODING_CONSTRAINT_8BIT,
+	GMIME_ENCODING_CONSTRAINT_BINARY
+} GMimeEncodingConstraint;
+
+
 GMimeContentEncoding g_mime_content_encoding_from_string (const char *str);
 const char *g_mime_content_encoding_to_string (GMimeContentEncoding encoding);
 
diff --git a/gmime/gmime-filter-best.h b/gmime/gmime-filter-best.h
index b8094d4..1a69acf 100644
--- a/gmime/gmime-filter-best.h
+++ b/gmime/gmime-filter-best.h
@@ -55,23 +55,6 @@ typedef enum {
 
 
 /**
- * GMimeEncodingConstraint:
- * @GMIME_ENCODING_CONSTRAINT_7BIT: The stream data must fit within the 7bit ASCII range.
- * @GMIME_ENCODING_CONSTRAINT_8BIT: The stream data may have bytes with the high bit set, but no null bytes.
- * @GMIME_ENCODING_CONSTRAINT_BINARY: The stream may contain any binary data.
- *
- * Used with g_mime_filter_best_encoding() as the 'constraint'
- * argument. These values provide a means of letting the filter know
- * what the encoding constraints are for the stream.
- **/
-typedef enum {
-	GMIME_ENCODING_CONSTRAINT_7BIT,
-	GMIME_ENCODING_CONSTRAINT_8BIT,
-	GMIME_ENCODING_CONSTRAINT_BINARY
-} GMimeEncodingConstraint;
-
-
-/**
  * GMimeFilterBest:
  * @parent_object: parent #GMimeFilter
  * @flags: #GMimeFilterBestFlags
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 720e92f..45e5d4b 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -60,6 +60,7 @@ static const char *message_get_header (GMimeObject *object, const char *header);
 static gboolean message_remove_header (GMimeObject *object, const char *header);
 static char *message_get_headers (GMimeObject *object);
 static ssize_t message_write_to_stream (GMimeObject *object, GMimeStream *stream);
+static void message_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
 
 static ssize_t write_structured (GMimeStream *stream, const char *name, const char *value);
 static ssize_t write_addrspec (GMimeStream *stream, const char *name, const char *value);
@@ -141,6 +142,7 @@ g_mime_message_class_init (GMimeMessageClass *klass)
 	object_class->get_header = message_get_header;
 	object_class->get_headers = message_get_headers;
 	object_class->write_to_stream = message_write_to_stream;
+	object_class->encode = message_encode;
 }
 
 static void
@@ -1007,6 +1009,16 @@ message_write_to_stream (GMimeObject *object, GMimeStream *stream)
 	return total;
 }
 
+static void
+message_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
+{
+	GMimeMessage *message = (GMimeMessage *) object;
+	
+	if (message->mime_part != NULL)
+		g_mime_object_encode (message->mime_part, constraint);
+}
+
+
 
 /**
  * g_mime_message_new: Create a new MIME Message object
diff --git a/gmime/gmime-message.h b/gmime/gmime-message.h
index d97c78a..e2bad72 100644
--- a/gmime/gmime-message.h
+++ b/gmime/gmime-message.h
@@ -25,10 +25,11 @@
 #include <stdarg.h>
 #include <time.h>
 
+#include <gmime/internet-address.h>
+#include <gmime/gmime-encodings.h>
 #include <gmime/gmime-object.h>
 #include <gmime/gmime-header.h>
 #include <gmime/gmime-stream.h>
-#include <gmime/internet-address.h>
 
 G_BEGIN_DECLS
 
@@ -120,6 +121,8 @@ const char *g_mime_message_get_message_id (GMimeMessage *message);
 GMimeObject *g_mime_message_get_mime_part (GMimeMessage *message);
 void g_mime_message_set_mime_part (GMimeMessage *message, GMimeObject *mime_part);
 
+/* convenience functions */
+
 void g_mime_message_foreach (GMimeMessage *message, GMimeObjectForeachFunc callback,
 			     gpointer user_data);
 
diff --git a/gmime/gmime-multipart-signed.c b/gmime/gmime-multipart-signed.c
index 851865f..5cadafe 100644
--- a/gmime/gmime-multipart-signed.c
+++ b/gmime/gmime-multipart-signed.c
@@ -57,6 +57,9 @@ static void g_mime_multipart_signed_class_init (GMimeMultipartSignedClass *klass
 static void g_mime_multipart_signed_init (GMimeMultipartSigned *mps, GMimeMultipartSignedClass *klass);
 static void g_mime_multipart_signed_finalize (GObject *object);
 
+/* GMimeObject class methods */
+static void multipart_signed_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
+
 
 static GMimeMultipartClass *parent_class = NULL;
 
@@ -89,11 +92,14 @@ g_mime_multipart_signed_get_type (void)
 static void
 g_mime_multipart_signed_class_init (GMimeMultipartSignedClass *klass)
 {
+	GMimeObjectClass *object_class = GMIME_OBJECT_CLASS (klass);
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	
 	parent_class = g_type_class_ref (GMIME_TYPE_MULTIPART);
 	
 	gobject_class->finalize = g_mime_multipart_signed_finalize;
+	
+	object_class->encode = multipart_signed_encode;
 }
 
 static void
@@ -108,6 +114,13 @@ g_mime_multipart_signed_finalize (GObject *object)
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static void
+multipart_signed_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
+{
+	/* Do NOT encode subparts of a multipart/signed */
+	return;
+}
+
 
 /**
  * g_mime_multipart_signed_new:
diff --git a/gmime/gmime-multipart.c b/gmime/gmime-multipart.c
index 4062d56..dae0e33 100644
--- a/gmime/gmime-multipart.c
+++ b/gmime/gmime-multipart.c
@@ -63,6 +63,7 @@ static gboolean multipart_remove_header (GMimeObject *object, const char *header
 static void multipart_set_content_type (GMimeObject *object, GMimeContentType *content_type);
 static char *multipart_get_headers (GMimeObject *object);
 static ssize_t multipart_write_to_stream (GMimeObject *object, GMimeStream *stream);
+static void multipart_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
 
 /* GMimeMultipart class methods */
 static void multipart_clear (GMimeMultipart *multipart);
@@ -124,6 +125,7 @@ g_mime_multipart_class_init (GMimeMultipartClass *klass)
 	object_class->set_content_type = multipart_set_content_type;
 	object_class->get_headers = multipart_get_headers;
 	object_class->write_to_stream = multipart_write_to_stream;
+	object_class->encode = multipart_encode;
 	
 	klass->add = multipart_add;
 	klass->clear = multipart_clear;
@@ -302,6 +304,19 @@ multipart_write_to_stream (GMimeObject *object, GMimeStream *stream)
 	return total;
 }
 
+static void
+multipart_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
+{
+	GMimeMultipart *multipart = (GMimeMultipart *) object;
+	GMimeObject *subpart;
+	int i;
+	
+	for (i = 0; i < g_mime_multipart_get_count (multipart); i++) {
+		subpart = g_mime_multipart_get_part (multipart, i);
+		g_mime_object_encode (subpart, constraint);
+	}
+}
+
 
 /**
  * g_mime_multipart_new:
diff --git a/gmime/gmime-multipart.h b/gmime/gmime-multipart.h
index 98bfca9..cc8498e 100644
--- a/gmime/gmime-multipart.h
+++ b/gmime/gmime-multipart.h
@@ -24,6 +24,7 @@
 
 #include <glib.h>
 
+#include <gmime/gmime-encodings.h>
 #include <gmime/gmime-object.h>
 
 G_BEGIN_DECLS
@@ -105,6 +106,8 @@ int g_mime_multipart_get_count (GMimeMultipart *multipart);
 void g_mime_multipart_set_boundary (GMimeMultipart *multipart, const char *boundary);
 const char *g_mime_multipart_get_boundary (GMimeMultipart *multipart);
 
+/* convenience functions */
+
 void g_mime_multipart_foreach (GMimeMultipart *multipart, GMimeObjectForeachFunc callback,
 			       gpointer user_data);
 
diff --git a/gmime/gmime-object.c b/gmime/gmime-object.c
index bacf929..d926a00 100644
--- a/gmime/gmime-object.c
+++ b/gmime/gmime-object.c
@@ -62,14 +62,15 @@ static void g_mime_object_class_init (GMimeObjectClass *klass);
 static void g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass);
 static void g_mime_object_finalize (GObject *object);
 
-static void prepend_header (GMimeObject *object, const char *name, const char *value);
-static void append_header (GMimeObject *object, const char *name, const char *value);
-static void set_header (GMimeObject *object, const char *name, const char *value);
-static const char *get_header (GMimeObject *object, const char *name);
-static gboolean remove_header (GMimeObject *object, const char *name);
-static void set_content_type (GMimeObject *object, GMimeContentType *content_type);
-static char *get_headers (GMimeObject *object);
-static ssize_t write_to_stream (GMimeObject *object, GMimeStream *stream);
+static void object_prepend_header (GMimeObject *object, const char *name, const char *value);
+static void object_append_header (GMimeObject *object, const char *name, const char *value);
+static void object_set_header (GMimeObject *object, const char *name, const char *value);
+static const char *object_get_header (GMimeObject *object, const char *name);
+static gboolean object_remove_header (GMimeObject *object, const char *name);
+static void object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
+static char *object_get_headers (GMimeObject *object);
+static ssize_t object_write_to_stream (GMimeObject *object, GMimeStream *stream);
+static void object_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
 
 static ssize_t write_content_type (GMimeStream *stream, const char *name, const char *value);
 static ssize_t write_disposition (GMimeStream *stream, const char *name, const char *value);
@@ -120,14 +121,15 @@ g_mime_object_class_init (GMimeObjectClass *klass)
 	
 	object_class->finalize = g_mime_object_finalize;
 	
-	klass->prepend_header = prepend_header;
-	klass->append_header = append_header;
-	klass->remove_header = remove_header;
-	klass->set_header = set_header;
-	klass->get_header = get_header;
-	klass->set_content_type = set_content_type;
-	klass->get_headers = get_headers;
-	klass->write_to_stream = write_to_stream;
+	klass->prepend_header = object_prepend_header;
+	klass->append_header = object_append_header;
+	klass->remove_header = object_remove_header;
+	klass->set_header = object_set_header;
+	klass->get_header = object_get_header;
+	klass->set_content_type = object_set_content_type;
+	klass->get_headers = object_get_headers;
+	klass->write_to_stream = object_write_to_stream;
+	klass->encode = object_encode;
 	
 	type_registry_init ();
 }
@@ -402,7 +404,7 @@ g_mime_object_new_type (const char *type, const char *subtype)
 
 
 static void
-set_content_type (GMimeObject *object, GMimeContentType *content_type)
+object_set_content_type (GMimeObject *object, GMimeContentType *content_type)
 {
 	if (object->content_type) {
 		g_mime_event_remove (object->content_type->priv, (GMimeEventCallback) content_type_changed, object);
@@ -766,7 +768,7 @@ process_header (GMimeObject *object, const char *header, const char *value)
 }
 
 static void
-prepend_header (GMimeObject *object, const char *header, const char *value)
+object_prepend_header (GMimeObject *object, const char *header, const char *value)
 {
 	if (!process_header (object, header, value))
 		g_mime_header_list_prepend (object->headers, header, value);
@@ -792,7 +794,7 @@ g_mime_object_prepend_header (GMimeObject *object, const char *header, const cha
 }
 
 static void
-append_header (GMimeObject *object, const char *header, const char *value)
+object_append_header (GMimeObject *object, const char *header, const char *value)
 {
 	if (!process_header (object, header, value))
 		g_mime_header_list_append (object->headers, header, value);
@@ -819,7 +821,7 @@ g_mime_object_append_header (GMimeObject *object, const char *header, const char
 
 
 static void
-set_header (GMimeObject *object, const char *header, const char *value)
+object_set_header (GMimeObject *object, const char *header, const char *value)
 {
 	if (!process_header (object, header, value))
 		g_mime_header_list_set (object->headers, header, value);
@@ -846,7 +848,7 @@ g_mime_object_set_header (GMimeObject *object, const char *header, const char *v
 
 
 static const char *
-get_header (GMimeObject *object, const char *header)
+object_get_header (GMimeObject *object, const char *header)
 {
 	return g_mime_header_list_get (object->headers, header);
 }
@@ -874,7 +876,7 @@ g_mime_object_get_header (GMimeObject *object, const char *header)
 
 
 static gboolean
-remove_header (GMimeObject *object, const char *header)
+object_remove_header (GMimeObject *object, const char *header)
 {
 	guint i;
 	
@@ -927,7 +929,7 @@ g_mime_object_remove_header (GMimeObject *object, const char *header)
 
 
 static char *
-get_headers (GMimeObject *object)
+object_get_headers (GMimeObject *object)
 {
 	return g_mime_header_list_to_string (object->headers);
 }
@@ -952,7 +954,7 @@ g_mime_object_get_headers (GMimeObject *object)
 
 
 static ssize_t
-write_to_stream (GMimeObject *object, GMimeStream *stream)
+object_write_to_stream (GMimeObject *object, GMimeStream *stream)
 {
 	return -1;
 }
@@ -977,6 +979,31 @@ g_mime_object_write_to_stream (GMimeObject *object, GMimeStream *stream)
 }
 
 
+static void
+object_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
+{
+	return;
+}
+
+
+/**
+ * g_mime_object_encode:
+ * @object: a #GMimeObject
+ * @constraint a #GMimeEncodingConstraint
+ *
+ * Calculates and sets the most efficient Content-Transfer-Encoding
+ * for this #GMimeObject and all child parts based on the @constraint
+ * provided.
+ **/
+void
+g_mime_object_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
+{
+	g_return_if_fail (GMIME_IS_OBJECT (object));
+	
+	return GMIME_OBJECT_GET_CLASS (object)->encode (object, constraint);
+}
+
+
 /**
  * g_mime_object_to_string:
  * @object: a #GMimeObject
diff --git a/gmime/gmime-object.h b/gmime/gmime-object.h
index 0c68a59..8624270 100644
--- a/gmime/gmime-object.h
+++ b/gmime/gmime-object.h
@@ -27,6 +27,7 @@
 
 #include <gmime/gmime-content-type.h>
 #include <gmime/gmime-disposition.h>
+#include <gmime/gmime-encodings.h>
 #include <gmime/gmime-stream.h>
 #include <gmime/gmime-header.h>
 
@@ -76,6 +77,8 @@ struct _GMimeObjectClass {
 	char *       (* get_headers)   (GMimeObject *object);
 	
 	ssize_t      (* write_to_stream) (GMimeObject *object, GMimeStream *stream);
+	
+	void         (* encode) (GMimeObject *object, GMimeEncodingConstraint constraint);
 };
 
 
@@ -128,6 +131,8 @@ char *g_mime_object_get_headers (GMimeObject *object);
 ssize_t g_mime_object_write_to_stream (GMimeObject *object, GMimeStream *stream);
 char *g_mime_object_to_string (GMimeObject *object);
 
+void g_mime_object_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
+
 G_END_DECLS
 
 #endif /* __GMIME_OBJECT_H__ */
diff --git a/gmime/gmime-part.c b/gmime/gmime-part.c
index ceede0f..2f0ef7e 100644
--- a/gmime/gmime-part.c
+++ b/gmime/gmime-part.c
@@ -33,6 +33,7 @@
 #include "gmime-stream-null.h"
 #include "gmime-stream-filter.h"
 #include "gmime-filter-basic.h"
+#include "gmime-filter-best.h"
 #include "gmime-filter-crlf.h"
 #include "gmime-filter-md5.h"
 
@@ -62,6 +63,7 @@ static const char *mime_part_get_header (GMimeObject *object, const char *header
 static gboolean mime_part_remove_header (GMimeObject *object, const char *header);
 static char *mime_part_get_headers (GMimeObject *object);
 static ssize_t mime_part_write_to_stream (GMimeObject *object, GMimeStream *stream);
+static void mime_part_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
 
 /* GMimePart class methods */
 static void set_content_object (GMimePart *mime_part, GMimeDataWrapper *content);
@@ -112,6 +114,7 @@ g_mime_part_class_init (GMimePartClass *klass)
 	object_class->get_header = mime_part_get_header;
 	object_class->get_headers = mime_part_get_headers;
 	object_class->write_to_stream = mime_part_write_to_stream;
+	object_class->encode = mime_part_encode;
 	
 	klass->set_content_object = set_content_object;
 }
@@ -394,6 +397,29 @@ mime_part_write_to_stream (GMimeObject *object, GMimeStream *stream)
 	return total;
 }
 
+static void
+mime_part_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
+{
+	GMimePart *part = (GMimePart *) object;
+	GMimeContentEncoding encoding;
+	GMimeStream *stream, *null;
+	GMimeFilter *filter;
+	
+	filter = g_mime_filter_best_new (GMIME_FILTER_BEST_ENCODING);
+	
+	null = g_mime_stream_null_new ();
+	stream = g_mime_stream_filter_new (null);
+	g_mime_stream_filter_add ((GMimeStreamFilter *) stream, filter);
+	g_object_unref (null);
+	
+	g_mime_object_write_to_stream (object, stream);
+	g_object_unref (stream);
+	
+	encoding = g_mime_filter_best_encoding ((GMimeFilterBest *) filter, constraint);
+	g_mime_part_set_content_encoding (part, encoding);
+	g_object_unref (filter);
+}
+
 
 /**
  * g_mime_part_new:



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