[gmime: 13/21] GMimeHeader::value is now the unfolded and decoded version
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime: 13/21] GMimeHeader::value is now the unfolded and decoded version
- Date: Sun, 26 Mar 2017 19:41:44 +0000 (UTC)
commit 9397272212b61553f1735b1cfc584112f7c85b67
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Sun Mar 26 07:04:50 2017 -0400
GMimeHeader::value is now the unfolded and decoded version
There is no longer any need to call g_mime_utils_header_decode_text()
on the value returned by get_value() and no longer any need to
call g_mime_utils_header_encode_text() when setting/appending a
header.
gmime/gmime-header.c | 740 +++++++++++++++++++++++++++++++++--------
gmime/gmime-header.h | 43 ++-
gmime/gmime-internal.h | 16 +-
gmime/gmime-message-partial.c | 5 +-
gmime/gmime-message.c | 451 +------------------------
gmime/gmime-object.c | 129 ++------
gmime/gmime-object.h | 6 +-
gmime/gmime-parser.c | 92 ++----
gmime/gmime-part.c | 20 +-
tests/test-headers.c | 8 +-
tests/test-pgpmime.c | 6 +-
tests/test-smime.c | 2 +-
12 files changed, 708 insertions(+), 810 deletions(-)
---
diff --git a/gmime/gmime-header.c b/gmime/gmime-header.c
index d31adae..039e17b 100644
--- a/gmime/gmime-header.c
+++ b/gmime/gmime-header.c
@@ -27,7 +27,10 @@
#include <ctype.h>
#include "gmime-stream-filter.h"
+#include "gmime-table-private.h"
+#include "gmime-parse-utils.h"
#include "gmime-stream-mem.h"
+#include "internet-address.h"
#include "gmime-internal.h"
#include "gmime-common.h"
#include "gmime-header.h"
@@ -46,6 +49,32 @@
**/
+static struct {
+ const char *name;
+ GMimeHeaderRawValueFormatter formatter;
+} formatters[] = {
+ { "Received", g_mime_header_format_received },
+ { "Sender", g_mime_header_format_addrlist },
+ { "From", g_mime_header_format_addrlist },
+ { "Reply-To", g_mime_header_format_addrlist },
+ { "To", g_mime_header_format_addrlist },
+ { "Cc", g_mime_header_format_addrlist },
+ { "Bcc", g_mime_header_format_addrlist },
+ { "Message-Id", g_mime_header_format_message_id },
+ { "In-Reply-To", g_mime_header_format_references },
+ { "References", g_mime_header_format_references },
+ { "Resent-Sender", g_mime_header_format_addrlist },
+ { "Resent-From", g_mime_header_format_addrlist },
+ { "Resent-Reply-To", g_mime_header_format_addrlist },
+ { "Resent-To", g_mime_header_format_addrlist },
+ { "Resent-Cc", g_mime_header_format_addrlist },
+ { "Resent-Bcc", g_mime_header_format_addrlist },
+ { "Resent-Message-Id", g_mime_header_format_message_id },
+ { "Content-Type", g_mime_header_format_content_type },
+ { "Content-Disposition", g_mime_header_format_content_disposition },
+};
+
+
static void g_mime_header_class_init (GMimeHeaderClass *klass);
static void g_mime_header_init (GMimeHeader *header, GMimeHeaderClass *klass);
static void g_mime_header_finalize (GObject *object);
@@ -91,6 +120,8 @@ static void
g_mime_header_init (GMimeHeader *header, GMimeHeaderClass *klass)
{
header->changed = g_mime_event_new (header);
+ header->formatter = NULL;
+ header->options = NULL;
header->raw_value = NULL;
header->raw_name = NULL;
header->value = NULL;
@@ -115,9 +146,11 @@ g_mime_header_finalize (GObject *object)
/**
* g_mime_header_new:
+ * @options: a #GMimeParserOptions
* @name: header name
* @value: header value
* @raw_value: raw header value
+ * @charset: a charset
* @offset: file/stream offset for the start of the header (or %-1 if unknown)
*
* Creates a new #GMimeHeader.
@@ -125,17 +158,33 @@ g_mime_header_finalize (GObject *object)
* Returns: a new #GMimeHeader with the specified values.
**/
static GMimeHeader *
-g_mime_header_new (const char *name, const char *value, const char *raw_name, const char *raw_value, gint64
offset)
+g_mime_header_new (GMimeParserOptions *options, const char *name, const char *value,
+ const char *raw_name, const char *raw_value, const char *charset,
+ gint64 offset)
{
+ GMimeHeaderRawValueFormatter formatter;
GMimeHeader *header;
+ guint i;
header = g_object_newv (GMIME_TYPE_HEADER, 0, NULL);
header->raw_value = raw_value ? g_strdup (raw_value) : NULL;
+ header->value = value ? g_strdup (value) : NULL;
header->raw_name = g_strdup (raw_name);
- header->value = g_strdup (value);
header->name = g_strdup (name);
+ header->options = options;
header->offset = offset;
+ formatter = g_mime_header_format_default;
+ for (i = 0; i < G_N_ELEMENTS (formatters); i++) {
+ if (!g_ascii_strcasecmp (formatters[i].name, name)) {
+ formatter = header->formatter = formatters[i].formatter;
+ break;
+ }
+ }
+
+ if (!raw_value && value)
+ header->raw_value = formatter (header, NULL, header->value, charset);
+
return header;
}
@@ -157,6 +206,37 @@ g_mime_header_get_name (GMimeHeader *header)
}
+static char *
+unfold (const char *value)
+{
+ register const char *inptr = value;
+ const char *start, *inend;
+ char *str, *outptr;
+
+ while (is_lwsp (*inptr))
+ inptr++;
+
+ start = inptr;
+ while (*inptr) {
+ if (!is_lwsp (*inptr++))
+ inend = inptr;
+ }
+
+ outptr = str = g_malloc ((size_t) (inend - start) + 1);
+ inptr = start;
+
+ while (inptr < inend) {
+ if (*inptr != '\r' && *inptr != '\n')
+ *outptr++ = *inptr;
+ inptr++;
+ }
+
+ *outptr = '\0';
+
+ return str;
+}
+
+
/**
* g_mime_header_get_value:
* @header: a #GMimeHeader
@@ -171,8 +251,16 @@ g_mime_header_get_name (GMimeHeader *header)
const char *
g_mime_header_get_value (GMimeHeader *header)
{
+ char *buf;
+
g_return_val_if_fail (GMIME_IS_HEADER (header), NULL);
+ if (!header->value && header->raw_value) {
+ buf = unfold (header->raw_value);
+ header->value = g_mime_utils_header_decode_text (header->options, buf);
+ g_free (buf);
+ }
+
return header->value;
}
@@ -180,24 +268,28 @@ g_mime_header_get_value (GMimeHeader *header)
/**
* g_mime_header_set_value:
* @header: a #GMimeHeader
+ * @options: a #GMimeFormatOptions
* @value: the new header value
+ * @charset: a charset
*
* Sets the header's value.
- *
- * Note: @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
**/
void
-g_mime_header_set_value (GMimeHeader *header, const char *value)
+g_mime_header_set_value (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const char
*charset)
{
+ GMimeHeaderRawValueFormatter formatter;
+ char *buf;
+
g_return_if_fail (GMIME_IS_HEADER (header));
g_return_if_fail (value != NULL);
+ formatter = header->formatter ? header->formatter : g_mime_header_format_default;
+ buf = g_mime_strdup_trim (value);
g_free (header->raw_value);
- header->raw_value = NULL;
-
g_free (header->value);
- header->value = g_strdup (value);
+
+ header->raw_value = formatter (header, options, buf, charset);
+ header->value = buf;
g_mime_event_emit (header->changed, NULL);
}
@@ -282,24 +374,9 @@ _g_mime_header_set_offset (GMimeHeader *header, gint64 offset)
header->offset = offset;
}
-static ssize_t
-default_writer (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- ssize_t nwritten;
- char *val;
-
- val = g_mime_utils_header_printf (options, format, "%s: %s\n", name, value);
- nwritten = g_mime_stream_write_string (stream, val);
- g_free (val);
-
- return nwritten;
-}
-
/**
* g_mime_header_write_to_stream:
- * @headers: the #GMimeHeaderList that contains @header
* @header: a #GMimeHeader
* @options: a #GMimeFormatOptions
* @stream: a #GMimeStream
@@ -309,37 +386,453 @@ default_writer (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeSt
* Returns: the number of bytes written, or %-1 on fail.
**/
ssize_t
-g_mime_header_write_to_stream (GMimeHeaderList *headers, GMimeHeader *header,
- GMimeFormatOptions *options, GMimeStream *stream)
+g_mime_header_write_to_stream (GMimeHeader *header, GMimeFormatOptions *options, GMimeStream *stream)
{
ssize_t nwritten, total = 0;
- GMimeHeaderWriter writer;
char *val;
- g_return_val_if_fail (GMIME_IS_HEADER_LIST (headers), -1);
g_return_val_if_fail (GMIME_IS_HEADER (header), -1);
g_return_val_if_fail (GMIME_IS_STREAM (stream), -1);
- if (header->raw_value) {
- val = g_strdup_printf ("%s:%s", header->raw_name, header->raw_value);
- nwritten = g_mime_stream_write_string (stream, val);
- g_free (val);
+ if (!header->raw_value)
+ return 0;
+
+ val = g_strdup_printf ("%s:%s", header->raw_name, header->raw_value);
+ nwritten = g_mime_stream_write_string (stream, val);
+ g_free (val);
+
+ if (nwritten == -1)
+ return -1;
+
+ total += nwritten;
+
+ return total;
+}
+
+
+char *
+g_mime_header_format_content_disposition (GMimeHeader *header, GMimeFormatOptions *options, const char
*value, const char *charset)
+{
+ GMimeContentDisposition *disposition;
+ GString *str;
+ guint n;
+
+ str = g_string_new (header->raw_name);
+ g_string_append_c (str, ':');
+ n = str->len;
+
+ g_string_append_c (str, ' ');
+
+ disposition = g_mime_content_disposition_parse (header->options, value);
+ g_string_append (str, disposition->disposition);
+
+ g_mime_param_list_encode (disposition->params, options, TRUE, str);
+ g_object_unref (disposition);
+
+ memmove (str->str, str->str + n, (str->len - n) + 1);
+
+ return g_string_free (str, FALSE);
+}
+
+
+char *
+g_mime_header_format_content_type (GMimeHeader *header, GMimeFormatOptions *options, const char *value,
const char *charset)
+{
+ GMimeContentType *content_type;
+ GString *str;
+ guint n;
+
+ str = g_string_new (header->raw_name);
+ g_string_append_c (str, ':');
+ n = str->len;
+
+ content_type = g_mime_content_type_parse (header->options, value);
+
+ g_string_append_c (str, ' ');
+ g_string_append (str, content_type->type ? content_type->type : "text");
+ g_string_append_c (str, '/');
+ g_string_append (str, content_type->subtype ? content_type->subtype : "plain");
+
+ g_mime_param_list_encode (content_type->params, options, TRUE, str);
+ g_object_unref (content_type);
+
+ memmove (str->str, str->str + n, (str->len - n) + 1);
+
+ return g_string_free (str, FALSE);
+}
+
+
+char *
+g_mime_header_format_message_id (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const
char *charset)
+{
+ const char *newline = g_mime_format_options_get_newline (options);
+
+ return g_strdup_printf (" %s%s", value, newline);
+}
+
+
+char *
+g_mime_header_format_references (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const
char *charset)
+{
+ GMimeReferences *references, *reference;
+ const char *newline;
+ guint cur, len, n;
+ GString *str;
+
+ /* Note: we don't want to break in the middle of msgid tokens as
+ it seems to break a lot of clients (and servers) */
+ newline = g_mime_format_options_get_newline (options);
+ references = g_mime_references_decode (value);
+ str = g_string_new (header->raw_name);
+ g_string_append_c (str, ':');
+ cur = n = str->len;
+
+ reference = references;
+ while (reference != NULL) {
+ len = strlen (reference->msgid);
+ if (cur > 1 && cur + len + 3 >= GMIME_FOLD_LEN) {
+ g_string_append (str, newline);
+ g_string_append_c (str, '\t');
+ cur = 1;
+ } else {
+ g_string_append_c (str, ' ');
+ cur++;
+ }
- if (nwritten == -1)
- return -1;
+ g_string_append_c (str, '<');
+ g_string_append_len (str, reference->msgid, len);
+ g_string_append_c (str, '>');
+ cur += len + 2;
- total += nwritten;
- } else if (header->value) {
- if (!(writer = g_hash_table_lookup (headers->writers, header->name)))
- writer = default_writer;
+ reference = reference->next;
+ }
+
+ g_mime_references_clear (&references);
+
+ g_string_append (str, newline);
+
+ memmove (str->str, str->str + n, (str->len - n) + 1);
+
+ return g_string_free (str, FALSE);
+}
+
+
+char *
+g_mime_header_format_addrlist (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const
char *charset)
+{
+ InternetAddressList *addrlist;
+ const char *newline;
+ GString *str;
+ guint n;
+
+ newline = g_mime_format_options_get_newline (options);
+ str = g_string_new (header->raw_name);
+ g_string_append_c (str, ':');
+ n = str->len;
+
+ g_string_append_c (str, ' ');
+
+ if (value && (addrlist = internet_address_list_parse (header->options, value))) {
+ internet_address_list_writer (addrlist, options, str);
+ g_object_unref (addrlist);
+ }
+
+ g_string_append (str, newline);
+
+ memmove (str->str, str->str + n, (str->len - n) + 1);
+
+ return g_string_free (str, FALSE);
+}
+
+
+typedef void (* token_skip_t) (const char **in);
+
+struct _received_token {
+ char *token;
+ size_t len;
+ token_skip_t skip;
+};
+
+static void skip_cfws_atom (const char **in);
+static void skip_domain (const char **in);
+static void skip_addr (const char **in);
+static void skip_msgid (const char **in);
+
+static struct _received_token received_tokens[] = {
+ { "from ", 5, skip_domain },
+ { "by ", 3, skip_domain },
+ { "via ", 4, skip_cfws_atom },
+ { "with ", 5, skip_cfws_atom },
+ { "id ", 3, skip_msgid },
+ { "for ", 4, skip_addr }
+};
+
+static void
+skip_cfws_atom (const char **in)
+{
+ skip_cfws (in);
+ skip_atom (in);
+}
+
+static void
+skip_domain_subliteral (const char **in)
+{
+ const char *inptr = *in;
+
+ while (*inptr && *inptr != '.' && *inptr != ']') {
+ if (is_dtext (*inptr)) {
+ inptr++;
+ } else if (is_lwsp (*inptr)) {
+ skip_cfws (&inptr);
+ } else {
+ break;
+ }
+ }
+
+ *in = inptr;
+}
+
+static void
+skip_domain_literal (const char **in)
+{
+ const char *inptr = *in;
+
+ skip_cfws (&inptr);
+ while (*inptr && *inptr != ']') {
+ skip_domain_subliteral (&inptr);
+ if (*inptr && *inptr != ']')
+ inptr++;
+ }
+
+ *in = inptr;
+}
+
+static void
+skip_domain (const char **in)
+{
+ const char *save, *inptr = *in;
+
+ while (inptr && *inptr) {
+ skip_cfws (&inptr);
+ if (*inptr == '[') {
+ /* domain literal */
+ inptr++;
+ skip_domain_literal (&inptr);
+ if (*inptr == ']')
+ inptr++;
+ } else {
+ skip_atom (&inptr);
+ }
- if ((nwritten = writer (headers->options, options, stream, header->name, header->value)) ==
-1)
- return -1;
+ save = inptr;
+ skip_cfws (&inptr);
+ if (*inptr != '.') {
+ inptr = save;
+ break;
+ }
- total += nwritten;
+ inptr++;
}
- return total;
+ *in = inptr;
+}
+
+static void
+skip_addrspec (const char **in)
+{
+ const char *inptr = *in;
+
+ skip_cfws (&inptr);
+ skip_word (&inptr);
+ skip_cfws (&inptr);
+
+ while (*inptr == '.') {
+ inptr++;
+ skip_cfws (&inptr);
+ skip_word (&inptr);
+ skip_cfws (&inptr);
+ }
+
+ if (*inptr == '@') {
+ inptr++;
+ skip_domain (&inptr);
+ }
+
+ *in = inptr;
+}
+
+static void
+skip_addr (const char **in)
+{
+ const char *inptr = *in;
+
+ skip_cfws (&inptr);
+ if (*inptr == '<') {
+ inptr++;
+ skip_addrspec (&inptr);
+ if (*inptr == '>')
+ inptr++;
+ } else {
+ skip_addrspec (&inptr);
+ }
+
+ *in = inptr;
+}
+
+static void
+skip_msgid (const char **in)
+{
+ const char *inptr = *in;
+
+ skip_cfws (&inptr);
+ if (*inptr == '<') {
+ inptr++;
+ skip_addrspec (&inptr);
+ if (*inptr == '>')
+ inptr++;
+ } else {
+ skip_atom (&inptr);
+ }
+
+ *in = inptr;
+}
+
+struct _received_part {
+ struct _received_part *next;
+ const char *start;
+ size_t len;
+};
+
+
+
+char *
+g_mime_header_format_received (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const
char *charset)
+{
+ struct _received_part *parts, *part, *tail;
+ const char *inptr, *lwsp = NULL;
+ const char *newline;
+ guint len, n, i;
+ GString *str;
+
+ newline = g_mime_format_options_get_newline (options);
+
+ while (is_lwsp (*value))
+ value++;
+
+ if (*value == '\0')
+ return g_strdup (newline);
+
+ str = g_string_new (header->raw_name);
+ g_string_append_c (str, ':');
+ n = str->len;
+
+ g_string_append_c (str, ' ');
+ len = str->len;
+
+ tail = parts = part = g_alloca (sizeof (struct _received_part));
+ part->start = inptr = value;
+ part->next = NULL;
+
+ while (*inptr) {
+ for (i = 0; i < G_N_ELEMENTS (received_tokens); i++) {
+ if (!strncmp (inptr, received_tokens[i].token, received_tokens[i].len)) {
+ if (inptr > part->start) {
+ g_assert (lwsp != NULL);
+ part->len = lwsp - part->start;
+
+ part = g_alloca (sizeof (struct _received_part));
+ part->start = inptr;
+ part->next = NULL;
+
+ tail->next = part;
+ tail = part;
+ }
+
+ inptr += received_tokens[i].len;
+ received_tokens[i].skip (&inptr);
+
+ lwsp = inptr;
+ while (is_lwsp (*inptr))
+ inptr++;
+
+ if (*inptr == ';') {
+ inptr++;
+
+ part->len = inptr - part->start;
+
+ lwsp = inptr;
+ while (is_lwsp (*inptr))
+ inptr++;
+
+ part = g_alloca (sizeof (struct _received_part));
+ part->start = inptr;
+ part->next = NULL;
+
+ tail->next = part;
+ tail = part;
+ }
+
+ break;
+ }
+ }
+
+ if (i == G_N_ELEMENTS (received_tokens)) {
+ while (*inptr && !is_lwsp (*inptr))
+ inptr++;
+
+ lwsp = inptr;
+ while (is_lwsp (*inptr))
+ inptr++;
+ }
+
+ if (*inptr == '(') {
+ skip_comment (&inptr);
+
+ lwsp = inptr;
+ while (is_lwsp (*inptr))
+ inptr++;
+ }
+ }
+
+ part->len = lwsp - part->start;
+
+ lwsp = NULL;
+ part = parts;
+ do {
+ len += lwsp ? part->start - lwsp : 0;
+ if (len + part->len > GMIME_FOLD_LEN && part != parts) {
+ g_string_append (str, newline);
+ g_string_append_c (str, '\t');
+ len = 1;
+ } else if (lwsp) {
+ g_string_append_len (str, lwsp, (size_t) (part->start - lwsp));
+ }
+
+ g_string_append_len (str, part->start, part->len);
+ lwsp = part->start + part->len;
+ len += part->len;
+
+ part = part->next;
+ } while (part != NULL);
+
+ g_string_append (str, newline);
+
+ memmove (str->str, str->str + n, (str->len - n) + 1);
+
+ return g_string_free (str, FALSE);
+}
+
+
+char *
+g_mime_header_format_default (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const
char *charset)
+{
+ char *encoded, *raw_value;
+
+ encoded = g_mime_utils_header_encode_text (options, value, charset);
+ raw_value = _g_mime_utils_unstructured_header_fold (header->options, options, header->raw_name,
encoded);
+ g_free (encoded);
+
+ return raw_value;
}
@@ -401,9 +894,6 @@ g_mime_header_list_class_init (GMimeHeaderListClass *klass)
static void
g_mime_header_list_init (GMimeHeaderList *list, GMimeHeaderListClass *klass)
{
- list->writers = g_hash_table_new_full (g_mime_strcase_hash,
- g_mime_strcase_equal,
- g_free, NULL);
list->hash = g_hash_table_new (g_mime_strcase_hash,
g_mime_strcase_equal);
list->changed = g_mime_event_new (list);
@@ -426,7 +916,6 @@ g_mime_header_list_finalize (GObject *object)
g_ptr_array_free (headers->array, TRUE);
g_mime_parser_options_free (headers->options);
- g_hash_table_destroy (headers->writers);
g_hash_table_destroy (headers->hash);
g_mime_event_free (headers->changed);
@@ -543,16 +1032,29 @@ g_mime_header_list_contains (GMimeHeaderList *headers, const char *name)
}
+/**
+ * g_mime_header_list_prepend:
+ * @headers: a #GMimeHeaderList
+ * @name: header name
+ * @value: header value
+ * @charset: a charset
+ *
+ * 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_list_prepend (GMimeHeaderList *headers, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset)
+g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value, const char
*charset)
{
GMimeHeaderListChangedEventArgs args;
unsigned char *dest, *src;
GMimeHeader *header;
guint n;
- header = g_mime_header_new (name, value, raw_name, raw_value, offset);
+ g_return_if_fail (GMIME_IS_HEADER_LIST (headers));
+ g_return_if_fail (name != NULL);
+
+ header = g_mime_header_new (headers->options, name, value, name, NULL, charset, -1);
g_mime_event_add (header->changed, (GMimeEventCallback) header_changed, headers);
g_hash_table_replace (headers->hash, header->name, header);
@@ -576,37 +1078,14 @@ _g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const c
}
-/**
- * g_mime_header_list_prepend:
- * @headers: a #GMimeHeaderList
- * @name: header name
- * @value: header value
- *
- * 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.
- *
- * Note: @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
- **/
void
-g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value)
-{
- g_return_if_fail (GMIME_IS_HEADER_LIST (headers));
- g_return_if_fail (name != NULL);
-
- _g_mime_header_list_prepend (headers, name, value, name, NULL, -1);
-}
-
-
-void
-_g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset)
+_g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *raw_name,
+ const char *raw_value, gint64 offset)
{
GMimeHeaderListChangedEventArgs args;
GMimeHeader *header;
- header = g_mime_header_new (name, value, raw_name, raw_value, offset);
+ header = g_mime_header_new (headers->options, name, NULL, raw_name, raw_value, NULL, offset);
g_mime_event_add (header->changed, (GMimeEventCallback) header_changed, headers);
g_ptr_array_add (headers->array, header);
@@ -625,21 +1104,32 @@ _g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const ch
* @headers: a #GMimeHeaderList
* @name: header name
* @value: header value
+ * @charset: a charset
*
* 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.
- *
- * Note: @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
**/
void
-g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value)
+g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value, const char
*charset)
{
+ GMimeHeaderListChangedEventArgs args;
+ GMimeHeader *header;
+
g_return_if_fail (GMIME_IS_HEADER_LIST (headers));
g_return_if_fail (name != NULL);
- _g_mime_header_list_append (headers, name, value, name, NULL, -1);
+ header = g_mime_header_new (headers->options, name, value, name, NULL, charset, -1);
+ g_mime_event_add (header->changed, (GMimeEventCallback) header_changed, headers);
+ g_ptr_array_add (headers->array, header);
+
+ if (!g_hash_table_lookup (headers->hash, name))
+ g_hash_table_insert (headers->hash, header->name, header);
+
+ args.action = GMIME_HEADER_LIST_CHANGED_ACTION_ADDED;
+ args.header = header;
+
+ g_mime_event_emit (headers->changed, &args);
}
@@ -664,25 +1154,34 @@ g_mime_header_list_get_header (GMimeHeaderList *headers, const char *name)
}
+/**
+ * g_mime_header_list_set:
+ * @headers: a #GMimeHeaderList
+ * @name: header name
+ * @value: header value
+ * @charset: a charset
+ *
+ * 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.
+ *
+ * Note: If there are multiple headers with the specified field name,
+ * the first instance of the header will be replaced and further
+ * instances will be removed.
+ **/
void
-_g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset)
+g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value, const char *charset)
{
GMimeHeaderListChangedEventArgs args;
GMimeHeader *header, *hdr;
guint i;
+ g_return_if_fail (GMIME_IS_HEADER_LIST (headers));
+ g_return_if_fail (name != NULL);
+
if ((header = g_hash_table_lookup (headers->hash, name))) {
- g_free (header->raw_value);
- header->raw_value = raw_value ? g_strdup (raw_value) : NULL;
-
- g_free (header->raw_name);
- header->raw_name = g_strdup (raw_name);
-
- g_free (header->value);
- header->value = g_strdup (value);
-
- header->offset = offset;
+ g_mime_header_set_value (header, NULL, value, charset);
for (i = headers->array->len - 1; i > 0; i--) {
hdr = (GMimeHeader *) headers->array->pdata[i];
@@ -703,40 +1202,12 @@ _g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char
g_mime_event_emit (headers->changed, &args);
} else {
- _g_mime_header_list_append (headers, name, value, raw_name, raw_value, offset);
+ g_mime_header_list_append (headers, name, value, charset);
}
}
/**
- * g_mime_header_list_set:
- * @headers: a #GMimeHeaderList
- * @name: header name
- * @value: header value
- *
- * 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.
- *
- * Note: If there are multiple headers with the specified field name,
- * the first instance of the header will be replaced and further
- * instances will be removed.
- *
- * Additionally, @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
- **/
-void
-g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value)
-{
- g_return_if_fail (GMIME_IS_HEADER_LIST (headers));
- g_return_if_fail (name != NULL);
-
- _g_mime_header_list_set (headers, name, value, name, NULL, -1);
-}
-
-
-/**
* g_mime_header_list_get_header_at:
* @headers: a #GMimeHeaderList
* @index: the 0-based index of the header
@@ -892,7 +1363,7 @@ g_mime_header_list_write_to_stream (GMimeHeaderList *headers, GMimeFormatOptions
header = (GMimeHeader *) headers->array->pdata[i];
if (!g_mime_format_options_is_hidden_header (options, header->name)) {
- if ((nwritten = g_mime_header_write_to_stream (headers, header, options, filtered))
== -1)
+ if ((nwritten = g_mime_header_write_to_stream (header, options, filtered)) == -1)
return -1;
total += nwritten;
@@ -937,28 +1408,3 @@ g_mime_header_list_to_string (GMimeHeaderList *headers, GMimeFormatOptions *opti
return str;
}
-
-
-/**
- * g_mime_header_list_register_writer:
- * @headers: a #GMimeHeaderList
- * @name: header name
- * @writer: writer function
- *
- * Changes the function used to write @name headers to @writer (or the
- * default if @writer is %NULL). This is useful if you want to change
- * the default header folding style for a particular header.
- **/
-void
-g_mime_header_list_register_writer (GMimeHeaderList *headers, const char *name, GMimeHeaderWriter writer)
-{
- gpointer okey, oval;
-
- g_return_if_fail (GMIME_IS_HEADER_LIST (headers));
- g_return_if_fail (name != NULL);
-
- g_hash_table_remove (headers->writers, name);
-
- if (writer)
- g_hash_table_insert (headers->writers, g_strdup (name), writer);
-}
diff --git a/gmime/gmime-header.h b/gmime/gmime-header.h
index 0a01596..4e56008 100644
--- a/gmime/gmime-header.h
+++ b/gmime/gmime-header.h
@@ -51,20 +51,26 @@ typedef struct _GMimeHeaderListClass GMimeHeaderListClass;
/**
- * GMimeHeaderWriter:
- * @options: The #GMimeParserOptions
- * @format: The #GMimeFormatOptions
- * @stream: The output stream.
- * @name: The field name.
- * @value: The field value.
+ * GMimeHeaderRawValueFormatter:
+ * @header: a #GMimeHeader
+ * @options: a #GMimeFormatOptions
+ * @value: an unencoded header value
+ * @charset: a charset
*
- * Function signature for the callback to
- * g_mime_header_list_register_writer().
+ * Function callback for encoding and formatting a header value.
*
- * Returns: the number of bytes written or %-1 on error.
+ * Returns: the encoded and formatted raw header value.
**/
-typedef ssize_t (* GMimeHeaderWriter) (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream
*stream,
- const char *name, const char *value);
+typedef char * (* GMimeHeaderRawValueFormatter) (GMimeHeader *header, GMimeFormatOptions *options,
+ const char *value, const char *charset);
+
+char *g_mime_header_format_content_disposition (GMimeHeader *header, GMimeFormatOptions *options, const char
*value, const char *charset);
+char *g_mime_header_format_content_type (GMimeHeader *header, GMimeFormatOptions *options, const char
*value, const char *charset);
+char *g_mime_header_format_message_id (GMimeHeader *header, GMimeFormatOptions *options, const char *value,
const char *charset);
+char *g_mime_header_format_references (GMimeHeader *header, GMimeFormatOptions *options, const char *value,
const char *charset);
+char *g_mime_header_format_addrlist (GMimeHeader *header, GMimeFormatOptions *options, const char *value,
const char *charset);
+char *g_mime_header_format_received (GMimeHeader *header, GMimeFormatOptions *options, const char *value,
const char *charset);
+char *g_mime_header_format_default (GMimeHeader *header, GMimeFormatOptions *options, const char *value,
const char *charset);
/**
@@ -80,6 +86,8 @@ struct _GMimeHeader {
char *name, *value;
/* < private > */
+ GMimeHeaderRawValueFormatter formatter;
+ GMimeParserOptions *options;
gpointer changed;
char *raw_value;
char *raw_name;
@@ -98,14 +106,13 @@ const char *g_mime_header_get_name (GMimeHeader *header);
const char *g_mime_header_get_raw_name (GMimeHeader *header);
const char *g_mime_header_get_value (GMimeHeader *header);
-void g_mime_header_set_value (GMimeHeader *header, const char *value);
+void g_mime_header_set_value (GMimeHeader *header, GMimeFormatOptions *options, const char *value, const
char *charset);
const char *g_mime_header_get_raw_value (GMimeHeader *header);
gint64 g_mime_header_get_offset (GMimeHeader *header);
-ssize_t g_mime_header_write_to_stream (GMimeHeaderList *headers, GMimeHeader *header,
- GMimeFormatOptions *options, GMimeStream *stream);
+ssize_t g_mime_header_write_to_stream (GMimeHeader *header, GMimeFormatOptions *options, GMimeStream
*stream);
/**
@@ -118,7 +125,6 @@ struct _GMimeHeaderList {
/* < private > */
GMimeParserOptions *options;
- GHashTable *writers;
gpointer changed;
GHashTable *hash;
GPtrArray *array;
@@ -137,15 +143,14 @@ GMimeHeaderList *g_mime_header_list_new (GMimeParserOptions *options);
void g_mime_header_list_clear (GMimeHeaderList *headers);
int g_mime_header_list_get_count (GMimeHeaderList *headers);
gboolean g_mime_header_list_contains (GMimeHeaderList *headers, const char *name);
-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);
+void g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value, const char
*charset);
+void g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value, const char
*charset);
+void g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value, const char
*charset);
GMimeHeader *g_mime_header_list_get_header (GMimeHeaderList *headers, const char *name);
GMimeHeader *g_mime_header_list_get_header_at (GMimeHeaderList *headers, int index);
gboolean g_mime_header_list_remove (GMimeHeaderList *headers, const char *name);
void g_mime_header_list_remove_at (GMimeHeaderList *headers, int index);
-void g_mime_header_list_register_writer (GMimeHeaderList *headers, const char *name, GMimeHeaderWriter
writer);
ssize_t g_mime_header_list_write_to_stream (GMimeHeaderList *headers, GMimeFormatOptions *options,
GMimeStream *stream);
char *g_mime_header_list_to_string (GMimeHeaderList *headers, GMimeFormatOptions *options);
diff --git a/gmime/gmime-internal.h b/gmime/gmime-internal.h
index 031687e..ab2373a 100644
--- a/gmime/gmime-internal.h
+++ b/gmime/gmime-internal.h
@@ -59,23 +59,15 @@ G_GNUC_INTERNAL void _g_mime_header_set_offset (GMimeHeader *header, gint64 offs
/* GMimeHeaderList */
G_GNUC_INTERNAL GMimeParserOptions *_g_mime_header_list_get_options (GMimeHeaderList *headers);
G_GNUC_INTERNAL void _g_mime_header_list_set_options (GMimeHeaderList *headers, GMimeParserOptions *options);
-G_GNUC_INTERNAL void _g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char
*value,
- const char *raw_name, const char *raw_value, gint64 offset);
-G_GNUC_INTERNAL void _g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char
*value,
- const char *raw_name, const char *raw_value, gint64 offset);
-G_GNUC_INTERNAL void _g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset);
+G_GNUC_INTERNAL void _g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char
*raw_name,
+ const char *raw_value, gint64 offset);
/* GMimeObject */
G_GNUC_INTERNAL void _g_mime_object_block_header_list_changed (GMimeObject *object);
G_GNUC_INTERNAL void _g_mime_object_unblock_header_list_changed (GMimeObject *object);
G_GNUC_INTERNAL void _g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
-G_GNUC_INTERNAL void _g_mime_object_prepend_header (GMimeObject *object, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64
offset);
-G_GNUC_INTERNAL void _g_mime_object_append_header (GMimeObject *object, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64
offset);
-G_GNUC_INTERNAL void _g_mime_object_set_header (GMimeObject *object, const char *name, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset);
+G_GNUC_INTERNAL void _g_mime_object_append_header (GMimeObject *object, const char *name, const char
*raw_name,
+ const char *raw_value, gint64 offset);
/* utils */
G_GNUC_INTERNAL char *_g_mime_utils_unstructured_header_fold (GMimeParserOptions *options,
GMimeFormatOptions *format,
diff --git a/gmime/gmime-message-partial.c b/gmime/gmime-message-partial.c
index 62a94ab..26dd17c 100644
--- a/gmime/gmime-message-partial.c
+++ b/gmime/gmime-message-partial.c
@@ -321,7 +321,7 @@ g_mime_message_partial_reconstruct_message (GMimeMessagePartial **partials, size
static GMimeMessage *
message_partial_message_new (GMimeMessage *base)
{
- const char *name, *value, *raw_name, *raw_value;
+ const char *name, *raw_name, *raw_value;
GMimeHeaderList *headers;
GMimeMessage *message;
GMimeHeader *header;
@@ -339,10 +339,9 @@ message_partial_message_new (GMimeMessage *base)
raw_value = g_mime_header_get_raw_value (header);
raw_name = g_mime_header_get_raw_name (header);
offset = g_mime_header_get_offset (header);
- value = g_mime_header_get_value (header);
name = g_mime_header_get_name (header);
- _g_mime_object_append_header ((GMimeObject *) message, name, value, raw_name, raw_value,
offset);
+ _g_mime_object_append_header ((GMimeObject *) message, name, raw_name, raw_value, offset);
}
return message;
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 3bad84d..ad6f7e0 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -65,20 +65,6 @@ static ssize_t message_write_to_stream (GMimeObject *object, GMimeFormatOptions
gboolean content_only, GMimeStream *stream);
static void message_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
-/*static ssize_t write_structured (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream
*stream,
- const char *name, const char *value);*/
-static ssize_t write_references (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream
*stream,
- const char *name, const char *value);
-static ssize_t write_addrspec (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value);
-static ssize_t write_received (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value);
-static ssize_t write_subject (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value);
-static ssize_t write_msgid (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value);
-
-
static void sender_changed (InternetAddressList *list, gpointer args, GMimeMessage *message);
static void from_changed (InternetAddressList *list, gpointer args, GMimeMessage *message);
static void reply_to_changed (InternetAddressList *list, gpointer args, GMimeMessage *message);
@@ -219,25 +205,6 @@ g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass)
message->addrlists[i] = internet_address_list_new ();
connect_changed_event (message, i);
}
-
- g_mime_header_list_register_writer (headers, "Reply-To", write_addrspec);
- 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-Reply-To", 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_references);
}
static void
@@ -264,386 +231,6 @@ g_mime_message_finalize (GObject *object)
}
-typedef void (* token_skip_t) (const char **in);
-
-struct _received_token {
- char *token;
- size_t len;
- token_skip_t skip;
-};
-
-static void skip_cfws_atom (const char **in);
-static void skip_domain (const char **in);
-static void skip_addr (const char **in);
-static void skip_msgid (const char **in);
-
-static struct _received_token received_tokens[] = {
- { "from ", 5, skip_domain },
- { "by ", 3, skip_domain },
- { "via ", 4, skip_cfws_atom },
- { "with ", 5, skip_cfws_atom },
- { "id ", 3, skip_msgid },
- { "for ", 4, skip_addr }
-};
-
-static void
-skip_cfws_atom (const char **in)
-{
- skip_cfws (in);
- skip_atom (in);
-}
-
-static void
-skip_domain_subliteral (const char **in)
-{
- const char *inptr = *in;
-
- while (*inptr && *inptr != '.' && *inptr != ']') {
- if (is_dtext (*inptr)) {
- inptr++;
- } else if (is_lwsp (*inptr)) {
- skip_cfws (&inptr);
- } else {
- break;
- }
- }
-
- *in = inptr;
-}
-
-static void
-skip_domain_literal (const char **in)
-{
- const char *inptr = *in;
-
- skip_cfws (&inptr);
- while (*inptr && *inptr != ']') {
- skip_domain_subliteral (&inptr);
- if (*inptr && *inptr != ']')
- inptr++;
- }
-
- *in = inptr;
-}
-
-static void
-skip_domain (const char **in)
-{
- const char *save, *inptr = *in;
-
- while (inptr && *inptr) {
- skip_cfws (&inptr);
- if (*inptr == '[') {
- /* domain literal */
- inptr++;
- skip_domain_literal (&inptr);
- if (*inptr == ']')
- inptr++;
- } else {
- skip_atom (&inptr);
- }
-
- save = inptr;
- skip_cfws (&inptr);
- if (*inptr != '.') {
- inptr = save;
- break;
- }
-
- inptr++;
- }
-
- *in = inptr;
-}
-
-static void
-skip_addrspec (const char **in)
-{
- const char *inptr = *in;
-
- skip_cfws (&inptr);
- skip_word (&inptr);
- skip_cfws (&inptr);
-
- while (*inptr == '.') {
- inptr++;
- skip_cfws (&inptr);
- skip_word (&inptr);
- skip_cfws (&inptr);
- }
-
- if (*inptr == '@') {
- inptr++;
- skip_domain (&inptr);
- }
-
- *in = inptr;
-}
-
-static void
-skip_addr (const char **in)
-{
- const char *inptr = *in;
-
- skip_cfws (&inptr);
- if (*inptr == '<') {
- inptr++;
- skip_addrspec (&inptr);
- if (*inptr == '>')
- inptr++;
- } else {
- skip_addrspec (&inptr);
- }
-
- *in = inptr;
-}
-
-static void
-skip_msgid (const char **in)
-{
- const char *inptr = *in;
-
- skip_cfws (&inptr);
- if (*inptr == '<') {
- inptr++;
- skip_addrspec (&inptr);
- if (*inptr == '>')
- inptr++;
- } else {
- skip_atom (&inptr);
- }
-
- *in = inptr;
-}
-
-
-struct _received_part {
- struct _received_part *next;
- const char *start;
- size_t len;
-};
-
-static ssize_t
-write_received (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- struct _received_part *parts, *part, *tail;
- const char *inptr, *lwsp = NULL;
- ssize_t nwritten;
- GString *str;
- size_t len;
- guint i;
-
- while (is_lwsp (*value))
- value++;
-
- if (*value == '\0')
- return 0;
-
- str = g_string_new (name);
- g_string_append_len (str, ": ", 2);
- len = 10;
-
- tail = parts = part = g_alloca (sizeof (struct _received_part));
- part->start = inptr = value;
- part->next = NULL;
-
- while (*inptr) {
- for (i = 0; i < G_N_ELEMENTS (received_tokens); i++) {
- if (!strncmp (inptr, received_tokens[i].token, received_tokens[i].len)) {
- if (inptr > part->start) {
- g_assert (lwsp != NULL);
- part->len = lwsp - part->start;
-
- part = g_alloca (sizeof (struct _received_part));
- part->start = inptr;
- part->next = NULL;
-
- tail->next = part;
- tail = part;
- }
-
- inptr += received_tokens[i].len;
- received_tokens[i].skip (&inptr);
-
- lwsp = inptr;
- while (is_lwsp (*inptr))
- inptr++;
-
- if (*inptr == ';') {
- inptr++;
-
- part->len = inptr - part->start;
-
- lwsp = inptr;
- while (is_lwsp (*inptr))
- inptr++;
-
- part = g_alloca (sizeof (struct _received_part));
- part->start = inptr;
- part->next = NULL;
-
- tail->next = part;
- tail = part;
- }
-
- break;
- }
- }
-
- if (i == G_N_ELEMENTS (received_tokens)) {
- while (*inptr && !is_lwsp (*inptr))
- inptr++;
-
- lwsp = inptr;
- while (is_lwsp (*inptr))
- inptr++;
- }
-
- if (*inptr == '(') {
- skip_comment (&inptr);
-
- lwsp = inptr;
- while (is_lwsp (*inptr))
- inptr++;
- }
- }
-
- part->len = lwsp - part->start;
-
- lwsp = NULL;
- part = parts;
- do {
- len += lwsp ? part->start - lwsp : 0;
- if (len + part->len > GMIME_FOLD_LEN && part != parts) {
- g_string_append (str, "\n\t");
- len = 1;
- } else if (lwsp) {
- g_string_append_len (str, lwsp, (size_t) (part->start - lwsp));
- }
-
- g_string_append_len (str, part->start, part->len);
- lwsp = part->start + part->len;
- len += part->len;
-
- part = part->next;
- } while (part != NULL);
-
- g_string_append_c (str, '\n');
-
- nwritten = g_mime_stream_write (stream, str->str, str->len);
- g_string_free (str, TRUE);
-
- return nwritten;
-}
-
-static ssize_t
-write_subject (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- char *folded;
- ssize_t n;
-
- folded = _g_mime_utils_unstructured_header_fold (options, format, name, value);
- n = g_mime_stream_write_string (stream, folded);
- g_free (folded);
-
- return n;
-}
-
-static ssize_t
-write_msgid (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- /* Note: we don't want to wrap the Message-Id header - seems to
- break a lot of clients (and servers) */
- return g_mime_stream_printf (stream, "%s: %s\n", name, value);
-}
-
-static ssize_t
-write_references (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- GMimeReferences *references, *reference;
- ssize_t nwritten;
- GString *folded;
- size_t len, n;
-
- /* Note: we don't want to break in the middle of msgid tokens as
- it seems to break a lot of clients (and servers) */
- references = g_mime_references_decode (value);
- folded = g_string_new (name);
- g_string_append_c (folded, ':');
- len = folded->len;
-
- reference = references;
- while (reference != NULL) {
- n = strlen (reference->msgid);
- if (len > 1 && len + n + 3 >= GMIME_FOLD_LEN) {
- g_string_append_len (folded, "\n\t", 2);
- len = 1;
- } else {
- g_string_append_c (folded, ' ');
- len++;
- }
-
- g_string_append_c (folded, '<');
- g_string_append_len (folded, reference->msgid, n);
- g_string_append_c (folded, '>');
- len += n + 2;
-
- reference = reference->next;
- }
-
- g_mime_references_clear (&references);
-
- g_string_append_len (folded, "\n", 1);
- nwritten = g_mime_stream_write (stream, folded->str, folded->len);
- g_string_free (folded, TRUE);
-
- return nwritten;
-}
-
-#if 0
-static ssize_t
-write_structured (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- char *folded;
- ssize_t n;
-
- folded = _g_mime_utils_structured_header_fold (options, format, name, value);
- n = g_mime_stream_write_string (stream, folded);
- g_free (folded);
-
- return n;
-}
-#endif
-
-static ssize_t
-write_addrspec (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- InternetAddressList *addrlist;
- GString *str;
- ssize_t n;
-
- str = g_string_new (name);
- g_string_append (str, ": ");
-
- if (value && (addrlist = internet_address_list_parse (options, value))) {
- internet_address_list_writer (addrlist, format, str);
- g_object_unref (addrlist);
- }
-
- g_string_append_c (str, '\n');
-
- n = g_mime_stream_write (stream, str->str, str->len);
- g_string_free (str, TRUE);
-
- return n;
-}
-
enum {
HEADER_SENDER,
HEADER_FROM,
@@ -694,7 +281,7 @@ message_update_addresses (GMimeMessage *message, GMimeParserOptions *options, GM
if (g_ascii_strcasecmp (address_types[type].name, name) != 0)
continue;
- if ((value = g_mime_header_get_value (header))) {
+ if ((value = g_mime_header_get_raw_value (header))) {
if ((list = internet_address_list_parse (options, value))) {
internet_address_list_append (addrlist, list);
g_object_unref (list);
@@ -745,7 +332,7 @@ process_header (GMimeObject *object, GMimeHeader *header)
g_free (message->subject);
if ((value = g_mime_header_get_value (header)))
- message->subject = g_mime_utils_header_decode_text (options, value);
+ message->subject = g_strdup (value);
else
message->subject = NULL;
break;
@@ -884,7 +471,7 @@ write_headers_to_stream (GMimeObject *object, GMimeFormatOptions *options, GMime
if (offset >= 0 && offset < body_offset) {
if (!g_mime_format_options_is_hidden_header (options, header->name)) {
- if ((nwritten = g_mime_header_write_to_stream (object->headers,
header, options, stream)) == -1)
+ if ((nwritten = g_mime_header_write_to_stream (header, options,
stream)) == -1)
return -1;
total += nwritten;
@@ -893,7 +480,7 @@ write_headers_to_stream (GMimeObject *object, GMimeFormatOptions *options, GMime
index++;
} else {
if (!g_mime_format_options_is_hidden_header (options, header->name)) {
- if ((nwritten = g_mime_header_write_to_stream (mime_part->headers,
body_header, options, stream)) == -1)
+ if ((nwritten = g_mime_header_write_to_stream (body_header, options,
stream)) == -1)
return -1;
total += nwritten;
@@ -907,7 +494,7 @@ write_headers_to_stream (GMimeObject *object, GMimeFormatOptions *options, GMime
header = g_mime_header_list_get_header_at (object->headers, index);
if (!g_mime_format_options_is_hidden_header (options, header->name)) {
- if ((nwritten = g_mime_header_write_to_stream (object->headers, header,
options, stream)) == -1)
+ if ((nwritten = g_mime_header_write_to_stream (header, options, stream)) ==
-1)
return -1;
total += nwritten;
@@ -920,7 +507,7 @@ write_headers_to_stream (GMimeObject *object, GMimeFormatOptions *options, GMime
header = g_mime_header_list_get_header_at (mime_part->headers, body_index);
if (!g_mime_format_options_is_hidden_header (options, header->name)) {
- if ((nwritten = g_mime_header_write_to_stream (mime_part->headers, header,
options, stream)) == -1)
+ if ((nwritten = g_mime_header_write_to_stream (header, options, stream)) ==
-1)
return -1;
total += nwritten;
@@ -1030,7 +617,7 @@ g_mime_message_new (gboolean pretty_headers)
_g_mime_object_block_header_list_changed ((GMimeObject *) message);
for (i = 0; i < G_N_ELEMENTS (rfc822_headers); i++)
- g_mime_header_list_set (headers, rfc822_headers[i], NULL);
+ g_mime_header_list_set (headers, rfc822_headers[i], NULL, NULL);
_g_mime_object_unblock_header_list_changed ((GMimeObject *) message);
}
@@ -1150,7 +737,7 @@ sync_internet_address_list (InternetAddressList *list, GMimeMessage *message, co
string = internet_address_list_to_string (list, options, TRUE);
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, name, string);
+ g_mime_object_set_header (object, name, string, NULL);
_g_mime_object_unblock_header_list_changed (object);
g_free (string);
@@ -1297,19 +884,10 @@ g_mime_message_get_all_recipients (GMimeMessage *message)
void
g_mime_message_set_subject (GMimeMessage *message, const char *subject, const char *charset)
{
- GMimeFormatOptions *options;
- char *encoded;
-
g_return_if_fail (GMIME_IS_MESSAGE (message));
g_return_if_fail (subject != NULL);
- g_free (message->subject);
- message->subject = g_mime_strdup_trim (subject);
-
- options = g_mime_format_options_get_default ();
- encoded = g_mime_utils_header_encode_text (options, message->subject, charset);
- g_mime_object_set_header ((GMimeObject *) message, "Subject", encoded);
- g_free (encoded);
+ g_mime_object_set_header ((GMimeObject *) message, "Subject", subject, charset);
}
@@ -1351,7 +929,7 @@ g_mime_message_set_date (GMimeMessage *message, time_t date, int tz_offset)
message->tz_offset = tz_offset;
str = g_mime_utils_header_format_date (date, tz_offset);
- g_mime_object_set_header (GMIME_OBJECT (message), "Date", str);
+ g_mime_object_set_header ((GMimeObject *) message, "Date", str, NULL);
g_free (str);
}
@@ -1417,7 +995,7 @@ g_mime_message_set_date_as_string (GMimeMessage *message, const char *str)
message->date = date;
buf = g_mime_utils_header_format_date (date, tz_offset);
- g_mime_object_set_header (GMIME_OBJECT (message), "Date", buf);
+ g_mime_object_set_header ((GMimeObject *) message, "Date", buf, NULL);
g_free (buf);
}
@@ -1437,11 +1015,8 @@ g_mime_message_set_message_id (GMimeMessage *message, const char *message_id)
g_return_if_fail (GMIME_IS_MESSAGE (message));
g_return_if_fail (message_id != NULL);
- g_free (message->message_id);
- message->message_id = g_mime_strdup_trim (message_id);
-
msgid = g_strdup_printf ("<%s>", message_id);
- g_mime_object_set_header (GMIME_OBJECT (message), "Message-Id", msgid);
+ g_mime_object_set_header ((GMimeObject *) message, "Message-Id", msgid, NULL);
g_free (msgid);
}
@@ -1508,7 +1083,7 @@ g_mime_message_set_mime_part (GMimeMessage *message, GMimeObject *mime_part)
int i;
if (!g_mime_header_list_contains (headers, "MIME-Version"))
- g_mime_header_list_append (headers, "MIME-Version", "1.0");
+ g_mime_header_list_append (headers, "MIME-Version", "1.0", NULL);
for (i = 0; i < g_mime_header_list_get_count (mime_part->headers); i++) {
header = g_mime_header_list_get_header_at (mime_part->headers, i);
diff --git a/gmime/gmime-object.c b/gmime/gmime-object.c
index 5e94da1..cff90d4 100644
--- a/gmime/gmime-object.c
+++ b/gmime/gmime-object.c
@@ -73,11 +73,6 @@ static char *object_get_headers (GMimeObject *object, GMimeFormatOptions *option
static ssize_t object_write_to_stream (GMimeObject *object, GMimeFormatOptions *options, gboolean
content_only, GMimeStream *stream);
static void object_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
-static ssize_t write_content_type (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream
*stream,
- const char *name, const char *value);
-static ssize_t write_disposition (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream
*stream,
- const char *name, const char *value);
-
static void header_list_changed (GMimeHeaderList *headers, GMimeHeaderListChangedEventArgs *args,
GMimeObject *object);
static void content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject *object);
static void content_disposition_changed (GMimeContentDisposition *disposition, gpointer args, GMimeObject
*object);
@@ -146,9 +141,6 @@ g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass)
object->content_type = NULL;
object->disposition = NULL;
object->content_id = NULL;
-
- 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);
}
@@ -209,7 +201,6 @@ object_header_changed (GMimeObject *object, GMimeHeader *header)
const char *name, *value;
guint i;
- value = g_mime_header_get_value (header);
name = g_mime_header_get_name (header);
if (g_ascii_strncasecmp (name, "Content-", 8) != 0)
@@ -222,16 +213,19 @@ object_header_changed (GMimeObject *object, GMimeHeader *header)
switch (i) {
case HEADER_CONTENT_DISPOSITION:
+ value = g_mime_header_get_value (header);
disposition = g_mime_content_disposition_parse (options, value);
_g_mime_object_set_content_disposition (object, disposition);
g_object_unref (disposition);
break;
case HEADER_CONTENT_TYPE:
+ value = g_mime_header_get_value (header);
content_type = g_mime_content_type_parse (options, value);
_g_mime_object_set_content_type (object, content_type);
g_object_unref (content_type);
break;
case HEADER_CONTENT_ID:
+ value = g_mime_header_get_value (header);
g_free (object->content_id);
object->content_id = g_mime_utils_decode_message_id (value);
break;
@@ -309,31 +303,6 @@ header_list_changed (GMimeHeaderList *headers, GMimeHeaderListChangedEventArgs *
}
}
-static ssize_t
-write_content_type (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- GMimeContentType *content_type;
- ssize_t nwritten;
- char *raw_value;
- GString *str;
-
- str = g_string_new (name);
- g_string_append_c (str, ':');
-
- content_type = g_mime_content_type_parse (options, value);
- raw_value = g_mime_content_type_encode (content_type, format);
- g_object_unref (content_type);
-
- g_string_append (str, raw_value);
- g_free (raw_value);
-
- nwritten = g_mime_stream_write (stream, str->str, str->len);
- g_string_free (str, TRUE);
-
- return nwritten;
-}
-
void
_g_mime_object_block_header_list_changed (GMimeObject *object)
{
@@ -390,7 +359,7 @@ content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject
value = unfold_raw_value (raw_value);
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, "Content-Type", value);
+ g_mime_header_list_set (object->headers, "Content-Type", value, NULL);
header = g_mime_header_list_get_header (object->headers, "Content-Type");
_g_mime_header_set_raw_value (header, raw_value);
_g_mime_object_unblock_header_list_changed (object);
@@ -398,30 +367,6 @@ content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject
g_free (value);
}
-static ssize_t
-write_disposition (GMimeParserOptions *options, GMimeFormatOptions *format, GMimeStream *stream,
- const char *name, const char *value)
-{
- GMimeContentDisposition *disposition;
- ssize_t nwritten;
- char *raw_value;
- GString *str;
-
- str = g_string_new (name);
- g_string_append_c (str, ':');
-
- disposition = g_mime_content_disposition_parse (options, value);
- g_string_append (str, disposition->disposition);
-
- g_mime_param_list_encode (disposition->params, format, TRUE, str);
- g_object_unref (disposition);
-
- nwritten = g_mime_stream_write (stream, str->str, str->len);
- g_string_free (str, TRUE);
-
- return nwritten;
-}
-
static void
content_disposition_changed (GMimeContentDisposition *disposition, gpointer args, GMimeObject *object)
{
@@ -436,7 +381,7 @@ content_disposition_changed (GMimeContentDisposition *disposition, gpointer args
raw_value = g_mime_content_disposition_encode (object->disposition, options);
value = unfold_raw_value (raw_value);
- g_mime_header_list_set (object->headers, "Content-Disposition", value);
+ g_mime_header_list_set (object->headers, "Content-Disposition", value, NULL);
header = g_mime_header_list_get_header (object->headers, "Content-Disposition");
_g_mime_header_set_raw_value (header, raw_value);
g_free (raw_value);
@@ -901,7 +846,7 @@ g_mime_object_set_content_id (GMimeObject *object, const char *content_id)
msgid = g_strdup_printf ("<%s>", content_id);
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, "Content-Id", msgid);
+ g_mime_header_list_set (object->headers, "Content-Id", msgid, NULL);
_g_mime_object_unblock_header_list_changed (object);
g_free (msgid);
}
@@ -924,39 +869,30 @@ g_mime_object_get_content_id (GMimeObject *object)
}
-void
-_g_mime_object_prepend_header (GMimeObject *object, const char *header, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset)
-{
- _g_mime_header_list_prepend (object->headers, header, value, raw_name, raw_value, offset);
-}
-
-
/**
* g_mime_object_prepend_header:
* @object: a #GMimeObject
* @header: header name
* @value: header value
+ * @charset: a charset
*
- * Prepends a raw, unprocessed header to the MIME object.
- *
- * Note: @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
+ * Prepends a new header to the header list.
**/
void
-g_mime_object_prepend_header (GMimeObject *object, const char *header, const char *value)
+g_mime_object_prepend_header (GMimeObject *object, const char *header, const char *value, const char
*charset)
{
g_return_if_fail (GMIME_IS_OBJECT (object));
+ g_return_if_fail (header != NULL);
- g_mime_header_list_prepend (object->headers, header, value);
+ g_mime_header_list_prepend (object->headers, header, value, charset);
}
void
-_g_mime_object_append_header (GMimeObject *object, const char *header, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset)
+_g_mime_object_append_header (GMimeObject *object, const char *header, const char *raw_name,
+ const char *raw_value, gint64 offset)
{
- _g_mime_header_list_append (object->headers, header, value, raw_name, raw_value, offset);
+ _g_mime_header_list_append (object->headers, header, raw_name, raw_value, offset);
}
@@ -965,26 +901,17 @@ _g_mime_object_append_header (GMimeObject *object, const char *header, const cha
* @object: a #GMimeObject
* @header: header name
* @value: header value
+ * @charset: a charset
*
- * Appends a raw, unprocessed header to the MIME object.
- *
- * Note: @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
+ * Appends a new header to the header list.
**/
void
-g_mime_object_append_header (GMimeObject *object, const char *header, const char *value)
+g_mime_object_append_header (GMimeObject *object, const char *header, const char *value, const char *charset)
{
g_return_if_fail (GMIME_IS_OBJECT (object));
+ g_return_if_fail (header != NULL);
- g_mime_header_list_append (object->headers, header, value);
-}
-
-
-void
-_g_mime_object_set_header (GMimeObject *object, const char *header, const char *value,
- const char *raw_name, const char *raw_value, gint64 offset)
-{
- _g_mime_header_list_set (object->headers, header, value, raw_name, raw_value, offset);
+ g_mime_header_list_append (object->headers, header, value, charset);
}
@@ -993,18 +920,17 @@ _g_mime_object_set_header (GMimeObject *object, const char *header, const char *
* @object: a #GMimeObject
* @header: header name
* @value: header value
+ * @charset: a charset
*
- * Sets an arbitrary raw, unprocessed header on the MIME object.
- *
- * Note: @value should be encoded with a function such as
- * g_mime_utils_header_encode_text().
+ * Sets a header to the specified value.
**/
void
-g_mime_object_set_header (GMimeObject *object, const char *header, const char *value)
+g_mime_object_set_header (GMimeObject *object, const char *header, const char *value, const char *charset)
{
g_return_if_fail (GMIME_IS_OBJECT (object));
+ g_return_if_fail (header != NULL);
- g_mime_header_list_set (object->headers, header, value);
+ g_mime_header_list_set (object->headers, header, value, charset);
}
@@ -1013,13 +939,10 @@ g_mime_object_set_header (GMimeObject *object, const char *header, const char *v
* @object: a #GMimeObject
* @header: header name
*
- * Gets the raw, unprocessed value of the first header with the specified name.
+ * Gets the value of the first header with the specified name.
*
- * Returns: the raw, unprocessed value of the requested header if it
+ * Returns: the value of the requested header if it
* exists or %NULL otherwise.
- *
- * Note: The returned value should be decoded with a function such as
- * g_mime_utils_header_decode_text() before displaying to the user.
**/
const char *
g_mime_object_get_header (GMimeObject *object, const char *header)
diff --git a/gmime/gmime-object.h b/gmime/gmime-object.h
index f02d069..c29534b 100644
--- a/gmime/gmime-object.h
+++ b/gmime/gmime-object.h
@@ -122,9 +122,9 @@ const char *g_mime_object_get_content_disposition_parameter (GMimeObject *object
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_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);
+void g_mime_object_prepend_header (GMimeObject *object, const char *header, const char *value, const char
*charset);
+void g_mime_object_append_header (GMimeObject *object, const char *header, const char *value, const char
*charset);
+void g_mime_object_set_header (GMimeObject *object, const char *header, const char *value, const char
*charset);
const char *g_mime_object_get_header (GMimeObject *object, const char *header);
gboolean g_mime_object_remove_header (GMimeObject *object, const char *header);
diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index c346603..d4cef20 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -102,8 +102,8 @@ typedef struct _boundary_stack {
} BoundaryStack;
typedef struct {
- char *raw_name, *raw_value;
- char *name, *value;
+ char *raw_name, *name;
+ char *raw_value;
gint64 offset;
} Header;
@@ -184,11 +184,6 @@ struct _GMimeParserPrivate {
char *headerptr;
size_t headerleft;
- /* raw header buffer */
- char *rawbuf;
- char *rawptr;
- size_t rawleft;
-
BoundaryStack *bounds;
short int state;
@@ -275,7 +270,7 @@ parser_find_header (GMimeParser *parser, const char *name, gint64 *offset)
if (offset)
*offset = header->offset;
- return header->value;
+ return header->raw_value;
}
return NULL;
@@ -291,7 +286,6 @@ parser_free_headers (struct _GMimeParserPrivate *priv)
header = priv->headers->pdata[i];
g_free (header->name);
- g_free (header->value);
g_free (header->raw_name);
g_free (header->raw_value);
g_slice_free (Header, header);
@@ -394,10 +388,6 @@ parser_init (GMimeParser *parser, GMimeStream *stream)
priv->headerleft = HEADER_INIT_SIZE - 1;
priv->headerptr = priv->headerbuf;
- priv->rawbuf = g_malloc (HEADER_INIT_SIZE);
- priv->rawleft = HEADER_INIT_SIZE - 1;
- priv->rawptr = priv->rawbuf;
-
priv->message_headers_begin = -1;
priv->message_headers_end = -1;
@@ -425,7 +415,6 @@ parser_close (GMimeParser *parser)
g_byte_array_free (priv->marker, TRUE);
g_free (priv->headerbuf);
- g_free (priv->rawbuf);
parser_free_headers (priv);
g_ptr_array_free (priv->headers, TRUE);
@@ -862,23 +851,6 @@ next_alloc_size (size_t n)
priv->headerleft -= len; \
} G_STMT_END
-#define raw_header_append(priv, start, len) G_STMT_START { \
- if (priv->rawleft <= len) { \
- size_t hlen, hoff; \
- \
- hoff = priv->rawptr - priv->rawbuf; \
- hlen = next_alloc_size (hoff + len + 1); \
- \
- priv->rawbuf = g_realloc (priv->rawbuf, hlen); \
- priv->rawptr = priv->rawbuf + hoff; \
- priv->rawleft = (hlen - 1) - hoff; \
- } \
- \
- memcpy (priv->rawptr, start, len); \
- priv->rawptr += len; \
- priv->rawleft -= len; \
-} G_STMT_END
-
static void
header_parse (GMimeParser *parser)
{
@@ -900,17 +872,15 @@ header_parse (GMimeParser *parser)
priv->headerleft += priv->headerptr - priv->headerbuf;
priv->headerptr = priv->headerbuf;
-
- priv->rawleft += priv->rawptr - priv->rawbuf;
- priv->rawptr = priv->rawbuf;
-
return;
}
header = g_slice_new (Header);
g_ptr_array_add (priv->headers, header);
- header->value = g_mime_strdup_trim (inptr + 1);
+ header->raw_name = g_strndup (priv->headerbuf, (size_t) (inptr - priv->headerbuf));
+ header->raw_value = g_strdup (inptr + 1);
+ header->offset = priv->header_offset;
/* now walk backwards over lwsp characters */
while (inptr > priv->headerbuf && is_blank (inptr[-1]))
@@ -918,24 +888,11 @@ header_parse (GMimeParser *parser)
header->name = g_strndup (priv->headerbuf, (size_t) (inptr - priv->headerbuf));
- *priv->rawptr = ':';
- inptr = priv->rawbuf;
- while (*inptr != ':')
- inptr++;
- *priv->rawptr = '\0';
-
- header->raw_name = g_strndup (priv->rawbuf, (size_t) (inptr - priv->rawbuf));
- header->raw_value = g_strdup (inptr + 1);
- header->offset = priv->header_offset;
-
priv->headerleft += priv->headerptr - priv->headerbuf;
priv->headerptr = priv->headerbuf;
- priv->rawleft += priv->rawptr - priv->rawbuf;
- priv->rawptr = priv->rawbuf;
-
if (priv->regex && g_regex_match (priv->regex, header->name, 0, NULL))
- priv->header_cb (parser, header->name, header->value,
+ priv->header_cb (parser, header->name, header->raw_value,
header->offset, priv->user_data);
}
@@ -1114,7 +1071,6 @@ parser_step_headers (GMimeParser *parser)
len--;
}
- raw_header_append (priv, start, len);
header_append (priv, start, len);
left = (ssize_t) (inend - inptr);
priv->midline = TRUE;
@@ -1122,7 +1078,7 @@ parser_step_headers (GMimeParser *parser)
goto refill;
}
- raw_header_append (priv, start, len);
+ header_append (priv, start, len);
if (inptr > start && inptr[-1] == '\r')
len--;
@@ -1131,10 +1087,8 @@ parser_step_headers (GMimeParser *parser)
if (!priv->midline && len == 0)
goto headers_end;
- header_append (priv, start, len);
-
/* inptr has to be less than inend - 1 */
- raw_header_append (priv, "\n", 1);
+ header_append (priv, "\n", 1);
priv->midline = FALSE;
continuation = TRUE;
inptr++;
@@ -1150,7 +1104,6 @@ parser_step_headers (GMimeParser *parser)
len = (size_t) (inend - inptr);
header_append (priv, inptr, len);
- raw_header_append (priv, inptr, len);
headers_end:
@@ -1680,8 +1633,8 @@ parser_scan_message_part (GMimeParser *parser, GMimeParserOptions *options, GMim
header = priv->headers->pdata[i];
if (g_ascii_strncasecmp (header->name, "Content-", 8) != 0) {
- _g_mime_object_append_header ((GMimeObject *) message, header->name, header->value,
- header->raw_name, header->raw_value, header->offset);
+ _g_mime_object_append_header ((GMimeObject *) message, header->name, header->raw_name,
+ header->raw_value, header->offset);
}
}
@@ -1722,9 +1675,8 @@ parser_construct_leaf_part (GMimeParser *parser, GMimeParserOptions *options, Co
header = priv->headers->pdata[i];
if (!toplevel || !g_ascii_strncasecmp (header->name, "Content-", 8)) {
- _g_mime_object_append_header (object, header->name, header->value,
- header->raw_name, header->raw_value,
- header->offset);
+ _g_mime_object_append_header (object, header->name, header->raw_name,
+ header->raw_value, header->offset);
}
}
@@ -1866,9 +1818,8 @@ parser_construct_multipart (GMimeParser *parser, GMimeParserOptions *options, Co
header = priv->headers->pdata[i];
if (!toplevel || !g_ascii_strncasecmp (header->name, "Content-", 8)) {
- _g_mime_object_append_header (object, header->name, header->value,
- header->raw_name, header->raw_value,
- header->offset);
+ _g_mime_object_append_header (object, header->name, header->raw_name,
+ header->raw_value, header->offset);
}
}
@@ -1973,6 +1924,7 @@ parser_construct_message (GMimeParser *parser, GMimeParserOptions *options)
GMimeObject *object;
GMimeStream *stream;
BoundaryType found;
+ const char *inptr;
Header *header;
char *endptr;
guint i;
@@ -1996,14 +1948,18 @@ parser_construct_message (GMimeParser *parser, GMimeParserOptions *options)
header = priv->headers->pdata[i];
if (priv->respect_content_length && !g_ascii_strcasecmp (header->name, "Content-Length")) {
- content_length = strtoul (header->value, &endptr, 10);
- if (endptr == header->value)
+ inptr = header->raw_value;
+ while (is_lwsp (*inptr))
+ inptr++;
+
+ content_length = strtoul (inptr, &endptr, 10);
+ if (endptr == inptr)
content_length = ULONG_MAX;
}
if (g_ascii_strncasecmp (header->name, "Content-", 8) != 0) {
- _g_mime_object_append_header ((GMimeObject *) message, header->name, header->value,
- header->raw_name, header->raw_value, header->offset);
+ _g_mime_object_append_header ((GMimeObject *) message, header->name, header->raw_name,
+ header->raw_value, header->offset);
}
}
diff --git a/gmime/gmime-part.c b/gmime/gmime-part.c
index dcb220f..fa5a07e 100644
--- a/gmime/gmime-part.c
+++ b/gmime/gmime-part.c
@@ -188,7 +188,6 @@ process_header (GMimeObject *object, GMimeHeader *header)
char encoding[32];
guint i;
- value = g_mime_header_get_value (header);
name = g_mime_header_get_name (header);
if (g_ascii_strncasecmp (name, "Content-", 8) != 0)
@@ -201,21 +200,24 @@ process_header (GMimeObject *object, GMimeHeader *header)
switch (i) {
case HEADER_CONTENT_TRANSFER_ENCODING:
+ value = g_mime_header_get_value (header);
copy_atom (value, encoding, sizeof (encoding) - 1);
mime_part->encoding = g_mime_content_encoding_from_string (encoding);
break;
case HEADER_CONTENT_DESCRIPTION:
- /* FIXME: we should decode this */
+ value = g_mime_header_get_value (header);
g_free (mime_part->content_description);
- mime_part->content_description = g_mime_strdup_trim (value);
+ mime_part->content_description = g_strdup (value);
break;
case HEADER_CONTENT_LOCATION:
+ value = g_mime_header_get_value (header);
g_free (mime_part->content_location);
- mime_part->content_location = g_mime_strdup_trim (value);
+ mime_part->content_location = g_strdup (value);
break;
case HEADER_CONTENT_MD5:
+ value = g_mime_header_get_value (header);
g_free (mime_part->content_md5);
- mime_part->content_md5 = g_mime_strdup_trim (value);
+ mime_part->content_md5 = g_strdup (value);
break;
default:
return FALSE;
@@ -541,7 +543,7 @@ g_mime_part_set_content_description (GMimePart *mime_part, const char *descripti
mime_part->content_description = g_strdup (description);
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, "Content-Description", description);
+ g_mime_header_list_set (object->headers, "Content-Description", description, NULL);
_g_mime_object_unblock_header_list_changed (object);
}
@@ -654,7 +656,7 @@ g_mime_part_set_content_md5 (GMimePart *mime_part, const char *content_md5)
mime_part->content_md5 = g_strdup (content_md5);
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, "Content-Md5", content_md5);
+ g_mime_header_list_set (object->headers, "Content-Md5", content_md5, NULL);
_g_mime_object_unblock_header_list_changed (object);
}
@@ -753,7 +755,7 @@ g_mime_part_set_content_location (GMimePart *mime_part, const char *content_loca
mime_part->content_location = g_strdup (content_location);
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, "Content-Location", content_location);
+ g_mime_header_list_set (object->headers, "Content-Location", content_location, NULL);
_g_mime_object_block_header_list_changed (object);
}
@@ -795,7 +797,7 @@ g_mime_part_set_content_encoding (GMimePart *mime_part, GMimeContentEncoding enc
mime_part->encoding = encoding;
_g_mime_object_block_header_list_changed (object);
- g_mime_header_list_set (object->headers, "Content-Transfer-Encoding", value);
+ g_mime_header_list_set (object->headers, "Content-Transfer-Encoding", value, NULL);
_g_mime_object_block_header_list_changed (object);
}
diff --git a/tests/test-headers.c b/tests/test-headers.c
index f21d18b..69c42f0 100644
--- a/tests/test-headers.c
+++ b/tests/test-headers.c
@@ -59,8 +59,8 @@ header_list_new (void)
list = g_mime_header_list_new (g_mime_parser_options_get_default ());
for (i = 1; i < G_N_ELEMENTS (initial); i++)
- g_mime_header_list_append (list, initial[i].name, initial[i].value);
- g_mime_header_list_prepend (list, initial[0].name, initial[0].value);
+ g_mime_header_list_append (list, initial[i].name, initial[i].value, NULL);
+ g_mime_header_list_prepend (list, initial[0].name, initial[0].value, NULL);
return list;
}
@@ -278,7 +278,7 @@ test_content_type_sync (void)
/* let's try this in reverse... set the header value and make sure GMimeContentType gets
updated */
header = g_mime_header_list_get_header_at (headers, 0);
- g_mime_header_set_value (header, "text/html; charset=utf-8");
+ g_mime_header_set_value (header, NULL, "text/html; charset=utf-8", NULL);
type = g_mime_object_get_content_type (object);
if (!g_mime_content_type_is_type (type, "text", "html"))
throw (exception_new ("GMimeContentType object was not updated"));
@@ -342,7 +342,7 @@ test_disposition_sync (void)
/* let's try this in reverse... set the header value and make sure GMimeContentDisposition
gets updated */
header = g_mime_header_list_get_header_at (headers, 1);
- g_mime_header_set_value (header, "attachment; filename=xyz");
+ g_mime_header_set_value (header, NULL, "attachment; filename=xyz", NULL);
disposition = g_mime_object_get_content_disposition (object);
if (!g_mime_content_disposition_is_attachment (disposition))
throw (exception_new ("GMimeContentDisposition object was not updated"));
diff --git a/tests/test-pgpmime.c b/tests/test-pgpmime.c
index 014668f..e2d210b 100644
--- a/tests/test-pgpmime.c
+++ b/tests/test-pgpmime.c
@@ -188,7 +188,7 @@ create_message (GMimeObject *body)
g_object_unref (mailbox);
g_mime_message_set_subject (message, "This is a test message", NULL);
- g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c");
+ g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c", NULL);
g_mime_message_set_mime_part (message, body);
stream = g_mime_stream_mem_new ();
@@ -327,8 +327,8 @@ create_encrypted_message (GMimeCryptoContext *ctx, gboolean sign,
g_object_unref (mailbox);
g_mime_message_set_subject (message, "This is a test message", NULL);
- g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c");
- g_mime_message_set_mime_part (message, GMIME_OBJECT (mpe));
+ g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c", NULL);
+ g_mime_message_set_mime_part (message, (GMimeObject *) mpe);
g_object_unref (mpe);
stream = g_mime_stream_mem_new ();
diff --git a/tests/test-smime.c b/tests/test-smime.c
index d89c603..27df8b0 100644
--- a/tests/test-smime.c
+++ b/tests/test-smime.c
@@ -190,7 +190,7 @@ create_message (GMimeObject *body)
g_object_unref (mailbox);
g_mime_message_set_subject (message, "This is a test message", NULL);
- g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c");
+ g_mime_object_set_header ((GMimeObject *) message, "X-Mailer", "main.c", NULL);
g_mime_message_set_mime_part (message, body);
stream = g_mime_stream_mem_new ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]