gmime r1310 - in trunk: . docs/reference gmime tests



Author: fejj
Date: Sat May 31 04:10:05 2008
New Revision: 1310
URL: http://svn.gnome.org/viewvc/gmime?rev=1310&view=rev

Log:
2008-05-30  Jeffrey Stedfast  <fejj novell com>

	* gmime/gmime-parser.c: Updated for GMimeHeaderList and
	GMimeObject changes.

	* gmime/gmime-message-partial.c: Updated for GMimeHeaderList and
	GMimeObject changes.

	* gmime/gmime-multipart-encrypted.c: Updated for GMimeHeaderList
	and GMimeObject changes.

	* gmime/gmime-multipart-signed.c: Updated for GMimeHeaderList and
	GMimeObject changes.

	* gmime/gmime-multipart.c: Updated for GMimeHeaderList and
	GMimeObject changes.

	* gmime/gmime-part.c: Updated for GMimeHeaderList and GMimeObject
	changes.

	* gmime/gmime-message.c: Updated for GMimeHeaderList and
	GMimeObject changes.

	* gmime/gmime-object.c (g_mime_object_append_header): Renamed from
	g_mime_object_add_header().
	(g_mime_object_prepend_header): New method.
	(remove_header): Cleanup content-header variables if they get
	removed. Don't allow removal of the Content-Type header.

	* gmime/gmime-header.[c,h]: Renamed GMimeHeader to GMimeHeaderList
	and all of it's methods appropriately. Added a new GMimeHeaderIter
	class for iterating over a header list.
	(g_mime_header_list_remove): Return gboolean specifying whether or
	not a header was removed.
	(g_mime_header_list_get_iter): New function to get a header
	iterator.

A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A



Modified:
   trunk/ChangeLog
   trunk/docs/reference/gmime-sections.txt
   trunk/gmime/gmime-header.c
   trunk/gmime/gmime-header.h
   trunk/gmime/gmime-message-part.c
   trunk/gmime/gmime-message-partial.c
   trunk/gmime/gmime-message.c
   trunk/gmime/gmime-multipart-encrypted.c
   trunk/gmime/gmime-multipart-signed.c
   trunk/gmime/gmime-multipart.c
   trunk/gmime/gmime-object.c
   trunk/gmime/gmime-object.h
   trunk/gmime/gmime-parser.c
   trunk/gmime/gmime-part.c
   trunk/tests/test-parser.c

Modified: trunk/docs/reference/gmime-sections.txt
==============================================================================
--- trunk/docs/reference/gmime-sections.txt	(original)
+++ trunk/docs/reference/gmime-sections.txt	Sat May 31 04:10:05 2008
@@ -569,22 +569,34 @@
 
 <SECTION>
 <FILE>gmime-header</FILE>
-GMimeHeader
+GMimeHeaderIter
+GMimeHeaderList
 GMimeHeaderForeachFunc
 GMimeHeaderWriter
-g_mime_header_new
-g_mime_header_destroy
-g_mime_header_add
-g_mime_header_prepend
-g_mime_header_set
-g_mime_header_get
-g_mime_header_remove
-g_mime_header_write_to_stream
-g_mime_header_to_string
-g_mime_header_foreach
-g_mime_header_has_raw
-g_mime_header_set_raw
-g_mime_header_register_writer
+g_mime_header_iter_copy
+g_mime_header_iter_free
+g_mime_header_iter_next
+g_mime_header_iter_prev
+g_mime_header_iter_is_valid
+g_mime_header_iter_get_offset
+g_mime_header_iter_get_name
+g_mime_header_iter_get_value
+g_mime_header_iter_set_value
+g_mime_header_iter_remove
+g_mime_header_list_new
+g_mime_header_list_destroy
+g_mime_header_list_prepend
+g_mime_header_list_append
+g_mime_header_list_remove
+g_mime_header_list_set
+g_mime_header_list_get
+g_mime_header_list_get_iter
+g_mime_header_list_write_to_stream
+g_mime_header_list_to_string
+g_mime_header_list_foreach
+g_mime_header_list_register_writer
+g_mime_header_list_has_raw
+g_mime_header_list_set_raw
 </SECTION>
 
 <SECTION>
@@ -636,10 +648,11 @@
 g_mime_object_get_content_disposition_parameter
 g_mime_object_set_content_id
 g_mime_object_get_content_id
-g_mime_object_add_header
+g_mime_object_prepend_header
+g_mime_object_append_header
+g_mime_object_remove_header
 g_mime_object_set_header
 g_mime_object_get_header
-g_mime_object_remove_header
 g_mime_object_get_headers
 g_mime_object_write_to_stream
 g_mime_object_to_string

Modified: trunk/gmime/gmime-header.c
==============================================================================
--- trunk/gmime/gmime-header.c	(original)
+++ trunk/gmime/gmime-header.c	Sat May 31 04:10:05 2008
@@ -31,6 +31,8 @@
 #include "gmime-utils.h"
 #include "gmime-stream-mem.h"
 
+#include "list.h"
+
 
 /**
  * SECTION: gmime-header
@@ -42,261 +44,607 @@
  * values.
  **/
 
-struct raw_header {
-	struct raw_header *next;
+
+typedef struct _GMimeHeader GMimeHeader;
+
+struct _GMimeHeaderList {
+	GHashTable *writers;
+	GHashTable *hash;
+	List iters;
+	List list;
+	char *raw;
+};
+
+/**
+ * GMimeHeader:
+ *
+ * A message/rfc822 header.
+ **/
+struct _GMimeHeader {
+	struct _GMimeHeader *next;
+	struct _GMimeHeader *prev;
+	gint64 offset;
 	char *name;
 	char *value;
 };
 
-struct _GMimeHeader {
-	GHashTable *hash;
-	GHashTable *writers;
-	struct raw_header *headers;
-	char *raw;
+struct _GMimeHeaderIter {
+	struct _GMimeHeaderIter *next;
+	struct _GMimeHeaderIter *prev;
+	GMimeHeaderList *headers;
+	GMimeHeader *cursor;
 };
 
 
+static GMimeHeader *g_mime_header_new (const char *name, const char *value, gint64 offset);
+static void g_mime_header_free (GMimeHeader *header);
+
 /**
  * g_mime_header_new:
+ * @name: header name
+ * @value: header value
+ * @offset: file/stream offset for the start of the header (or %-1 if unknown)
  *
- * Creates a new #GMimeHeader object.
+ * Creates a new #GMimeHeader.
  *
- * Returns a new header object.
+ * Returns a new #GMimeHeader with the specified values.
  **/
-GMimeHeader *
-g_mime_header_new (void)
+static GMimeHeader *
+g_mime_header_new (const char *name, const char *value, gint64 offset)
 {
-	GMimeHeader *new;
+	GMimeHeader *header;
 	
-	new = g_new (GMimeHeader, 1);
-	new->hash = g_hash_table_new (g_mime_strcase_hash, g_mime_strcase_equal);
-	new->writers = g_hash_table_new (g_mime_strcase_hash, g_mime_strcase_equal);
-	new->headers = NULL;
-	new->raw = NULL;
+	header = g_new (GMimeHeader, 1);
+	header->name = g_strdup (name);
+	header->value = g_strdup (value);
+	header->offset = offset;
+	header->next = NULL;
+	header->prev = NULL;
 	
-	return new;
+	return header;
 }
 
 
+/**
+ * g_mime_header_free:
+ * @header: a #GMimeHeader
+ *
+ * Frees a single #GMimeHeader node.
+ **/
 static void
-writer_free (gpointer key, gpointer value, gpointer user_data)
+g_mime_header_free (GMimeHeader *header)
 {
-	g_free (key);
+	g_free (header->name);
+	g_free (header->value);
+	g_free (header);
 }
 
 
 /**
- * g_mime_header_destroy:
- * @header: header object
+ * g_mime_header_iter_copy:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Copies a header iterator.
  *
- * Destroy the header object
+ * Returns a new #GMimeHeaderIter which matches @iter's state.
+ **/
+GMimeHeaderIter *
+g_mime_header_iter_copy (GMimeHeaderIter *iter)
+{
+	GMimeHeaderIter *copy;
+	
+	g_return_val_if_fail (iter != NULL, NULL);
+	
+	copy = g_new (GMimeHeaderIter, 1);
+	copy->headers = iter->headers;
+	copy->cursor = iter->cursor;
+	
+	if (iter->headers)
+		list_append (&iter->headers->iters, (ListNode *) copy);
+	
+	return copy;
+}
+
+
+/**
+ * g_mime_header_iter_free:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Frees a #GMimeHeaderIter.
  **/
 void
-g_mime_header_destroy (GMimeHeader *header)
+g_mime_header_iter_free (GMimeHeaderIter *iter)
+{
+	g_return_if_fail (iter != NULL);
+	
+	if (iter->headers)
+		list_unlink ((ListNode *) iter);
+	
+	g_free (iter);
+}
+
+
+/**
+ * g_mime_header_iter_is_valid:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Checks if a #GMimeHeaderIter is valid. An iterator may become
+ * invalid if the #GMimeHeaderList that the iterator refers to changes
+ * or is destroyed.
+ *
+ * Returns %TRUE if @iter is still valid or %FALSE otherwise.
+ **/
+gboolean
+g_mime_header_iter_is_valid (GMimeHeaderIter *iter)
 {
-	if (header) {
-		struct raw_header *h, *n;
+	g_return_val_if_fail (iter != NULL, FALSE);
+	
+	return iter->cursor && iter->cursor->next;
+}
+
+
+/**
+ * g_mime_header_iter_next:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Advances to the next header.
+ *
+ * Returns %TRUE on success or %FALSE otherwise.
+ **/
+gboolean
+g_mime_header_iter_next (GMimeHeaderIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, FALSE);
+	
+	if (!iter->cursor || !iter->cursor->next)
+		return FALSE;
+	
+	iter->cursor = iter->cursor->next;
+	
+	return iter->next != NULL;
+}
+
+
+/**
+ * g_mime_header_iter_next:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Advances to the previous header.
+ *
+ * Returns %TRUE on success or %FALSE otherwise.
+ **/
+gboolean
+g_mime_header_iter_prev (GMimeHeaderIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, FALSE);
+	
+	if (!iter->cursor || !iter->cursor->prev)
+		return FALSE;
+	
+	iter->cursor = iter->cursor->prev;
+	
+	return iter->prev != NULL;
+}
+
+
+/**
+ * g_mime_header_iter_get_offset:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Gets the current header's file/stream offset.
+ *
+ * Returns the file/stream offset or %-1 if unknown or invalid.
+ **/
+gint64
+g_mime_header_iter_get_offset (GMimeHeaderIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, FALSE);
+	
+	if (!iter->cursor || !iter->cursor->next)
+		return -1;
+	
+	return iter->cursor->offset;
+}
+
+
+/**
+ * g_mime_header_iter_get_name:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Gets the current header's name.
+ *
+ * Returns the header name or %NULL if invalid.
+ **/
+const char *
+g_mime_header_iter_get_name (GMimeHeaderIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, NULL);
+	
+	if (!iter->cursor || !iter->cursor->next)
+		return NULL;
+	
+	return iter->cursor->name;
+}
+
+
+/**
+ * g_mime_header_iter_set_value:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Sets the current header's value.
+ *
+ * Returns %TRUE if the value was set or %FALSE otherwise (indicates
+ * invalid iter).
+ **/
+gboolean
+g_mime_header_iter_set_value (GMimeHeaderIter *iter, const char *value)
+{
+	g_return_val_if_fail (iter != NULL, FALSE);
+	
+	if (!iter->cursor || !iter->cursor->next)
+		return FALSE;
+	
+	g_free (iter->cursor->value);
+	iter->cursor->value = g_strdup (value);
+	
+	g_mime_header_list_set_raw (iter->headers, NULL);
+	
+	return TRUE;
+}
+
+
+/**
+ * g_mime_header_iter_get_value:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Gets the current header's name.
+ *
+ * Returns the header name or %NULL if invalid.
+ **/
+const char *
+g_mime_header_iter_get_value (GMimeHeaderIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, NULL);
+	
+	if (!iter->cursor || !iter->cursor->next)
+		return NULL;
+	
+	return iter->cursor->value;
+}
+
+
+/**
+ * g_mime_header_iter_remove:
+ * @iter: a #GMimeHeaderIter
+ *
+ * Removes the current header from the references #GMimeHeaderList.
+ *
+ * Returns %TRUE on success or %FALSE otherwise
+ **/
+gboolean
+g_mime_header_iter_remove (GMimeHeaderIter *iter)
+{
+	GMimeHeader *header, *next;
+	GMimeHeaderList *headers;
+	char *name;
+	
+	g_return_val_if_fail (iter != NULL, FALSE);
+	
+	if (!iter->cursor || !iter->cursor->next)
+		return FALSE;
+	
+	/* save iter state */
+	next = iter->cursor->next;
+	name = iter->cursor->name;
+	headers = iter->headers;
+	
+	if (!(header = g_hash_table_lookup (headers->hash, name)))
+		return FALSE;
+	
+	if (iter->cursor == header) {
+		/* update the header lookup table */
+		GMimeHeader *node = iter->cursor->next;
+		
+		g_hash_table_remove (headers->hash, name);
+		
+		while (node->next) {
+			if (!g_ascii_strcasecmp (node->name, name)) {
+				/* enter this node into the lookup table */
+				g_hash_table_insert (headers->hash, node->name, node);
+				break;
+			}
+			
+			node = node->next;
+		}
+	}
+	
+	/* remove/free the header */
+	list_unlink ((ListNode *) iter->cursor);
+	g_mime_header_free (iter->cursor);
+	
+	/* restore iter state */
+	iter->headers = headers;
+	iter->cursor = next;
+	
+	return TRUE;
+}
+
+
+/**
+ * g_mime_header_list_invalidate_iters:
+ * @headers: a #GMimeHeaderList
+ * @header: a #GMimeHeader
+ *
+ * Invalidate all outstanding iterators that are currently referencing
+ * @header. If @header is NULL, then invalidate all iterators.
+ **/
+static void
+g_mime_header_list_invalidate_iters (GMimeHeaderList *headers, GMimeHeader *header)
+{
+	GMimeHeaderIter *iter, *next;
+	
+	/* invalidate all our outstanding iterators matching @header */
+	iter = (GMimeHeaderIter *) headers->iters.head;
+	while (iter->next) {
+		next = iter->next;
 		
-		h = header->headers;
-		while (h) {
-			g_free (h->name);
-			g_free (h->value);
-			n = h->next;
-			g_free (h);
-			h = n;
+		if (!header || iter->cursor == header) {
+			/* invalidate this iter */
+			list_unlink ((ListNode *) iter);
+			iter->headers = NULL;
+			iter->cursor = NULL;
 		}
 		
-		g_hash_table_destroy (header->hash);
-		g_hash_table_foreach (header->writers, writer_free, NULL);
-		g_hash_table_destroy (header->writers);
-		g_free (header->raw);
-		g_free (header);
+		iter = next;
 	}
 }
 
 
 /**
- * g_mime_header_set:
- * @header: header object
- * @name: header name
- * @value: header value
+ * g_mime_header_list_new:
+ *
+ * Creates a new #GMimeHeaderList object.
+ *
+ * Returns a new header list object.
+ **/
+GMimeHeaderList *
+g_mime_header_list_new (void)
+{
+	GMimeHeaderList *headers;
+	
+	headers = g_new (GMimeHeaderList, 1);
+	headers->writers = g_hash_table_new_full (g_mime_strcase_hash,
+						  g_mime_strcase_equal,
+						  g_free, NULL);
+	headers->hash = g_hash_table_new (g_mime_strcase_hash,
+					  g_mime_strcase_equal);
+	list_init (&headers->iters);
+	list_init (&headers->list);
+	headers->raw = NULL;
+	
+	return headers;
+}
+
+
+/**
+ * g_mime_header_list_destroy:
+ * @headers: a #GMimeHeaderList
  *
- * Set the value of the specified header. If @value is %NULL and the
- * header, @name, had not been previously set, a space will be set
- * aside for it (useful for setting the order of headers before values
- * can be obtained for them) otherwise the header will be unset.
+ * Destroy the header list.
  **/
 void
-g_mime_header_set (GMimeHeader *header, const char *name, const char *value)
+g_mime_header_list_destroy (GMimeHeaderList *headers)
 {
-	struct raw_header *h, *n;
+	GMimeHeader *header, *next;
+	GMimeHeaderIter *iter;
 	
-	g_return_if_fail (header != NULL);
-	g_return_if_fail (name != NULL);
+	if (!headers)
+		return;
 	
-	if ((h = g_hash_table_lookup (header->hash, name))) {
-		g_free (h->value);
-		h->value = g_strdup (value);
-	} else {
-		n = g_new (struct raw_header, 1);
-		n->next = NULL;
-		n->name = g_strdup (name);
-		n->value = g_strdup (value);
-		
-		h = header->headers;
-		while (h && h->next)
-			h = h->next;
-		
-		if (h != NULL)
-			h->next = n;
-		else
-			header->headers = n;
-		
-		g_hash_table_insert (header->hash, n->name, n);
+	/* invalidate all our outstanding iterators */
+	g_mime_header_list_invalidate_iters (headers, NULL);
+	
+	header = (GMimeHeader *) headers->list.head;
+	while (header->next) {
+		next = header->next;
+		g_mime_header_free (header);
+		header = next;
 	}
 	
-	g_free (header->raw);
-	header->raw = NULL;
+	g_hash_table_destroy (headers->writers);
+	g_hash_table_destroy (headers->hash);
+	g_free (headers->raw);
+	g_free (headers);
 }
 
 
 /**
- * g_mime_header_add:
- * @header: header object
+ * g_mime_header_list_prepend:
+ * @headers: a #GMimeHeaderList
  * @name: header name
  * @value: header value
  *
- * Adds a header. If @value is %NULL, a space will be set aside for it
- * (useful for setting the order of headers before values can be
- * obtained for them) otherwise the header will be unset.
+ * Prepends a header. If @value is %NULL, a space will be set aside
+ * for it (useful for setting the order of headers before values can
+ * be obtained for them) otherwise the header will be unset.
  **/
 void
-g_mime_header_add (GMimeHeader *header, const char *name, const char *value)
+g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value)
 {
-	struct raw_header *h, *n;
+	GMimeHeader *header;
 	
-	g_return_if_fail (header != NULL);
+	g_return_if_fail (headers != NULL);
 	g_return_if_fail (name != NULL);
 	
-	n = g_new (struct raw_header, 1);
-	n->next = NULL;
-	n->name = g_strdup (name);
-	n->value = g_strdup (value);
+	header = g_mime_header_new (name, value, -1);
+	list_append (&headers->list, (ListNode *) header);
+	g_hash_table_replace (headers->hash, header->name, header);
 	
-	h = header->headers;
-	while (h && h->next)
-		h = h->next;
-	
-	if (h)
-		h->next = n;
-	else
-		header->headers = n;
-	
-	if (!g_hash_table_lookup (header->hash, name))
-		g_hash_table_insert (header->hash, n->name, n);
-	
-	g_free (header->raw);
-	header->raw = NULL;
+	g_free (headers->raw);
+	headers->raw = NULL;
 }
 
 
 /**
- * g_mime_header_prepend:
- * @header: header object
+ * g_mime_header_list_append:
+ * @headers: a #GMimeHeaderList
  * @name: header name
  * @value: header value
  *
- * Adds a header to the head of the list. If @value is %NULL, a space
- * will be set aside for it (useful for setting the order of headers
- * before values can be obtained for them) otherwise the header will
- * be unset.
+ * Appends a header. If @value is %NULL, a space will be set aside for it
+ * (useful for setting the order of headers before values can be
+ * obtained for them) otherwise the header will be unset.
  **/
 void
-g_mime_header_prepend (GMimeHeader *header, const char *name, const char *value)
+g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value)
 {
-	struct raw_header *n;
+	GMimeHeader *header;
 	
-	g_return_if_fail (header != NULL);
+	g_return_if_fail (headers != NULL);
 	g_return_if_fail (name != NULL);
 	
-	n = g_new (struct raw_header, 1);
-	n->next = header->headers;
-	n->name = g_strdup (name);
-	n->value = g_strdup (value);
-	header->headers = n;
+	header = g_mime_header_new (name, value, -1);
+	list_append (&headers->list, (ListNode *) header);
 	
-	if (!g_hash_table_lookup (header->hash, name))
-		g_hash_table_insert (header->hash, n->name, n);
+	if (!g_hash_table_lookup (headers->hash, name))
+		g_hash_table_insert (headers->hash, header->name, header);
 	
-	g_free (header->raw);
-	header->raw = NULL;
+	g_free (headers->raw);
+	headers->raw = NULL;
 }
 
 
 /**
- * g_mime_header_get:
- * @header: header object
+ * g_mime_header_list_get:
+ * @headers: a #GMimeHeaderList
  * @name: header name
  *
- * Gets the value of the header requested.
+ * Gets the value of the first header with the name requested.
  *
  * Returns the value of the header requested.
  **/
 const char *
-g_mime_header_get (const GMimeHeader *header, const char *name)
+g_mime_header_list_get (const GMimeHeaderList *headers, const char *name)
 {
-	const struct raw_header *h;
+	const GMimeHeader *header;
 	
-	g_return_val_if_fail (header != NULL, NULL);
+	g_return_val_if_fail (headers != NULL, NULL);
 	g_return_val_if_fail (name != NULL, NULL);
 	
-	h = g_hash_table_lookup (header->hash, name);
+	if (!(header = g_hash_table_lookup (headers->hash, name)))
+		return NULL;
 	
-	return h ? h->value : NULL;
+	return header->value;
 }
 
 
 /**
- * g_mime_header_remove:
- * @header: header object
+ * g_mime_header_list_set:
+ * @headers: a #GMimeHeaderList
  * @name: header name
+ * @value: header value
  *
- * Remove the specified header.
+ * Set the value of the first header with the name specified. If
+ * @value is %NULL and the header, @name, had not been previously set,
+ * a space will be set aside for it (useful for setting the order of
+ * headers before values can be obtained for them) otherwise the
+ * header will be unset.
  **/
 void
-g_mime_header_remove (GMimeHeader *header, const char *name)
+g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value)
 {
-	struct raw_header *h, *n;
+	GMimeHeader *header;
 	
-	g_return_if_fail (header != NULL);
+	g_return_if_fail (headers != NULL);
 	g_return_if_fail (name != NULL);
 	
-	if ((h = g_hash_table_lookup (header->hash, name))) {
-		/* remove the header */
-		g_hash_table_remove (header->hash, name);
-		n = header->headers;
-		
-		if (h == n) {
-			header->headers = h->next;
-		} else {
-			while (n->next != h)
-				n = n->next;
-			
-			n->next = h->next;
+	if ((header = g_hash_table_lookup (headers->hash, name))) {
+		g_free (header->value);
+		header->value = g_strdup (value);
+	} else {
+		header = g_mime_header_new (name, value, -1);
+		list_append (&headers->list, (ListNode *) header);
+		g_hash_table_insert (headers->hash, header->name, header);
+	}
+	
+	g_free (headers->raw);
+	headers->raw = NULL;
+}
+
+
+/**
+ * g_mime_header_list_remove:
+ * @headers: a #GMimeHeaderList
+ * @name: header name
+ *
+ * Remove the specified header.
+ *
+ * Returns %TRUE if the header was successfully removed or %FALSE if
+ * the specified header could not be found.
+ **/
+gboolean
+g_mime_header_list_remove (GMimeHeaderList *headers, const char *name)
+{
+	GMimeHeader *header, *node;
+	
+	g_return_if_fail (headers != NULL);
+	g_return_if_fail (name != NULL);
+	
+	if (!(header = g_hash_table_lookup (headers->hash, name)))
+		return FALSE;
+	
+	/* look for another header with the same name... */
+	node = header->next;
+	while (node->next) {
+		if (!g_ascii_strcasecmp (node->name, name)) {
+			/* enter this node into the lookup table */
+			g_hash_table_replace (headers->hash, node->name, node);
+			break;
 		}
 		
-		g_free (h->name);
-		g_free (h->value);
-		g_free (h);
+		node = node->next;
 	}
 	
-	g_free (header->raw);
-	header->raw = NULL;
+	/* invalidate all our outstanding iterators matching @header */
+	g_mime_header_list_invalidate_iters (headers, header);
+	
+	/* remove/free the header */
+	list_unlink ((ListNode *) header);
+	g_mime_header_free (header);
+	
+	g_free (headers->raw);
+	headers->raw = NULL;
+}
+
+
+/**
+ * g_mime_header_list_get_iter:
+ * @headers: a #GMimeHeaderList
+ *
+ * Gets a new iterator for traversing @headers.
+ *
+ * Returns a new #GMimeHeaderIter which must be freed using
+ * g_mime_header_iter_free() when finished with it.
+ **/
+GMimeHeaderIter *
+g_mime_header_list_get_iter (GMimeHeaderList *headers)
+{
+	GMimeHeaderIter *iter;
+	
+	g_return_val_if_fail (headers != NULL, NULL);
+	
+	iter = g_new (GMimeHeaderIter, 1);
+	iter->cursor = (GMimeHeader *) headers->list.head;
+	iter->headers = headers;
+	
+	list_append (&headers->iters, (ListNode *) iter);
+	
+	return iter;
 }
 
 
 static ssize_t
-write_default (GMimeStream *stream, const char *name, const char *value)
+default_writer (GMimeStream *stream, const char *name, const char *value)
 {
 	ssize_t nwritten;
 	char *val;
@@ -310,8 +658,8 @@
 
 
 /**
- * g_mime_header_write_to_stream:
- * @header: header object
+ * g_mime_header_list_write_to_stream:
+ * @headers: a #GMimeHeaderList
  * @stream: output stream
  *
  * Write the headers to a stream.
@@ -319,34 +667,34 @@
  * Returns the number of bytes written or %-1 on fail.
  **/
 ssize_t
-g_mime_header_write_to_stream (const GMimeHeader *header, GMimeStream *stream)
+g_mime_header_list_write_to_stream (const GMimeHeaderList *headers, GMimeStream *stream)
 {
-	GMimeHeaderWriter header_write;
 	ssize_t nwritten, total = 0;
-	struct raw_header *h;
+	GMimeHeaderWriter writer;
+	GHashTable *writers;
+	GMimeHeader *header;
 	
-	g_return_val_if_fail (header != NULL, -1);
+	g_return_val_if_fail (headers != NULL, -1);
 	g_return_val_if_fail (stream != NULL, -1);
 	
-	if (header->raw)
-		return g_mime_stream_write_string (stream, header->raw);
+	if (headers->raw)
+		return g_mime_stream_write_string (stream, headers->raw);
 	
-	h = header->headers;
-	while (h) {
-		if (h->value) {
-			header_write = g_hash_table_lookup (header->writers, h->name);
-			if (header_write)
-				nwritten = (*header_write) (stream, h->name, h->value);
-			else
-				nwritten = write_default (stream, h->name, h->value);
+	header = (GMimeHeader *) headers->list.head;
+	writers = headers->writers;
+	
+	while (header->next) {
+		if (header->value) {
+			if (!(writer = g_hash_table_lookup (writers, header->name)))
+				writer = default_writer;
 			
-			if (nwritten == -1)
+			if ((nwritten = (* writer) (stream, header->name, header->value)) == -1)
 				return -1;
 			
 			total += nwritten;
 		}
 		
-		h = h->next;
+		header = header->next;
 	}
 	
 	return total;
@@ -354,27 +702,30 @@
 
 
 /**
- * g_mime_header_to_string:
- * @header: header object
+ * g_mime_header_list_to_string:
+ * @headers: a #GMimeHeaderList
  *
  * Allocates a string buffer containing the raw rfc822 headers
- * contained in @header.
+ * contained in @headers.
  *
- * Returns a string containing the header block
+ * Returns a string containing the header block.
  **/
 char *
-g_mime_header_to_string (const GMimeHeader *header)
+g_mime_header_list_to_string (const GMimeHeaderList *headers)
 {
 	GMimeStream *stream;
 	GByteArray *array;
 	char *str;
 	
-	g_return_val_if_fail (header != NULL, NULL);
+	g_return_val_if_fail (headers != NULL, NULL);
+	
+	if (headers->raw)
+		return g_strdup (headers->raw);
 	
 	array = g_byte_array_new ();
 	stream = g_mime_stream_mem_new ();
 	g_mime_stream_mem_set_byte_array (GMIME_STREAM_MEM (stream), array);
-	g_mime_header_write_to_stream (header, stream);
+	g_mime_header_list_write_to_stream (headers, stream);
 	g_object_unref (stream);
 	
 	g_byte_array_append (array, (unsigned char *) "", 1);
@@ -386,30 +737,32 @@
 
 
 /**
- * g_mime_header_foreach:
- * @header: header object
+ * g_mime_header_list_foreach:
+ * @headers: a #GMimeHeaderList
  * @func: function to be called for each header.
  * @user_data: User data to be passed to the func.
  *
  * Calls @func for each header name/value pair.
  */
 void
-g_mime_header_foreach (const GMimeHeader *header, GMimeHeaderForeachFunc func, gpointer user_data)
+g_mime_header_list_foreach (const GMimeHeaderList *headers, GMimeHeaderForeachFunc func, gpointer user_data)
 {
-	const struct raw_header *h;
+	const GMimeHeader *header;
 	
-	g_return_if_fail (header != NULL);
-	g_return_if_fail (header->hash != NULL);
+	g_return_if_fail (headers != NULL);
 	g_return_if_fail (func != NULL);
 	
-	for (h = header->headers; h != NULL; h = h->next)
-		(*func) (h->name, h->value, user_data);
+	header = (const GMimeHeader *) headers->list.head;
+	while (header->next) {
+		(*func) (header->name, header->value, user_data);
+		header = header->next;
+	}
 }
 
 
 /**
- * g_mime_header_register_writer:
- * @header: header object
+ * g_mime_header_list_register_writer:
+ * @headers: a #GMimeHeaderList
  * @name: header name
  * @writer: writer function
  *
@@ -418,54 +771,54 @@
  * the default header folding style for a particular header.
  **/
 void
-g_mime_header_register_writer (GMimeHeader *header, const char *name, GMimeHeaderWriter writer)
+g_mime_header_list_register_writer (GMimeHeaderList *headers, const char *name, GMimeHeaderWriter writer)
 {
 	gpointer okey, oval;
 	
-	g_return_if_fail (header != NULL);
+	g_return_if_fail (headers != NULL);
 	g_return_if_fail (name != NULL);
 	
-	if (g_hash_table_lookup (header->writers, name)) {
-		g_hash_table_lookup_extended (header->writers, name, &okey, &oval);
-		g_hash_table_remove (header->writers, name);
+	if (g_hash_table_lookup (headers->writers, name)) {
+		g_hash_table_lookup_extended (headers->writers, name, &okey, &oval);
+		g_hash_table_remove (headers->writers, name);
 		g_free (okey);
 	}
 	
 	if (writer)
-		g_hash_table_insert (header->writers, g_strdup (name), writer);
+		g_hash_table_insert (headers->writers, g_strdup (name), writer);
 }
 
 
 
 /**
- * g_mime_header_set_raw:
- * @header: header object
+ * g_mime_header_list_set_raw:
+ * @headers: a #GMimeHeaderList
  * @raw: raw mime part header
  *
  * Set the raw header.
  **/
 void
-g_mime_header_set_raw (GMimeHeader *header, const char *raw)
+g_mime_header_list_set_raw (GMimeHeaderList *headers, const char *raw)
 {
-	g_return_if_fail (header != NULL);
+	g_return_if_fail (headers != NULL);
 	
-	g_free (header->raw);
-	header->raw = raw ? g_strdup (raw) : NULL;
+	g_free (headers->raw);
+	headers->raw = raw ? g_strdup (raw) : NULL;
 }
 
 
 /**
- * g_mime_header_has_raw:
- * @header: ehader object
+ * g_mime_header_list_has_raw:
+ * @headers: a #GMimeHeaderList
  *
- * Gets whether or not a raw header has been set on @header.
+ * Gets whether or not a raw header has been set on @headers.
  *
  * Returns %TRUE if a raw header is set or %FALSE otherwise.
  **/
 gboolean
-g_mime_header_has_raw (GMimeHeader *header)
+g_mime_header_list_has_raw (const GMimeHeaderList *headers)
 {
-	g_return_val_if_fail (header != NULL, FALSE);
+	g_return_val_if_fail (headers != NULL, FALSE);
 	
-	return header->raw ? TRUE : FALSE;
+	return headers->raw ? TRUE : FALSE;
 }

Modified: trunk/gmime/gmime-header.h
==============================================================================
--- trunk/gmime/gmime-header.h	(original)
+++ trunk/gmime/gmime-header.h	Sat May 31 04:10:05 2008
@@ -28,21 +28,33 @@
 G_BEGIN_DECLS
 
 /**
- * GMimeHeader:
+ * GMimeHeaderIter:
  *
- * A message or mime-part header.
+ * A message or mime-part header iterator.
  **/
-typedef struct _GMimeHeader GMimeHeader;
+typedef struct _GMimeHeaderIter GMimeHeaderIter;
+
+GMimeHeaderIter *g_mime_header_iter_copy (GMimeHeaderIter *iter);
+void g_mime_header_iter_free (GMimeHeaderIter *iter);
+
+gboolean g_mime_header_iter_is_valid (GMimeHeaderIter *iter);
+
+gboolean g_mime_header_iter_next (GMimeHeaderIter *iter);
+gboolean g_mime_header_iter_prev (GMimeHeaderIter *iter);
+
+gint64 g_mime_header_iter_get_offset (GMimeHeaderIter *iter);
+const char *g_mime_header_iter_get_name (GMimeHeaderIter *iter);
+gboolean g_mime_header_iter_set_value (GMimeHeaderIter *iter, const char *value);
+const char *g_mime_header_iter_get_value (GMimeHeaderIter *iter);
+gboolean g_mime_header_iter_remove (GMimeHeaderIter *iter);
+
 
 /**
- * GMimeHeaderForeachFunc:
- * @name: The field name.
- * @value: The field value.
- * @user_data: The user-supplied callback data.
+ * GMimeHeaderList:
  *
- * Function signature for the callback to g_mime_header_foreach().
+ * A message or mime-part header.
  **/
-typedef void (* GMimeHeaderForeachFunc) (const char *name, const char *value, gpointer user_data);
+typedef struct _GMimeHeaderList GMimeHeaderList;
 
 
 /**
@@ -58,33 +70,38 @@
  **/
 typedef ssize_t (* GMimeHeaderWriter) (GMimeStream *stream, const char *name, const char *value);
 
+ /**
+  * GMimeHeaderForeachFunc:
+  * @name: The field name.
+  * @value: The field value.
+  * @user_data: The user-supplied callback data.
+  *
+  * Function signature for the callback to g_mime_header_list_foreach().
+  **/
+typedef void (* GMimeHeaderForeachFunc) (const char *name, const char *value, gpointer user_data);
 
-GMimeHeader *g_mime_header_new (void);
-
-void g_mime_header_destroy (GMimeHeader *header);
-
-void g_mime_header_set (GMimeHeader *header, const char *name, const char *value);
-
-void g_mime_header_add (GMimeHeader *header, const char *name, const char *value);
-
-void g_mime_header_prepend (GMimeHeader *header, const char *name, const char *value);
-
-const char *g_mime_header_get (const GMimeHeader *header, const char *name);
 
-void g_mime_header_remove (GMimeHeader *header, const char *name);
+GMimeHeaderList *g_mime_header_list_new (void);
 
-ssize_t g_mime_header_write_to_stream (const GMimeHeader *header, GMimeStream *stream);
+void g_mime_header_list_destroy (GMimeHeaderList *headers);
 
-char *g_mime_header_to_string (const GMimeHeader *header);
+void g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value);
+void g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value);
+void g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value);
+const char *g_mime_header_list_get (const GMimeHeaderList *headers, const char *name);
+gboolean g_mime_header_list_remove (GMimeHeaderList *headers, const char *name);
 
-void g_mime_header_foreach (const GMimeHeader *header, GMimeHeaderForeachFunc func, gpointer user_data);
+GMimeHeaderIter *g_mime_header_list_get_iter (GMimeHeaderList *headers);
 
-void g_mime_header_register_writer (GMimeHeader *header, const char *name, GMimeHeaderWriter writer);
+void g_mime_header_list_register_writer (GMimeHeaderList *headers, const char *name, GMimeHeaderWriter writer);
+ssize_t g_mime_header_list_write_to_stream (const GMimeHeaderList *headers, GMimeStream *stream);
+char *g_mime_header_list_to_string (const GMimeHeaderList *headers);
 
+void g_mime_header_list_foreach (const GMimeHeaderList *headers, GMimeHeaderForeachFunc func, gpointer user_data);
 
 /* for internal use only */
-void g_mime_header_set_raw (GMimeHeader *header, const char *raw);
-gboolean g_mime_header_has_raw (GMimeHeader *header);
+void g_mime_header_list_set_raw (GMimeHeaderList *headers, const char *raw);
+gboolean g_mime_header_list_has_raw (const GMimeHeaderList *headers);
 
 G_END_DECLS
 

Modified: trunk/gmime/gmime-message-part.c
==============================================================================
--- trunk/gmime/gmime-message-part.c	(original)
+++ trunk/gmime/gmime-message-part.c	Sat May 31 04:10:05 2008
@@ -48,10 +48,11 @@
 
 /* GMimeObject class methods */
 static void message_part_init (GMimeObject *object);
-static void message_part_add_header (GMimeObject *object, const char *header, const char *value);
+static void message_part_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void message_part_append_header (GMimeObject *object, const char *header, const char *value);
 static void message_part_set_header (GMimeObject *object, const char *header, const char *value);
 static const char *message_part_get_header (GMimeObject *object, const char *header);
-static void message_part_remove_header (GMimeObject *object, const char *header);
+static gboolean message_part_remove_header (GMimeObject *object, const char *header);
 static void message_part_set_content_type (GMimeObject *object, GMimeContentType *content_type);
 static char *message_part_get_headers (GMimeObject *object);
 static ssize_t message_part_write_to_stream (GMimeObject *object, GMimeStream *stream);
@@ -96,10 +97,11 @@
 	gobject_class->finalize = g_mime_message_part_finalize;
 	
 	object_class->init = message_part_init;
-	object_class->add_header = message_part_add_header;
+	object_class->prepend_header = message_part_prepend_header;
+	object_class->append_header = message_part_append_header;
+	object_class->remove_header = message_part_remove_header;
 	object_class->set_header = message_part_set_header;
 	object_class->get_header = message_part_get_header;
-	object_class->remove_header = message_part_remove_header;
 	object_class->set_content_type = message_part_set_content_type;
 	object_class->get_headers = message_part_get_headers;
 	object_class->write_to_stream = message_part_write_to_stream;
@@ -131,13 +133,21 @@
 }
 
 static void
-message_part_add_header (GMimeObject *object, const char *header, const char *value)
+message_part_prepend_header (GMimeObject *object, const char *header, const char *value)
+{
+	/* Make sure that the header is a Content-* header, else it
+           doesn't belong on a message part */
+	if (!g_ascii_strncasecmp ("Content-", header, 8))
+		GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+}
+
+static void
+message_part_append_header (GMimeObject *object, const char *header, const char *value)
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a message part */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
+		GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
 }
 
 static void
@@ -149,7 +159,6 @@
 	
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a message part */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
 		GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
 }
@@ -159,21 +168,21 @@
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a message part */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
 		return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
 	else
 		return NULL;
 }
 
-static void
+static gboolean
 message_part_remove_header (GMimeObject *object, const char *header)
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a message part */
+	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
+		return FALSE;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 static void
@@ -196,7 +205,7 @@
 	ssize_t nwritten, total = 0;
 	
 	/* write the content headers */
-	if ((nwritten = g_mime_header_write_to_stream (object->headers, stream)) == -1)
+	if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
 		return -1;
 	
 	total += nwritten;

Modified: trunk/gmime/gmime-message-partial.c
==============================================================================
--- trunk/gmime/gmime-message-partial.c	(original)
+++ trunk/gmime/gmime-message-partial.c	Sat May 31 04:10:05 2008
@@ -49,8 +49,11 @@
 
 /* GMimeObject class methods */
 static void message_partial_init (GMimeObject *object);
-static void message_partial_add_header (GMimeObject *object, const char *header, const char *value);
+static void message_partial_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void message_partial_append_header (GMimeObject *object, const char *header, const char *value);
 static void message_partial_set_header (GMimeObject *object, const char *header, const char *value);
+static const char *message_partial_get_header (GMimeObject *object, const char *header);
+static gboolean message_partial_remove_header (GMimeObject *object, const char *header);
 static void message_partial_set_content_type (GMimeObject *object, GMimeContentType *content_type);
 
 
@@ -93,8 +96,11 @@
 	gobject_class->finalize = g_mime_message_partial_finalize;
 	
 	object_class->init = message_partial_init;
-	object_class->add_header = message_partial_add_header;
+	object_class->prepend_header = message_partial_prepend_header;
+	object_class->append_header = message_partial_append_header;
+	object_class->remove_header = message_partial_remove_header;
 	object_class->set_header = message_partial_set_header;
+	object_class->get_header = message_partial_get_header;
 	object_class->set_content_type = message_partial_set_content_type;
 }
 
@@ -124,17 +130,23 @@
 }
 
 static void
-message_partial_add_header (GMimeObject *object, const char *header, const char *value)
+message_partial_prepend_header (GMimeObject *object, const char *header, const char *value)
 {
 	/* RFC 1864 states that you cannot set a Content-MD5 on a message part */
 	if (!g_ascii_strcasecmp ("Content-MD5", header))
 		return;
 	
-	/* Make sure that the header is a Content-* header, else it
-           doesn't belong on a mime part */
+	GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+}
+
+static void
+message_partial_append_header (GMimeObject *object, const char *header, const char *value)
+{
+	/* RFC 1864 states that you cannot set a Content-MD5 on a message part */
+	if (!g_ascii_strcasecmp ("Content-MD5", header))
+		return;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
+	GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
 }
 
 static void
@@ -144,11 +156,27 @@
 	if (!g_ascii_strcasecmp ("Content-MD5", header))
 		return;
 	
-	/* Make sure that the header is a Content-* header, else it
-           doesn't belong on a mime part */
+	GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
+}
+
+static const char *
+message_partial_get_header (GMimeObject *object, const char *header)
+{
+	/* RFC 1864 states that you cannot set a Content-MD5 on a message part */
+	if (!g_ascii_strcasecmp ("Content-MD5", header))
+		return NULL;
+	
+	return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
+}
+
+static gboolean
+message_partial_remove_header (GMimeObject *object, const char *header)
+{
+	/* RFC 1864 states that you cannot set a Content-MD5 on a message part */
+	if (!g_ascii_strcasecmp ("Content-MD5", header))
+		return FALSE;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 static void
@@ -362,7 +390,7 @@
 	GMimeMessage *message = (GMimeMessage *) user_data;
 	
 	if (value)
-		g_mime_object_add_header (GMIME_OBJECT (message), name, value);
+		g_mime_object_append_header (GMIME_OBJECT (message), name, value);
 }
 
 static GMimeMessage *
@@ -371,7 +399,7 @@
 	GMimeMessage *message;
 	
 	message = g_mime_message_new (FALSE);
-	g_mime_header_foreach (GMIME_OBJECT (base)->headers, header_copy, message);
+	g_mime_header_list_foreach (GMIME_OBJECT (base)->headers, header_copy, message);
 	
 	return message;
 }

Modified: trunk/gmime/gmime-message.c
==============================================================================
--- trunk/gmime/gmime-message.c	(original)
+++ trunk/gmime/gmime-message.c	Sat May 31 04:10:05 2008
@@ -51,10 +51,11 @@
 
 /* GMimeObject class methods */
 static void message_init (GMimeObject *object);
-static void message_add_header (GMimeObject *object, const char *header, const char *value);
+static void message_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void message_append_header (GMimeObject *object, const char *header, const char *value);
 static void message_set_header (GMimeObject *object, const char *header, const char *value);
 static const char *message_get_header (GMimeObject *object, const char *header);
-static void message_remove_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);
 
@@ -80,7 +81,6 @@
 	"Sender",
 	"To",
 	"Cc",
-	NULL
 };
 
 
@@ -120,10 +120,11 @@
 	gobject_class->finalize = g_mime_message_finalize;
 	
 	object_class->init = message_init;
-	object_class->add_header = message_add_header;
+	object_class->prepend_header = message_prepend_header;
+	object_class->append_header = message_append_header;
+	object_class->remove_header = message_remove_header;
 	object_class->set_header = message_set_header;
 	object_class->get_header = message_get_header;
-	object_class->remove_header = message_remove_header;
 	object_class->get_headers = message_get_headers;
 	object_class->write_to_stream = message_write_to_stream;
 }
@@ -131,6 +132,8 @@
 static void
 g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass)
 {
+	GMimeHeaderList *headers = ((GMimeObject *) message)->headers;
+	
 	message->from = NULL;
 	message->reply_to = NULL;
 	message->recipients = g_hash_table_new (g_str_hash, g_str_equal);
@@ -140,22 +143,22 @@
 	message->message_id = NULL;
 	message->mime_part = NULL;
 	
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Sender", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "From", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "To", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Cc", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Bcc", write_addrspec);
-	
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Resent-Sender", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Resent-From", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Resent-To", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Resent-Cc", write_addrspec);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Resent-Bcc", write_addrspec);
-	
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Subject", write_subject);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Received", write_received);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "Message-Id", write_msgid);
-	g_mime_header_register_writer (((GMimeObject *) message)->headers, "References", write_structured);
+	g_mime_header_list_register_writer (headers, "Sender", write_addrspec);
+	g_mime_header_list_register_writer (headers, "From", write_addrspec);
+	g_mime_header_list_register_writer (headers, "To", write_addrspec);
+	g_mime_header_list_register_writer (headers, "Cc", write_addrspec);
+	g_mime_header_list_register_writer (headers, "Bcc", write_addrspec);
+	
+	g_mime_header_list_register_writer (headers, "Resent-Sender", write_addrspec);
+	g_mime_header_list_register_writer (headers, "Resent-From", write_addrspec);
+	g_mime_header_list_register_writer (headers, "Resent-To", write_addrspec);
+	g_mime_header_list_register_writer (headers, "Resent-Cc", write_addrspec);
+	g_mime_header_list_register_writer (headers, "Resent-Bcc", write_addrspec);
+	
+	g_mime_header_list_register_writer (headers, "Subject", write_subject);
+	g_mime_header_list_register_writer (headers, "Received", write_received);
+	g_mime_header_list_register_writer (headers, "Message-Id", write_msgid);
+	g_mime_header_list_register_writer (headers, "References", write_structured);
 }
 
 static gboolean
@@ -609,7 +612,7 @@
 	HEADER_UNKNOWN
 };
 
-static char *headers[] = {
+static const char *message_headers[] = {
 	"From",
 	"Reply-To",
 	"To",
@@ -618,7 +621,6 @@
 	"Subject",
 	"Date",
 	"Message-Id",
-	NULL
 };
 
 static gboolean
@@ -629,8 +631,8 @@
 	int offset, i;
 	time_t date;
 	
-	for (i = 0; headers[i]; i++) {
-		if (!g_ascii_strcasecmp (headers[i], header))
+	for (i = 0; i < G_N_ELEMENTS (message_headers); i++) {
+		if (!g_ascii_strcasecmp (message_headers[i], header))
 			break;
 	}
 	
@@ -673,70 +675,96 @@
 		break;
 	default:
 		return FALSE;
-		break;
 	}
 	
 	return TRUE;
 }
 
 static void
-message_add_header (GMimeObject *object, const char *header, const char *value)
+message_prepend_header (GMimeObject *object, const char *header, const char *value)
 {
+	GMimeMessage *message = (GMimeMessage *) object;
+	
 	if (!g_ascii_strcasecmp ("MIME-Version", header))
 		return;
 	
 	/* Make sure that the header is not a Content-* header, else it
            doesn't belong on a message */
+	if (!g_ascii_strncasecmp ("Content-", header, 8))
+		return;
 	
-	if (g_ascii_strncasecmp ("Content-", header, 8)) {
-		if (process_header (object, header, value))
-			g_mime_header_add (object->headers, header, value);
-		else
-			GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
-	}
+	if (!process_header (object, header, value))
+		GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+	else
+		g_mime_header_list_prepend (object->headers, header, value);
 	
-	if (((GMimeMessage *) object)->mime_part)
-		g_mime_header_set_raw (((GMimeMessage *) object)->mime_part->headers, NULL);
+	if (message->mime_part)
+		g_mime_header_list_set_raw (message->mime_part->headers, NULL);
+}
+
+static void
+message_append_header (GMimeObject *object, const char *header, const char *value)
+{
+	GMimeMessage *message = (GMimeMessage *) object;
+	
+	if (!g_ascii_strcasecmp ("MIME-Version", header))
+		return;
+	
+	/* Make sure that the header is not a Content-* header, else it
+           doesn't belong on a message */
+	if (!g_ascii_strncasecmp ("Content-", header, 8))
+		return;
+	
+	if (!process_header (object, header, value))
+		GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
+	else
+		g_mime_header_list_append (object->headers, header, value);
+	
+	if (message->mime_part)
+		g_mime_header_list_set_raw (message->mime_part->headers, NULL);
 }
 
 static void
 message_set_header (GMimeObject *object, const char *header, const char *value)
 {
+	GMimeMessage *message = (GMimeMessage *) object;
+	
 	if (!g_ascii_strcasecmp ("MIME-Version", header))
 		return;
 	
 	/* Make sure that the header is not a Content-* header, else it
            doesn't belong on a message */
+	if (!g_ascii_strncasecmp ("Content-", header, 8))
+		return;
 	
-	if (g_ascii_strncasecmp ("Content-", header, 8)) {
-		if (process_header (object, header, value))
-			g_mime_header_set (object->headers, header, value);
-		else
-			GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
-	}
+	if (!process_header (object, header, value))
+		GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
+	else
+		g_mime_header_list_set (object->headers, header, value);
 	
-	if (((GMimeMessage *) object)->mime_part)
-		g_mime_header_set_raw (((GMimeMessage *) object)->mime_part->headers, NULL);
+	if (message->mime_part)
+		g_mime_header_list_set_raw (message->mime_part->headers, NULL);
 }
 
 static const char *
 message_get_header (GMimeObject *object, const char *header)
 {
-	/* Make sure that the header is not a Content-* header, else it
-           doesn't belong on a message */
+	GMimeMessage *message = (GMimeMessage *) object;
 	
 	if (!g_ascii_strcasecmp ("MIME-Version", header))
 		return "1.0";
 	
+	/* Make sure that the header is not a Content-* header, else it
+           doesn't belong on a message */
 	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
 		return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
-	else if (((GMimeMessage *) object)->mime_part)
-		return g_mime_object_get_header (((GMimeMessage *) object)->mime_part, header);
+	else if (message->mime_part)
+		return g_mime_object_get_header (message->mime_part, header);
 	else
 		return NULL;
 }
 
-static void
+static gboolean
 message_remove_header (GMimeObject *object, const char *header)
 {
 	GMimeMessage *message = (GMimeMessage *) object;
@@ -744,16 +772,19 @@
 	int i;
 	
 	if (!g_ascii_strcasecmp ("MIME-Version", header))
-		return;
+		return FALSE;
 	
 	/* Make sure that the header is not a Content-* header, else it
            doesn't belong on a message */
+	if (!g_ascii_strncasecmp ("Content-", header, 8)) {
+		if (message->mime_part)
+			return g_mime_object_remove_header (message->mime_part, header);
+		
+		return FALSE;
+	}
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		return;
-	
-	for (i = 0; headers[i]; i++) {
-		if (!g_ascii_strcasecmp (headers[i], header))
+	for (i = 0; i < G_N_ELEMENTS (message_headers); i++) {
+		if (!g_ascii_strcasecmp (message_headers[i], header))
 			break;
 	}
 	
@@ -797,10 +828,10 @@
 		break;
 	}
 	
-	GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
+	if (message->mime_part)
+		g_mime_header_list_set_raw (message->mime_part->headers, NULL);
 	
-	if (((GMimeMessage *) object)->mime_part)
-		g_mime_header_set_raw (((GMimeMessage *) object)->mime_part->headers, NULL);
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 
@@ -816,14 +847,14 @@
 	stream = g_mime_stream_mem_new ();
 	g_mime_stream_mem_set_byte_array (GMIME_STREAM_MEM (stream), ba);
 	
-	if (message->mime_part && g_mime_header_has_raw (message->mime_part->headers)) {
+	if (message->mime_part && g_mime_header_list_has_raw (message->mime_part->headers)) {
 		/* if the mime part has raw headers, then it contains the message headers as well */
-		g_mime_header_write_to_stream (message->mime_part->headers, stream);
+		g_mime_header_list_write_to_stream (message->mime_part->headers, stream);
 	} else {
-		g_mime_header_write_to_stream (object->headers, stream);
+		g_mime_header_list_write_to_stream (object->headers, stream);
 		if (message->mime_part) {
 			g_mime_stream_write_string (stream, "MIME-Version: 1.0\n");
-			g_mime_header_write_to_stream (message->mime_part->headers, stream);
+			g_mime_header_list_write_to_stream (message->mime_part->headers, stream);
 		}
 	}
 	
@@ -842,10 +873,10 @@
 	ssize_t nwritten, total = 0;
 	
 	if (message->mime_part) {
-		if (!g_mime_header_has_raw (message->mime_part->headers)) {
+		if (!g_mime_header_list_has_raw (message->mime_part->headers)) {
 			/* if the mime part has raw headers, then it contains the message
 			 * headers as well otherwise it doesn't, so write them now */
-			if ((nwritten = g_mime_header_write_to_stream (object->headers, stream)) == -1)
+			if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
 				return -1;
 			
 			total += nwritten;
@@ -859,7 +890,7 @@
 		if ((nwritten = g_mime_object_write_to_stream (message->mime_part, stream)) == -1)
 			return -1;
 	} else {
-		if ((nwritten = g_mime_header_write_to_stream (object->headers, stream)) == -1)
+		if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
 			return -1;
 		
 		total += nwritten;
@@ -888,6 +919,7 @@
 GMimeMessage *
 g_mime_message_new (gboolean pretty_headers)
 {
+	GMimeHeaderList *headers;
 	GMimeMessage *message;
 	int i;
 	
@@ -895,8 +927,9 @@
 	
 	if (pretty_headers) {
 		/* Populate with the "standard" rfc822 headers so we can have a standard order */
-		for (i = 0; rfc822_headers[i]; i++) 
-			g_mime_header_set (GMIME_OBJECT (message)->headers, rfc822_headers[i], NULL);
+		headers = ((GMimeObject *) message)->headers;
+		for (i = 0; i < G_N_ELEMENTS (rfc822_headers); i++) 
+			g_mime_header_list_set (headers, rfc822_headers[i], NULL);
 	}
 	
 	return message;
@@ -927,7 +960,7 @@
 	encoded = internet_address_list_to_string (addrlist, TRUE);
 	internet_address_list_destroy (addrlist);
 	
-	g_mime_header_set (GMIME_OBJECT (message)->headers, "From", encoded);
+	g_mime_header_list_set (GMIME_OBJECT (message)->headers, "From", encoded);
 	g_free (encoded);
 }
 
@@ -965,7 +998,7 @@
 	g_free (message->reply_to);
 	message->reply_to = g_strstrip (g_strdup (reply_to));
 	
-	g_mime_header_set (GMIME_OBJECT (message)->headers, "Reply-To", message->reply_to);
+	g_mime_header_list_set (GMIME_OBJECT (message)->headers, "Reply-To", message->reply_to);
 }
 
 
@@ -995,10 +1028,10 @@
 	/* sync the specified recipient header */
 	if ((recipients = g_mime_message_get_recipients (message, type))) {
 		string = internet_address_list_to_string (recipients, TRUE);
-		g_mime_header_set (GMIME_OBJECT (message)->headers, type, string);
+		g_mime_header_list_set (GMIME_OBJECT (message)->headers, type, string);
 		g_free (string);
 	} else
-		g_mime_header_set (GMIME_OBJECT (message)->headers, type, NULL);
+		g_mime_header_list_set (GMIME_OBJECT (message)->headers, type, NULL);
 }
 
 
@@ -1164,7 +1197,7 @@
 	message->subject = g_strstrip (g_strdup (subject));
 	
 	encoded = g_mime_utils_header_encode_text (message->subject);
-	g_mime_header_set (GMIME_OBJECT (message)->headers, "Subject", encoded);
+	g_mime_object_set_header (GMIME_OBJECT (message), "Subject", encoded);
 	g_free (encoded);
 }
 
@@ -1205,7 +1238,7 @@
 	message->gmt_offset = gmt_offset;
 	
 	date_str = g_mime_message_get_date_string (message);
-	g_mime_header_set (GMIME_OBJECT (message)->headers, "Date", date_str);
+	g_mime_object_set_header (GMIME_OBJECT (message), "Date", date_str);
 	g_free (date_str);
 }
 
@@ -1273,7 +1306,7 @@
 	message->message_id = g_strstrip (g_strdup (message_id));
 	
 	msgid = g_strdup_printf ("<%s>", message_id);
-	g_mime_header_set (GMIME_OBJECT (message)->headers, "Message-Id", msgid);
+	g_mime_object_set_header (GMIME_OBJECT (message), "Message-Id", msgid);
 	g_free (msgid);
 }
 
@@ -1328,12 +1361,13 @@
 g_mime_message_set_mime_part (GMimeMessage *message, GMimeObject *mime_part)
 {
 	g_return_if_fail (GMIME_IS_MESSAGE (message));
+	g_return_if_fail (GMIME_IS_OBJECT (mime_part));
 	
 	g_object_ref (mime_part);
-	g_mime_header_set_raw (mime_part->headers, NULL);
+	g_mime_header_list_set_raw (mime_part->headers, NULL);
 	
 	if (message->mime_part) {
-		g_mime_header_set_raw (message->mime_part->headers, NULL);
+		g_mime_header_list_set_raw (message->mime_part->headers, NULL);
 		g_object_unref (message->mime_part);
 	}
 	

Modified: trunk/gmime/gmime-multipart-encrypted.c
==============================================================================
--- trunk/gmime/gmime-multipart-encrypted.c	(original)
+++ trunk/gmime/gmime-multipart-encrypted.c	Sat May 31 04:10:05 2008
@@ -58,10 +58,11 @@
 
 /* GMimeObject class methods */
 static void multipart_encrypted_init (GMimeObject *object);
-static void multipart_encrypted_add_header (GMimeObject *object, const char *header, const char *value);
+static void multipart_encrypted_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void multipart_encrypted_append_header (GMimeObject *object, const char *header, const char *value);
 static void multipart_encrypted_set_header (GMimeObject *object, const char *header, const char *value);
 static const char *multipart_encrypted_get_header (GMimeObject *object, const char *header);
-static void multipart_encrypted_remove_header (GMimeObject *object, const char *header);
+static gboolean multipart_encrypted_remove_header (GMimeObject *object, const char *header);
 static void multipart_encrypted_set_content_type (GMimeObject *object, GMimeContentType *content_type);
 static char *multipart_encrypted_get_headers (GMimeObject *object);
 static ssize_t multipart_encrypted_write_to_stream (GMimeObject *object, GMimeStream *stream);
@@ -106,10 +107,11 @@
 	gobject_class->finalize = g_mime_multipart_encrypted_finalize;
 	
 	object_class->init = multipart_encrypted_init;
-	object_class->add_header = multipart_encrypted_add_header;
+	object_class->prepend_header = multipart_encrypted_prepend_header;
+	object_class->append_header = multipart_encrypted_append_header;
+	object_class->remove_header = multipart_encrypted_remove_header;
 	object_class->set_header = multipart_encrypted_set_header;
 	object_class->get_header = multipart_encrypted_get_header;
-	object_class->remove_header = multipart_encrypted_remove_header;
 	object_class->set_content_type = multipart_encrypted_set_content_type;
 	object_class->get_headers = multipart_encrypted_get_headers;
 	object_class->write_to_stream = multipart_encrypted_write_to_stream;
@@ -144,9 +146,15 @@
 }
 
 static void
-multipart_encrypted_add_header (GMimeObject *object, const char *header, const char *value)
+multipart_encrypted_prepend_header (GMimeObject *object, const char *header, const char *value)
 {
-	GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
+	GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+}
+
+static void
+multipart_encrypted_append_header (GMimeObject *object, const char *header, const char *value)
+{
+	GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
 }
 
 static void
@@ -161,10 +169,10 @@
 	return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
 }
 
-static void
+static gboolean
 multipart_encrypted_remove_header (GMimeObject *object, const char *header)
 {
-	GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 static void

Modified: trunk/gmime/gmime-multipart-signed.c
==============================================================================
--- trunk/gmime/gmime-multipart-signed.c	(original)
+++ trunk/gmime/gmime-multipart-signed.c	Sat May 31 04:10:05 2008
@@ -34,6 +34,7 @@
 #include "gmime-filter-crlf.h"
 #include "gmime-stream-mem.h"
 #include "gmime-parser.h"
+#include "gmime-error.h"
 #include "gmime-part.h"
 
 #define d(x)
@@ -58,10 +59,11 @@
 
 /* GMimeObject class methods */
 static void multipart_signed_init (GMimeObject *object);
-static void multipart_signed_add_header (GMimeObject *object, const char *header, const char *value);
+static void multipart_signed_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void multipart_signed_append_header (GMimeObject *object, const char *header, const char *value);
 static void multipart_signed_set_header (GMimeObject *object, const char *header, const char *value);
 static const char *multipart_signed_get_header (GMimeObject *object, const char *header);
-static void multipart_signed_remove_header (GMimeObject *object, const char *header);
+static gboolean multipart_signed_remove_header (GMimeObject *object, const char *header);
 static void multipart_signed_set_content_type (GMimeObject *object, GMimeContentType *content_type);
 static char *multipart_signed_get_headers (GMimeObject *object);
 static ssize_t multipart_signed_write_to_stream (GMimeObject *object, GMimeStream *stream);
@@ -106,10 +108,11 @@
 	gobject_class->finalize = g_mime_multipart_signed_finalize;
 	
 	object_class->init = multipart_signed_init;
-	object_class->add_header = multipart_signed_add_header;
+	object_class->prepend_header = multipart_signed_prepend_header;
+	object_class->append_header = multipart_signed_append_header;
+	object_class->remove_header = multipart_signed_remove_header;
 	object_class->set_header = multipart_signed_set_header;
 	object_class->get_header = multipart_signed_get_header;
-	object_class->remove_header = multipart_signed_remove_header;
 	object_class->set_content_type = multipart_signed_set_content_type;
 	object_class->get_headers = multipart_signed_get_headers;
 	object_class->write_to_stream = multipart_signed_write_to_stream;
@@ -142,9 +145,15 @@
 }
 
 static void
-multipart_signed_add_header (GMimeObject *object, const char *header, const char *value)
+multipart_signed_prepend_header (GMimeObject *object, const char *header, const char *value)
 {
-	GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
+	GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+}
+
+static void
+multipart_signed_append_header (GMimeObject *object, const char *header, const char *value)
+{
+	GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
 }
 
 static void
@@ -159,10 +168,10 @@
 	return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
 }
 
-static void
+static gboolean
 multipart_signed_remove_header (GMimeObject *object, const char *header)
 {
-	GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 static void
@@ -414,8 +423,9 @@
 	g_return_val_if_fail (GMIME_IS_CIPHER_CONTEXT (ctx), NULL);
 	g_return_val_if_fail (ctx->sign_protocol != NULL, NULL);
 	
-	if (g_mime_multipart_get_number ((GMimeMultipart *) mps) != 2) {
-		/* FIXME: set an exception */
+	if (g_mime_multipart_get_number ((GMimeMultipart *) mps) < 2) {
+		g_set_error (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR, "%s",
+			     "Cannot verify multipart/signed part due to missing subparts.");
 		return NULL;
 	}
 	

Modified: trunk/gmime/gmime-multipart.c
==============================================================================
--- trunk/gmime/gmime-multipart.c	(original)
+++ trunk/gmime/gmime-multipart.c	Sat May 31 04:10:05 2008
@@ -54,10 +54,11 @@
 
 /* GMimeObject class methods */
 static void multipart_init (GMimeObject *object);
-static void multipart_add_header (GMimeObject *object, const char *header, const char *value);
+static void multipart_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void multipart_append_header (GMimeObject *object, const char *header, const char *value);
 static void multipart_set_header (GMimeObject *object, const char *header, const char *value);
 static const char *multipart_get_header (GMimeObject *object, const char *header);
-static void multipart_remove_header (GMimeObject *object, const char *header);
+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);
@@ -112,10 +113,11 @@
 	gobject_class->finalize = g_mime_multipart_finalize;
 	
 	object_class->init = multipart_init;
-	object_class->add_header = multipart_add_header;
+	object_class->prepend_header = multipart_prepend_header;
+	object_class->append_header = multipart_append_header;
+	object_class->remove_header = multipart_remove_header;
 	object_class->set_header = multipart_set_header;
 	object_class->get_header = multipart_get_header;
-	object_class->remove_header = multipart_remove_header;
 	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;
@@ -171,13 +173,21 @@
 }
 
 static void
-multipart_add_header (GMimeObject *object, const char *header, const char *value)
+multipart_prepend_header (GMimeObject *object, const char *header, const char *value)
+{
+	/* Make sure that the header is a Content-* header, else it
+           doesn't belong on a multipart */
+	if (!g_ascii_strncasecmp ("Content-", header, 8))
+		GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+}
+
+static void
+multipart_append_header (GMimeObject *object, const char *header, const char *value)
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a multipart */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
+		GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
 }
 
 static void
@@ -189,7 +199,6 @@
 	
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a multipart */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
 		GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
 }
@@ -199,21 +208,21 @@
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a multipart */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
 		return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
 	else
 		return NULL;
 }
 
-static void
+static gboolean
 multipart_remove_header (GMimeObject *object, const char *header)
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a multipart */
+	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
+		return FALSE;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 static void
@@ -247,11 +256,11 @@
 	 * header (in which case it should already be set... or if
 	 * not, then it's a broken multipart and so we don't want to
 	 * alter it or we'll completely break the output) */
-	if (!multipart->boundary && !g_mime_header_has_raw (object->headers))
+	if (!multipart->boundary && !g_mime_header_list_has_raw (object->headers))
 		g_mime_multipart_set_boundary (multipart, NULL);
 	
 	/* write the content headers */
-	if ((nwritten = g_mime_header_write_to_stream (object->headers, stream)) == -1)
+	if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
 		return -1;
 	
 	total += nwritten;

Modified: trunk/gmime/gmime-object.c
==============================================================================
--- trunk/gmime/gmime-object.c	(original)
+++ trunk/gmime/gmime-object.c	Sat May 31 04:10:05 2008
@@ -59,10 +59,11 @@
 static void g_mime_object_finalize (GObject *object);
 
 static void init (GMimeObject *object);
-static void add_header (GMimeObject *object, const char *header, const char *value);
-static void set_header (GMimeObject *object, const char *header, const char *value);
-static const char *get_header (GMimeObject *object, const char *header);
-static void remove_header (GMimeObject *object, const char *header);
+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);
@@ -113,10 +114,11 @@
 	object_class->finalize = g_mime_object_finalize;
 	
 	klass->init = init;
-	klass->add_header = add_header;
+	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->remove_header = remove_header;
 	klass->set_content_type = set_content_type;
 	klass->get_headers = get_headers;
 	klass->write_to_stream = write_to_stream;
@@ -127,13 +129,13 @@
 static void
 g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass)
 {
-	object->headers = g_mime_header_new ();
+	object->headers = g_mime_header_list_new ();
 	object->content_type = NULL;
 	object->disposition = NULL;
 	object->content_id = NULL;
 	
-	g_mime_header_register_writer (object->headers, "Content-Type", write_content_type);
-	g_mime_header_register_writer (object->headers, "Content-Disposition", write_disposition);
+	g_mime_header_list_register_writer (object->headers, "Content-Type", write_content_type);
+	g_mime_header_list_register_writer (object->headers, "Content-Disposition", write_disposition);
 }
 
 static void
@@ -148,7 +150,7 @@
 		g_mime_content_disposition_destroy (mime->disposition);
 	
 	if (mime->headers)
-		g_mime_header_destroy (mime->headers);
+		g_mime_header_list_destroy (mime->headers);
 	
 	g_free (mime->content_id);
 	
@@ -205,7 +207,7 @@
 	g_string_free (string, FALSE);
 	
 	type = p + strlen ("Content-Type: ");
-	g_mime_header_set (object->headers, "Content-Type", type);
+	g_mime_header_list_set (object->headers, "Content-Type", type);
 	g_free (p);
 }
 
@@ -238,10 +240,10 @@
 	
 	if (object->disposition) {
 		str = g_mime_content_disposition_to_string (object->disposition, FALSE);
-		g_mime_header_set (object->headers, "Content-Disposition", str);
+		g_mime_header_list_set (object->headers, "Content-Disposition", str);
 		g_free (str);
 	} else {
-		g_mime_header_remove (object->headers, "Content-Disposition");
+		g_mime_header_list_remove (object->headers, "Content-Disposition");
 	}
 }
 
@@ -362,7 +364,7 @@
 
 /**
  * g_mime_object_set_content_type:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @mime_type: Mime type
  *
  * Sets the content-type for the specified Mime object.
@@ -379,7 +381,7 @@
 
 /**
  * g_mime_object_get_content_type:
- * @object: Mime object
+ * @object: a #GMimeObject
  *
  * Gets the Content-Type object for the given Mime object or %NULL on
  * fail.
@@ -397,7 +399,7 @@
 
 /**
  * g_mime_object_set_content_type_parameter:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @name: param name
  * @value: param value
  *
@@ -415,7 +417,7 @@
 
 /**
  * g_mime_object_get_content_type_parameter:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @name: param name
  *
  * Gets the value of the content-type param @name set on the Mime part
@@ -436,7 +438,7 @@
 
 /**
  * g_mime_object_get_content_disposition:
- * @object: Mime object
+ * @object: a #GMimeObject
  *
  * Get the content disposition for the specified Mime object.
  *
@@ -453,7 +455,7 @@
 
 /**
  * g_mime_object_set_content_disposition:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @disposition: a #GMimeContentDisposition object
  *
  * Set the content disposition for the specified mime part.
@@ -475,7 +477,7 @@
 
 /**
  * g_mime_object_set_disposition:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @disposition: disposition ("attachment" or "inline")
  *
  * Sets the disposition to @disposition which may be one of
@@ -500,7 +502,7 @@
 
 /**
  * g_mime_object_get_disposition:
- * @object: Mime object
+ * @object: a #GMimeObject
  *
  * Gets the Mime object's disposition if set or %NULL otherwise.
  *
@@ -521,7 +523,7 @@
 
 /**
  * g_mime_object_set_content_disposition_parameter:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @attribute: parameter name
  * @value: parameter value
  *
@@ -544,7 +546,7 @@
 
 /**
  * g_mime_object_get_content_disposition_parameter:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @attribute: parameter name
  *
  * Gets the value of the Content-Disposition parameter specified by
@@ -568,7 +570,7 @@
 
 /**
  * g_mime_object_set_content_id:
- * @object: Mime object
+ * @object: a #GMimeObject
  * @content_id: content-id (addr-spec portion)
  *
  * Sets the Content-Id of the Mime object.
@@ -591,7 +593,7 @@
 
 /**
  * g_mime_object_get_content_id:
- * @object: Mime object
+ * @object: a #GMimeObject
  *
  * Gets the Content-Id of the Mime object or NULL if one is not set.
  *
@@ -613,11 +615,10 @@
 	HEADER_UNKNOWN,
 };
 
-static char *headers[] = {
+static char *content_headers[] = {
 	"Content-Disposition",
 	"Content-Type",
 	"Content-Id",
-	NULL
 };
 
 static gboolean
@@ -627,8 +628,8 @@
 	GMimeContentType *content_type;
 	int i;
 	
-	for (i = 0; headers[i]; i++) {
-		if (!g_ascii_strcasecmp (headers[i], header))
+	for (i = 0; i < G_N_ELEMENTS (content_headers); i++) {
+		if (!g_ascii_strcasecmp (content_headers[i], header))
 			break;
 	}
 	
@@ -651,35 +652,61 @@
 		return FALSE;
 	}
 	
-	g_mime_header_set (object->headers, header, value);
+	g_mime_header_list_set (object->headers, header, value);
 	
 	return TRUE;
 }
 
 static void
-add_header (GMimeObject *object, const char *header, const char *value)
+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);
+}
+
+
+/**
+ * g_mime_object_prepend_header:
+ * @object: a #GMimeObject
+ * @header: header name
+ * @value: header value
+ *
+ * Prepends a header to the Mime object.
+ **/
+void
+g_mime_object_prepend_header (GMimeObject *object, const char *header, const char *value)
+{
+	g_return_if_fail (GMIME_IS_OBJECT (object));
+	g_return_if_fail (header != NULL);
+	g_return_if_fail (value != NULL);
+	
+	GMIME_OBJECT_GET_CLASS (object)->prepend_header (object, header, value);
+}
+
+static void
+append_header (GMimeObject *object, const char *header, const char *value)
 {
 	if (!process_header (object, header, value))
-		g_mime_header_add (object->headers, header, value);
+		g_mime_header_list_append (object->headers, header, value);
 }
 
 
 /**
- * g_mime_object_add_header:
- * @object: mime object
+ * g_mime_object_append_header:
+ * @object: a #GMimeObject
  * @header: header name
  * @value: header value
  *
- * Adds an arbitrary header to the Mime object.
+ * Appends a header to the Mime object.
  **/
 void
-g_mime_object_add_header (GMimeObject *object, const char *header, const char *value)
+g_mime_object_append_header (GMimeObject *object, const char *header, const char *value)
 {
 	g_return_if_fail (GMIME_IS_OBJECT (object));
 	g_return_if_fail (header != NULL);
 	g_return_if_fail (value != NULL);
 	
-	GMIME_OBJECT_GET_CLASS (object)->add_header (object, header, value);
+	GMIME_OBJECT_GET_CLASS (object)->append_header (object, header, value);
 }
 
 
@@ -687,13 +714,13 @@
 set_header (GMimeObject *object, const char *header, const char *value)
 {
 	if (!process_header (object, header, value))
-		g_mime_header_set (object->headers, header, value);
+		g_mime_header_list_set (object->headers, header, value);
 }
 
 
 /**
  * g_mime_object_set_header:
- * @object: mime object
+ * @object: a #GMimeObject
  * @header: header name
  * @value: header value
  *
@@ -713,13 +740,13 @@
 static const char *
 get_header (GMimeObject *object, const char *header)
 {
-	return g_mime_header_get (object->headers, header);
+	return g_mime_header_list_get (object->headers, header);
 }
 
 
 /**
  * g_mime_object_get_header:
- * @object: mime object
+ * @object: a #GMimeObject
  * @header: header name
  *
  * Gets the value of the requested header if it exists or %NULL
@@ -738,40 +765,68 @@
 }
 
 
-static void
+static gboolean
 remove_header (GMimeObject *object, const char *header)
 {
-	g_mime_header_remove (object->headers, header);
+	int i;
+	
+	for (i = 0; i < G_N_ELEMENTS (content_headers); i++) {
+		if (!g_ascii_strcasecmp (content_headers[i], header))
+			break;
+	}
+	
+	switch (i) {
+	case HEADER_CONTENT_DISPOSITION:
+		if (object->disposition) {
+			g_mime_content_disposition_destroy (object->disposition);
+			object->disposition = NULL;
+		}
+		break;
+	case HEADER_CONTENT_TYPE:
+		/* never allow the removal of the Content-Type header */
+		return FALSE;
+	case HEADER_CONTENT_ID:
+		g_free (object->content_id);
+		object->content_id = NULL;
+		break;
+	default:
+		break;
+	}
+	
+	return g_mime_header_list_remove (object->headers, header);
 }
 
 
 /**
  * g_mime_object_remove_header:
- * @object: mime object
+ * @object: a #GMimeObject
  * @header: header name
  *
  * Removed the specified header if it exists.
+ *
+ * Returns %TRUE if the header was removed or %FALSE if it could not
+ * be found.
  **/
-void
+gboolean
 g_mime_object_remove_header (GMimeObject *object, const char *header)
 {
 	g_return_if_fail (GMIME_IS_OBJECT (object));
 	g_return_if_fail (header != NULL);
 	
-	GMIME_OBJECT_GET_CLASS (object)->remove_header (object, header);
+	return GMIME_OBJECT_GET_CLASS (object)->remove_header (object, header);
 }
 
 
 static char *
 get_headers (GMimeObject *object)
 {
-	return g_mime_header_to_string (object->headers);
+	return g_mime_header_list_to_string (object->headers);
 }
 
 
 /**
  * g_mime_object_get_headers:
- * @object: mime object
+ * @object: a #GMimeObject
  *
  * Allocates a string buffer containing all of the Mime object's raw
  * headers.
@@ -796,7 +851,7 @@
 
 /**
  * g_mime_object_write_to_stream:
- * @object: mime object
+ * @object: a #GMimeObject
  * @stream: stream
  *
  * Write the contents of the Mime object to @stream.
@@ -815,7 +870,7 @@
 
 /**
  * g_mime_object_to_string:
- * @object: mime object
+ * @object: a #GMimeObject
  *
  * Allocates a string buffer containing the contents of @object.
  *

Modified: trunk/gmime/gmime-object.h
==============================================================================
--- trunk/gmime/gmime-object.h	(original)
+++ trunk/gmime/gmime-object.h	Sat May 31 04:10:05 2008
@@ -47,7 +47,7 @@
 	
 	GMimeContentDisposition *disposition;
 	GMimeContentType *content_type;
-	GMimeHeader *headers;
+	GMimeHeaderList *headers;
 	
 	char *content_id;
 };
@@ -57,10 +57,11 @@
 	
 	void         (* init)          (GMimeObject *object);
 	
-	void         (* add_header)    (GMimeObject *object, const char *header, const char *value);
-	void         (* set_header)    (GMimeObject *object, const char *header, const char *value);
-	const char * (* get_header)    (GMimeObject *object, const char *header);
-	void         (* remove_header) (GMimeObject *object, const char *header);
+	void         (* prepend_header) (GMimeObject *object, const char *header, const char *value);
+	void         (* append_header)  (GMimeObject *object, const char *header, const char *value);
+	void         (* set_header)     (GMimeObject *object, const char *header, const char *value);
+	const char * (* get_header)     (GMimeObject *object, const char *header);
+	gboolean     (* remove_header)  (GMimeObject *object, const char *header);
 	
 	void         (* set_content_type) (GMimeObject *object, GMimeContentType *content_type);
 	
@@ -103,10 +104,14 @@
 void g_mime_object_set_content_id (GMimeObject *object, const char *content_id);
 const char *g_mime_object_get_content_id (GMimeObject *object);
 
-void g_mime_object_add_header (GMimeObject *object, const char *header, const char *value);
+void g_mime_object_prepend_header (GMimeObject *object, const char *header, const char *value);
+void g_mime_object_append_header (GMimeObject *object, const char *header, const char *value);
 void g_mime_object_set_header (GMimeObject *object, const char *header, const char *value);
 const char *g_mime_object_get_header (GMimeObject *object, const char *header);
-void g_mime_object_remove_header (GMimeObject *object, const char *header);
+gboolean g_mime_object_remove_header (GMimeObject *object, const char *header);
+
+void g_mime_object_set_header_list (GMimeObject *object, GMimeHeaderList *headers);
+const GMimeHeaderList *g_mime_object_get_header_list (GMimeObject *object);
 
 char *g_mime_object_get_headers (GMimeObject *object);
 

Modified: trunk/gmime/gmime-parser.c
==============================================================================
--- trunk/gmime/gmime-parser.c	(original)
+++ trunk/gmime/gmime-parser.c	Sat May 31 04:10:05 2008
@@ -1330,7 +1330,7 @@
 	message = g_mime_message_new (FALSE);
 	header = priv->headers;
 	while (header) {
-		g_mime_object_add_header ((GMimeObject *) message, header->name, header->value);
+		g_mime_object_append_header ((GMimeObject *) message, header->name, header->value);
 		header = header->next;
 	}
 	
@@ -1361,7 +1361,7 @@
 	
 	header = priv->headers;
 	while (header) {
-		g_mime_object_add_header (object, header->name, header->value);
+		g_mime_object_append_header (object, header->name, header->value);
 		header = header->next;
 	}
 	
@@ -1371,7 +1371,7 @@
 		g_mime_content_type_destroy (object->content_type);
 	object->content_type = content_type;
 	
-	g_mime_header_set_raw (object->headers, priv->rawbuf);
+	g_mime_header_list_set_raw (object->headers, priv->rawbuf);
 	raw_header_reset (priv);
 	
 	if (priv->state == GMIME_PARSER_STATE_HEADERS_END) {
@@ -1513,7 +1513,7 @@
 	
 	header = priv->headers;
 	while (header) {
-		g_mime_object_add_header (object, header->name, header->value);
+		g_mime_object_append_header (object, header->name, header->value);
 		header = header->next;
 	}
 	
@@ -1523,7 +1523,7 @@
 		g_mime_content_type_destroy (object->content_type);
 	object->content_type = content_type;
 	
-	g_mime_header_set_raw (object->headers, priv->rawbuf);
+	g_mime_header_list_set_raw (object->headers, priv->rawbuf);
 	raw_header_reset (priv);
 	
 	multipart = (GMimeMultipart *) object;
@@ -1638,7 +1638,7 @@
 				content_length = ULONG_MAX;
 		}
 		
-		g_mime_object_add_header ((GMimeObject *) message, header->name, header->value);
+		g_mime_object_append_header ((GMimeObject *) message, header->name, header->value);
 		header = header->next;
 	}
 	

Modified: trunk/gmime/gmime-part.c
==============================================================================
--- trunk/gmime/gmime-part.c	(original)
+++ trunk/gmime/gmime-part.c	Sat May 31 04:10:05 2008
@@ -60,10 +60,11 @@
 
 /* GMimeObject class methods */
 static void mime_part_init (GMimeObject *object);
-static void mime_part_add_header (GMimeObject *object, const char *header, const char *value);
+static void mime_part_prepend_header (GMimeObject *object, const char *header, const char *value);
+static void mime_part_append_header (GMimeObject *object, const char *header, const char *value);
 static void mime_part_set_header (GMimeObject *object, const char *header, const char *value);
 static const char *mime_part_get_header (GMimeObject *object, const char *header);
-static void mime_part_remove_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);
 
@@ -107,10 +108,11 @@
 	gobject_class->finalize = g_mime_part_finalize;
 	
 	object_class->init = mime_part_init;
-	object_class->add_header = mime_part_add_header;
+	object_class->prepend_header = mime_part_prepend_header;
+	object_class->append_header = mime_part_append_header;
+	object_class->remove_header = mime_part_remove_header;
 	object_class->set_header = mime_part_set_header;
 	object_class->get_header = mime_part_get_header;
-	object_class->remove_header = mime_part_remove_header;
 	object_class->get_headers = mime_part_get_headers;
 	object_class->write_to_stream = mime_part_write_to_stream;
 }
@@ -156,12 +158,11 @@
 	HEADER_UNKNOWN
 };
 
-static char *headers[] = {
+static const char *content_headers[] = {
 	"Content-Transfer-Encoding",
 	"Content-Description",
 	"Content-Location",
 	"Content-Md5",
-	NULL
 };
 
 
@@ -172,8 +173,8 @@
 	char *text;
 	int i;
 	
-	for (i = 0; headers[i]; i++) {
-		if (!g_ascii_strcasecmp (headers[i], header))
+	for (i = 0; i < G_N_ELEMENTS (content_headers); i++) {
+		if (!g_ascii_strcasecmp (content_headers[i], header))
 			break;
 	}
 	
@@ -206,17 +207,31 @@
 }
 
 static void
-mime_part_add_header (GMimeObject *object, const char *header, const char *value)
+mime_part_prepend_header (GMimeObject *object, const char *header, const char *value)
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a mime part */
+	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
+		return;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8)) {
-		if (process_header (object, header, value))
-			g_mime_header_add (object->headers, header, value);
-		else
-			GMIME_OBJECT_CLASS (parent_class)->add_header (object, header, value);
-	}
+	if (!process_header (object, header, value))
+		GMIME_OBJECT_CLASS (parent_class)->prepend_header (object, header, value);
+	else
+		g_mime_header_list_prepend (object->headers, header, value);
+}
+
+static void
+mime_part_append_header (GMimeObject *object, const char *header, const char *value)
+{
+	/* Make sure that the header is a Content-* header, else it
+           doesn't belong on a mime part */
+	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
+		return;
+	
+	if (!process_header (object, header, value))
+		GMIME_OBJECT_CLASS (parent_class)->append_header (object, header, value);
+	else
+		g_mime_header_list_append (object->headers, header, value);
 }
 
 static void
@@ -224,13 +239,13 @@
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a mime part */
+	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
+		return;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8)) {
-		if (process_header (object, header, value))
-			g_mime_header_set (object->headers, header, value);
-		else
-			GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
-	}
+	if (!process_header (object, header, value))
+		GMIME_OBJECT_CLASS (parent_class)->set_header (object, header, value);
+	else
+		g_mime_header_list_set (object->headers, header, value);
 }
 
 static const char *
@@ -238,21 +253,50 @@
 {
 	/* Make sure that the header is a Content-* header, else it
            doesn't belong on a mime part */
-	
 	if (!g_ascii_strncasecmp ("Content-", header, 8))
 		return GMIME_OBJECT_CLASS (parent_class)->get_header (object, header);
 	else
 		return NULL;
 }
 
-static void
+static gboolean
 mime_part_remove_header (GMimeObject *object, const char *header)
 {
+	GMimePart *mime_part = (GMimePart *) object;
+	int i;
+	
 	/* Make sure that the header is a Content-* header, else it
 	   doesn't belong on a mime part */
+	if (g_ascii_strncasecmp ("Content-", header, 8) != 0)
+		return FALSE;
 	
-	if (!g_ascii_strncasecmp ("Content-", header, 8))
-		GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
+	for (i = 0; i < G_N_ELEMENTS (content_headers); i++) {
+		if (!g_ascii_strcasecmp (content_headers[i], header))
+			break;
+	}
+	
+	switch (i) {
+	case HEADER_CONTENT_TRANSFER_ENCODING:
+		mime_part->encoding = GMIME_CONTENT_ENCODING_DEFAULT;
+		break;
+	case HEADER_CONTENT_DESCRIPTION:
+		/* FIXME: we should decode this */
+		g_free (mime_part->content_description);
+		mime_part->content_description = NULL;
+		break;
+	case HEADER_CONTENT_LOCATION:
+		g_free (mime_part->content_location);
+		mime_part->content_location = NULL;
+		break;
+	case HEADER_CONTENT_MD5:
+		g_free (mime_part->content_md5);
+		mime_part->content_md5 = NULL;
+		break;
+	default:
+		break;
+	}
+	
+	return GMIME_OBJECT_CLASS (parent_class)->remove_header (object, header);
 }
 
 static char *
@@ -347,7 +391,7 @@
 	ssize_t nwritten, total = 0;
 	
 	/* write the content headers */
-	if ((nwritten = g_mime_header_write_to_stream (object->headers, stream)) == -1)
+	if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
 		return -1;
 	
 	total += nwritten;
@@ -469,7 +513,7 @@
 		g_free (mime_part->content_description);
 	
 	mime_part->content_description = g_strdup (description);
-	g_mime_header_set (GMIME_OBJECT (mime_part)->headers, "Content-Description", description);
+	g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Description", description);
 }
 
 
@@ -585,7 +629,7 @@
 	}
 	
 	mime_part->content_md5 = g_strdup (content_md5);
-	g_mime_header_set (GMIME_OBJECT (mime_part)->headers, "Content-Md5", content_md5);
+	g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Md5", content_md5);
 }
 
 
@@ -684,7 +728,7 @@
 		g_free (mime_part->content_location);
 	
 	mime_part->content_location = g_strdup (content_location);
-	g_mime_header_set (GMIME_OBJECT (mime_part)->headers, "Content-Location", content_location);
+	g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Location", content_location);
 }
 
 
@@ -719,8 +763,8 @@
 	g_return_if_fail (GMIME_IS_PART (mime_part));
 	
 	mime_part->encoding = encoding;
-	g_mime_header_set (GMIME_OBJECT (mime_part)->headers, "Content-Transfer-Encoding",
-			   g_mime_content_encoding_to_string (encoding));
+	g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Transfer-Encoding",
+				g_mime_content_encoding_to_string (encoding));
 }
 
 

Modified: trunk/tests/test-parser.c
==============================================================================
--- trunk/tests/test-parser.c	(original)
+++ trunk/tests/test-parser.c	Sat May 31 04:10:05 2008
@@ -126,12 +126,12 @@
 	{
 		GMimeStream *stream;
 		
-		g_mime_header_set_raw (GMIME_OBJECT (message)->headers, NULL);
+		g_mime_header_list_set_raw (GMIME_OBJECT (message)->headers, NULL);
 		
 		fprintf (stdout, "\nTesting preservation of headers...\n\n");
 		stream = g_mime_stream_file_new (stdout);
 		/*g_mime_header_set_raw (GMIME_OBJECT (message)->headers, NULL);*/
-		g_mime_header_write_to_stream (GMIME_OBJECT (message)->headers, stream);
+		g_mime_header_list_write_to_stream (GMIME_OBJECT (message)->headers, stream);
 		g_mime_stream_flush (stream);
 		GMIME_STREAM_FILE (stream)->fp = NULL;
 		g_object_unref (stream);



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