gmime r1427 - in trunk: . gmime
- From: fejj svn gnome org
- To: svn-commits-list gnome org
- Subject: gmime r1427 - in trunk: . gmime
- Date: Sat, 6 Sep 2008 14:39:15 +0000 (UTC)
Author: fejj
Date: Sat Sep 6 14:39:15 2008
New Revision: 1427
URL: http://svn.gnome.org/viewvc/gmime?rev=1427&view=rev
Log:
2008-09-06 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-part.c (g_mime_part_set_content_object): Made
virtual, seems like it could be useful.
* gmime/gmime-object.c (set_content_type): Do not serialize the
GMimeContentType object to the headers. This is done elsewhere
now.
(g_mime_object_set_content_type): After calling the virtual
set_content_type(), serialize the GMimeContentType object to the
headers.
* gmime/gmime-multipart-encrypted.c: Get rid of the protocol
member variable, it's not needed.
* gmime/gmime-multipart-signed.c: Get rid of the protocol and
micalg member strings, these aren't needed - just request them
from the content_type.
* gmime/gmime-multipart.c: Get rid of boundary member variable, we
can just request it from the ContentType object. No sense
duplicating strings.
* gmime/gmime-message.c (message_get_headers): Don't write out a
MIME-Version header if a Content-Type header doesn't exist.
* gmime/gmime-parser.c (parser_content_type): Instead of returning
a GMimeContentType object, we now return a simpler ContentType
struct so that we don't waste time processing more of the header
than we need to, all we need is the type/subtype to figure out
which MIME object type to instantiate.
(parser_scan_message_part): After finishing parsing the object,
destroy the content_type ourselves.
(parser_construct_leaf_part): Updated. Don't set a
GMimeContentType on the GMimeObject unless the Content-Type header
doesn't exist (if it does exist, then appending the Content-Type
header will cause one to be created and set on the GMimeObject).
(parser_construct_multipart): Updated.
* gmime/gmime-content-type.c (g_mime_content_type_new_from_string):
Use the new g_mime_parse_content_type() utility function and set
the parsed string values on the new GMimeContentType object
directly to avoid unnecessary strdup()ing.
* gmime/gmime-parse-utils.c (g_mime_parse_content_type): New
function to parse the simple type/subtype Content-Type form.
Modified:
trunk/ChangeLog
trunk/gmime/gmime-content-type.c
trunk/gmime/gmime-message.c
trunk/gmime/gmime-multipart-encrypted.c
trunk/gmime/gmime-multipart-encrypted.h
trunk/gmime/gmime-multipart-signed.c
trunk/gmime/gmime-multipart-signed.h
trunk/gmime/gmime-multipart.c
trunk/gmime/gmime-object.c
trunk/gmime/gmime-object.h
trunk/gmime/gmime-parse-utils.c
trunk/gmime/gmime-parse-utils.h
trunk/gmime/gmime-parser.c
trunk/gmime/gmime-part.c
trunk/gmime/gmime-part.h
Modified: trunk/gmime/gmime-content-type.c
==============================================================================
--- trunk/gmime/gmime-content-type.c (original)
+++ trunk/gmime/gmime-content-type.c Sat Sep 6 14:39:15 2008
@@ -194,45 +194,20 @@
g_mime_content_type_new_from_string (const char *str)
{
GMimeContentType *mime_type;
- char *type = NULL, *subtype;
const char *inptr = str;
+ char *type, *subtype;
g_return_val_if_fail (str != NULL, NULL);
- /* get the type */
- type = (char *) inptr;
- while (*inptr && is_ttoken (*inptr))
- inptr++;
-
- type = g_strndup (type, (unsigned) (inptr - type));
+ if (!g_mime_parse_content_type (&inptr, &type, &subtype))
+ return g_mime_content_type_new ("application", "octet-stream");
- decode_lwsp (&inptr);
-
- /* get the subtype */
- if (*inptr == '/') {
- inptr++;
-
- decode_lwsp (&inptr);
-
- subtype = (char *) inptr;
- while (*inptr && is_ttoken (*inptr))
- inptr++;
-
- if (inptr > subtype)
- subtype = g_strndup (subtype, (size_t) (inptr - subtype));
- else
- subtype = NULL;
-
- decode_lwsp (&inptr);
- } else {
- subtype = NULL;
- }
-
- mime_type = g_mime_content_type_new (type, subtype);
- g_free (subtype);
- g_free (type);
+ mime_type = g_object_new (GMIME_TYPE_CONTENT_TYPE, NULL);
+ mime_type->subtype = subtype;
+ mime_type->type = type;
/* skip past any remaining junk that shouldn't be here... */
+ decode_lwsp (&inptr);
while (*inptr && *inptr != ';')
inptr++;
Modified: trunk/gmime/gmime-message.c
==============================================================================
--- trunk/gmime/gmime-message.c (original)
+++ trunk/gmime/gmime-message.c Sat Sep 6 14:39:15 2008
@@ -948,7 +948,8 @@
} else {
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");
+ if (g_mime_object_get_header (message->mime_part, "Content-Type"))
+ g_mime_stream_write_string (stream, "MIME-Version: 1.0\n");
g_mime_header_list_write_to_stream (message->mime_part->headers, stream);
}
}
Modified: trunk/gmime/gmime-multipart-encrypted.c
==============================================================================
--- trunk/gmime/gmime-multipart-encrypted.c (original)
+++ trunk/gmime/gmime-multipart-encrypted.c Sat Sep 6 14:39:15 2008
@@ -119,7 +119,6 @@
static void
g_mime_multipart_encrypted_init (GMimeMultipartEncrypted *mpe, GMimeMultipartEncryptedClass *klass)
{
- mpe->protocol = NULL;
mpe->decrypted = NULL;
mpe->validity = NULL;
}
@@ -129,8 +128,6 @@
{
GMimeMultipartEncrypted *mpe = (GMimeMultipartEncrypted *) object;
- g_free (mpe->protocol);
-
if (mpe->decrypted)
g_object_unref (mpe->decrypted);
@@ -173,13 +170,6 @@
static void
multipart_encrypted_set_content_type (GMimeObject *object, GMimeContentType *content_type)
{
- GMimeMultipartEncrypted *mpe = (GMimeMultipartEncrypted *) object;
- const char *protocol;
-
- protocol = g_mime_content_type_get_parameter (content_type, "protocol");
- g_free (mpe->protocol);
- mpe->protocol = g_strdup (protocol);
-
GMIME_OBJECT_CLASS (parent_class)->set_content_type (object, content_type);
}
@@ -295,7 +285,6 @@
g_object_unref (wrapper);
g_object_unref (stream);
- mpe->protocol = g_strdup (ctx->encrypt_protocol);
mpe->decrypted = content;
g_object_ref (content);
@@ -315,7 +304,8 @@
g_object_unref (version_part);
/* set the content-type params for this multipart/encrypted part */
- g_mime_object_set_content_type_parameter (GMIME_OBJECT (mpe), "protocol", mpe->protocol);
+ g_mime_object_set_content_type_parameter (GMIME_OBJECT (mpe), "protocol",
+ ctx->encrypt_protocol);
g_mime_multipart_set_boundary (GMIME_MULTIPART (mpe), NULL);
return 0;
Modified: trunk/gmime/gmime-multipart-encrypted.h
==============================================================================
--- trunk/gmime/gmime-multipart-encrypted.h (original)
+++ trunk/gmime/gmime-multipart-encrypted.h Sat Sep 6 14:39:15 2008
@@ -48,7 +48,6 @@
* @parent_object: parent #GMimeMultipart
* @validity: a #GMimeSignatureValidity if the part has been decrypted or %NULL otherwise
* @decrypted: cached decrypted MIME part
- * @protocol: encryption protocol string
*
* A multipart/encrypted MIME part.
**/
@@ -57,7 +56,6 @@
GMimeSignatureValidity *validity;
GMimeObject *decrypted;
- char *protocol;
};
struct _GMimeMultipartEncryptedClass {
Modified: trunk/gmime/gmime-multipart-signed.c
==============================================================================
--- trunk/gmime/gmime-multipart-signed.c (original)
+++ trunk/gmime/gmime-multipart-signed.c Sat Sep 6 14:39:15 2008
@@ -119,8 +119,7 @@
static void
g_mime_multipart_signed_init (GMimeMultipartSigned *mps, GMimeMultipartSignedClass *klass)
{
- mps->protocol = NULL;
- mps->micalg = NULL;
+
}
static void
@@ -128,9 +127,6 @@
{
GMimeMultipartSigned *mps = (GMimeMultipartSigned *) object;
- g_free (mps->protocol);
- g_free (mps->micalg);
-
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -167,17 +163,6 @@
static void
multipart_signed_set_content_type (GMimeObject *object, GMimeContentType *content_type)
{
- GMimeMultipartSigned *mps = (GMimeMultipartSigned *) object;
- const char *protocol, *micalg;
-
- protocol = g_mime_content_type_get_parameter (content_type, "protocol");
- g_free (mps->protocol);
- mps->protocol = g_strdup (protocol);
-
- micalg = g_mime_content_type_get_parameter (content_type, "micalg");
- g_free (mps->micalg);
- mps->micalg = g_strdup (micalg);
-
GMIME_OBJECT_CLASS (parent_class)->set_content_type (object, content_type);
}
@@ -289,6 +274,7 @@
GMimePart *signature;
GMimeFilter *filter;
GMimeParser *parser;
+ const char *micalg;
int rv;
g_return_val_if_fail (GMIME_IS_MULTIPART_SIGNED (mps), -1);
@@ -340,10 +326,10 @@
g_mime_stream_reset (stream);
/* set the multipart/signed protocol and micalg */
- mps->protocol = g_strdup (ctx->sign_protocol);
- mps->micalg = g_strdup (g_mime_cipher_context_hash_name (ctx, (GMimeCipherHash) rv));
- g_mime_object_set_content_type_parameter (GMIME_OBJECT (mps), "protocol", mps->protocol);
- g_mime_object_set_content_type_parameter (GMIME_OBJECT (mps), "micalg", mps->micalg);
+ content_type = g_mime_object_get_content_type (GMIME_OBJECT (mps));
+ g_mime_content_type_set_parameter (content_type, "protocol", ctx->sign_protocol);
+ micalg = g_strdup (g_mime_cipher_context_hash_name (ctx, (GMimeCipherHash) rv));
+ g_mime_content_type_set_parameter (content_type, "micalg", micalg);
g_mime_multipart_set_boundary (GMIME_MULTIPART (mps), NULL);
/* construct the content part */
@@ -353,7 +339,7 @@
g_object_unref (parser);
/* construct the signature part */
- content_type = g_mime_content_type_new_from_string (mps->protocol);
+ content_type = g_mime_content_type_new_from_string (ctx->sign_protocol);
signature = g_mime_part_new_with_type (content_type->type, content_type->subtype);
g_object_unref (content_type);
@@ -366,7 +352,7 @@
/* FIXME: temporary hack, this info should probably be set in
* the CipherContext class - maybe ::sign can take/output a
* GMimePart instead. */
- if (!g_ascii_strcasecmp (mps->protocol, "application/pkcs7-signature")) {
+ if (!g_ascii_strcasecmp (ctx->sign_protocol, "application/pkcs7-signature")) {
g_mime_part_set_content_encoding (signature, GMIME_CONTENT_ENCODING_BASE64);
g_mime_part_set_filename (signature, "smime.p7m");
}
@@ -475,7 +461,7 @@
g_mime_stream_reset (sigstream);
/* verify the signature */
- hash = g_mime_cipher_context_hash_id (ctx, mps->micalg);
+ hash = g_mime_cipher_context_hash_id (ctx, micalg);
valid = g_mime_cipher_context_verify (ctx, hash, stream, sigstream, err);
d(printf ("attempted to verify:\n----- BEGIN SIGNED PART -----\n%.*s----- END SIGNED PART -----\n",
Modified: trunk/gmime/gmime-multipart-signed.h
==============================================================================
--- trunk/gmime/gmime-multipart-signed.h (original)
+++ trunk/gmime/gmime-multipart-signed.h Sat Sep 6 14:39:15 2008
@@ -46,16 +46,12 @@
/**
* GMimeMultipartSigned:
* @parent_object: parent #GMimeMultipart
- * @protocol: signature protocol string
- * @micalg: signature hash
*
* A multipart/signed MIME part.
**/
struct _GMimeMultipartSigned {
GMimeMultipart parent_object;
- char *protocol;
- char *micalg;
};
struct _GMimeMultipartSignedClass {
Modified: trunk/gmime/gmime-multipart.c
==============================================================================
--- trunk/gmime/gmime-multipart.c (original)
+++ trunk/gmime/gmime-multipart.c Sat Sep 6 14:39:15 2008
@@ -140,7 +140,6 @@
g_mime_multipart_init (GMimeMultipart *multipart, GMimeMultipartClass *klass)
{
multipart->children = g_ptr_array_new ();
- multipart->boundary = NULL;
multipart->preface = NULL;
multipart->postface = NULL;
}
@@ -151,7 +150,6 @@
GMimeMultipart *multipart = (GMimeMultipart *) object;
guint i;
- g_free (multipart->boundary);
g_free (multipart->preface);
g_free (multipart->postface);
@@ -219,13 +217,6 @@
static void
multipart_set_content_type (GMimeObject *object, GMimeContentType *content_type)
{
- GMimeMultipart *multipart = (GMimeMultipart *) object;
- const char *boundary;
-
- boundary = g_mime_content_type_get_parameter (content_type, "boundary");
- g_free (multipart->boundary);
- multipart->boundary = g_strdup (boundary);
-
GMIME_OBJECT_CLASS (parent_class)->set_content_type (object, content_type);
}
@@ -240,6 +231,7 @@
{
GMimeMultipart *multipart = (GMimeMultipart *) object;
ssize_t nwritten, total = 0;
+ const char *boundary;
GMimeObject *part;
guint i;
@@ -247,8 +239,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_list_has_raw (object->headers))
+ boundary = g_mime_object_get_content_type_parameter (object, "boundary");
+ if (!boundary && !g_mime_header_list_has_raw (object->headers)) {
g_mime_multipart_set_boundary (multipart, NULL);
+ boundary = g_mime_object_get_content_type_parameter (object, "boundary");
+ }
/* write the content headers */
if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
@@ -274,7 +269,7 @@
part = multipart->children->pdata[i];
/* write the boundary */
- if ((nwritten = g_mime_stream_printf (stream, "\n--%s\n", multipart->boundary)) == -1)
+ if ((nwritten = g_mime_stream_printf (stream, "\n--%s\n", boundary)) == -1)
return -1;
total += nwritten;
@@ -287,8 +282,8 @@
}
/* write the end-boundary (but only if a boundary is set) */
- if (multipart->boundary) {
- if ((nwritten = g_mime_stream_printf (stream, "\n--%s--\n", multipart->boundary)) == -1)
+ if (boundary) {
+ if ((nwritten = g_mime_stream_printf (stream, "\n--%s--\n", boundary)) == -1)
return -1;
total += nwritten;
@@ -763,9 +758,6 @@
boundary = bbuf;
}
- g_free (multipart->boundary);
- multipart->boundary = g_strdup (boundary);
-
g_mime_object_set_content_type_parameter (GMIME_OBJECT (multipart), "boundary", boundary);
}
@@ -790,10 +782,15 @@
static const char *
multipart_get_boundary (GMimeMultipart *multipart)
{
- if (!multipart->boundary)
- multipart_set_boundary (multipart, NULL);
+ GMimeObject *object = (GMimeObject *) multipart;
+ const char *boundary;
+
+ if ((boundary = g_mime_object_get_content_type_parameter (object, "boundary")))
+ return boundary;
+
+ multipart_set_boundary (multipart, NULL);
- return multipart->boundary;
+ return g_mime_object_get_content_type_parameter (object, "boundary");
}
Modified: trunk/gmime/gmime-object.c
==============================================================================
--- trunk/gmime/gmime-object.c (original)
+++ trunk/gmime/gmime-object.c Sat Sep 6 14:39:15 2008
@@ -54,6 +54,9 @@
GType object_type;
};
+static void _g_mime_object_set_content_disposition (GMimeObject *object, GMimeContentDisposition *disposition);
+void _g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
+
static void g_mime_object_class_init (GMimeObjectClass *klass);
static void g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass);
static void g_mime_object_finalize (GObject *object);
@@ -292,26 +295,6 @@
g_hash_table_insert (bucket->subtype_hash, sub->subtype, sub);
}
-static void
-set_content_type_internal (GMimeObject *object, GMimeContentType *content_type, gboolean resync)
-{
- if (content_type == object->content_type)
- return;
-
- if (object->content_type) {
- g_signal_handlers_disconnect_matched (object->content_type,
- G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, content_type_changed, object);
- g_object_unref (object->content_type);
- }
-
- g_signal_connect (content_type, "changed", G_CALLBACK (content_type_changed), object);
- object->content_type = content_type;
- g_object_ref (content_type);
-
- if (resync)
- content_type_changed (content_type, object);
-}
/**
* g_mime_object_new:
@@ -426,24 +409,56 @@
static void
set_content_type (GMimeObject *object, GMimeContentType *content_type)
{
- set_content_type_internal (object, content_type, TRUE);
+ if (object->content_type) {
+ g_signal_handlers_disconnect_matched (object->content_type,
+ G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, content_type_changed, object);
+ g_object_unref (object->content_type);
+ }
+
+ g_signal_connect (content_type, "changed", G_CALLBACK (content_type_changed), object);
+ object->content_type = content_type;
+ g_object_ref (content_type);
}
/**
- * g_mime_object_set_content_type:
+ * _g_mime_object_set_content_type:
* @object: a #GMimeObject
- * @mime_type: a #GMimeContentType object
+ * @content_type: a #GMimeContentType object
*
* Sets the content-type for the specified MIME object.
+ *
+ * Note: This method is meant for internal-use only and avoids
+ * serialization of @content_type to the Content-Type header field.
**/
void
-g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *mime_type)
+_g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type)
{
- g_return_if_fail (GMIME_IS_CONTENT_TYPE (mime_type));
+ GMIME_OBJECT_GET_CLASS (object)->set_content_type (object, content_type);
+}
+
+
+/**
+ * g_mime_object_set_content_type:
+ * @object: a #GMimeObject
+ * @content_type: a #GMimeContentType object
+ *
+ * Sets the content-type for the specified MIME object and then
+ * serializes it to the Content-Type header field.
+ **/
+void
+g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type)
+{
+ g_return_if_fail (GMIME_IS_CONTENT_TYPE (content_type));
g_return_if_fail (GMIME_IS_OBJECT (object));
- GMIME_OBJECT_GET_CLASS (object)->set_content_type (object, mime_type);
+ if (object->content_type == content_type)
+ return;
+
+ GMIME_OBJECT_GET_CLASS (object)->set_content_type (object, content_type);
+
+ content_type_changed (content_type, object);
}
@@ -520,13 +535,20 @@
return object->disposition;
}
-
+/**
+ * g_mime_object_set_content_disposition:
+ * @object: a #GMimeObject
+ * @disposition: a #GMimeContentDisposition object
+ *
+ * Set the content disposition for the specified mime part.
+ *
+ * Note: This method is meant for internal-use only and avoids
+ * serialization of @disposition to the Content-Disposition header
+ * field.
+ **/
static void
-set_content_disposition_internal (GMimeObject *object, GMimeContentDisposition *disposition, gboolean resync)
+_g_mime_object_set_content_disposition (GMimeObject *object, GMimeContentDisposition *disposition)
{
- if (disposition == object->disposition)
- return;
-
if (object->disposition) {
g_signal_handlers_disconnect_matched (object->disposition,
G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
@@ -537,17 +559,16 @@
g_signal_connect (disposition, "changed", G_CALLBACK (content_disposition_changed), object);
object->disposition = disposition;
g_object_ref (disposition);
-
- if (resync)
- content_disposition_changed (disposition, object);
}
+
/**
* g_mime_object_set_content_disposition:
* @object: a #GMimeObject
* @disposition: a #GMimeContentDisposition object
*
- * Set the content disposition for the specified mime part.
+ * Set the content disposition for the specified mime part and then
+ * serializes it to the Content-Disposition header field.
**/
void
g_mime_object_set_content_disposition (GMimeObject *object, GMimeContentDisposition *disposition)
@@ -555,7 +576,12 @@
g_return_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition));
g_return_if_fail (GMIME_IS_OBJECT (object));
- set_content_disposition_internal (object, disposition, TRUE);
+ if (object->disposition == disposition)
+ return;
+
+ _g_mime_object_set_content_disposition (object, disposition);
+
+ content_disposition_changed (disposition, object);
}
@@ -628,7 +654,7 @@
if (!object->disposition) {
disposition = g_mime_content_disposition_new ();
- set_content_disposition_internal (object, disposition, FALSE);
+ _g_mime_object_set_content_disposition (object, disposition);
}
g_mime_content_disposition_set_parameter (object->disposition, attribute, value);
@@ -727,12 +753,12 @@
switch (i) {
case HEADER_CONTENT_DISPOSITION:
disposition = g_mime_content_disposition_new_from_string (value);
- set_content_disposition_internal (object, disposition, FALSE);
+ _g_mime_object_set_content_disposition (object, disposition);
g_object_unref (disposition);
break;
case HEADER_CONTENT_TYPE:
content_type = g_mime_content_type_new_from_string (value);
- set_content_type_internal (object, content_type, FALSE);
+ _g_mime_object_set_content_type (object, content_type);
g_object_unref (content_type);
break;
case HEADER_CONTENT_ID:
Modified: trunk/gmime/gmime-object.h
==============================================================================
--- trunk/gmime/gmime-object.h (original)
+++ trunk/gmime/gmime-object.h Sat Sep 6 14:39:15 2008
@@ -97,7 +97,7 @@
GMimeObject *g_mime_object_new (GMimeContentType *content_type);
GMimeObject *g_mime_object_new_type (const char *type, const char *subtype);
-void g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *mime_type);
+void g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
GMimeContentType *g_mime_object_get_content_type (GMimeObject *object);
void g_mime_object_set_content_type_parameter (GMimeObject *object, const char *name, const char *value);
const char *g_mime_object_get_content_type_parameter (GMimeObject *object, const char *name);
Modified: trunk/gmime/gmime-parse-utils.c
==============================================================================
--- trunk/gmime/gmime-parse-utils.c (original)
+++ trunk/gmime/gmime-parse-utils.c Sat Sep 6 14:39:15 2008
@@ -39,6 +39,68 @@
/**
+ * g_mime_parse_content_type:
+ * @in: address of input text string
+ * @type: address of the 'type' output string
+ * @subtype: address of the 'subtype' output string
+ *
+ * Decodes the simple Content-Type type/subtype tokens and updates @in
+ * to point to the first char after the end of the subtype.
+ *
+ * Returns: %TRUE if the string was successfully parsed or %FALSE
+ * otherwise.
+ **/
+gboolean
+g_mime_parse_content_type (const char **in, char **type, char **subtype)
+{
+ register const char *inptr;
+ const char *start = *in;
+
+ decode_lwsp (&start);
+ inptr = start;
+
+ /* decode the type */
+ while (*inptr && is_ttoken (*inptr))
+ inptr++;
+
+ *type = g_strndup (start, (size_t) (inptr - start));
+
+ start = inptr;
+ decode_lwsp (&start);
+
+ /* check for type/subtype delimeter */
+ if (*start++ != '/') {
+ g_free (*type);
+ *subtype = NULL;
+ *type = NULL;
+ return FALSE;
+ }
+
+ decode_lwsp (&start);
+ inptr = start;
+
+ /* decode the subtype */
+ while (*inptr && is_ttoken (*inptr))
+ inptr++;
+
+ /* check that the subtype exists */
+ if (inptr == start) {
+ g_free (*type);
+ *subtype = NULL;
+ *type = NULL;
+ return FALSE;
+ }
+
+ *subtype = g_strndup (start, (size_t) (inptr - start));
+
+ /* update the input string pointer */
+ *in = inptr;
+
+ return TRUE;
+}
+
+
+/**
* g_mime_decode_lwsp:
* @in: address of input text string
*
Modified: trunk/gmime/gmime-parse-utils.h
==============================================================================
--- trunk/gmime/gmime-parse-utils.h (original)
+++ trunk/gmime/gmime-parse-utils.h Sat Sep 6 14:39:15 2008
@@ -24,6 +24,8 @@
G_BEGIN_DECLS
+gboolean g_mime_parse_content_type (const char **in, char **type, char **subtype);
+
void g_mime_decode_lwsp (const char **in);
#define decode_lwsp(in) g_mime_decode_lwsp (in)
Modified: trunk/gmime/gmime-parser.c
==============================================================================
--- trunk/gmime/gmime-parser.c (original)
+++ trunk/gmime/gmime-parser.c Sat Sep 6 14:39:15 2008
@@ -57,6 +57,13 @@
**/
+typedef struct _ContentType {
+ char *type, *subtype;
+ gboolean exists;
+} ContentType;
+
+extern void _g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
+
static void g_mime_parser_class_init (GMimeParserClass *klass);
static void g_mime_parser_init (GMimeParser *parser, GMimeParserClass *klass);
static void g_mime_parser_finalize (GObject *object);
@@ -64,9 +71,9 @@
static void parser_init (GMimeParser *parser, GMimeStream *stream);
static void parser_close (GMimeParser *parser);
-static GMimeObject *parser_construct_leaf_part (GMimeParser *parser, GMimeContentType *content_type,
+static GMimeObject *parser_construct_leaf_part (GMimeParser *parser, ContentType *content_type,
int *found);
-static GMimeObject *parser_construct_multipart (GMimeParser *parser, GMimeContentType *content_type,
+static GMimeObject *parser_construct_multipart (GMimeParser *parser, ContentType *content_type,
int *found);
static GObjectClass *parent_class = NULL;
@@ -125,7 +132,6 @@
unsigned short int persist_stream:1;
unsigned short int respect_content_length:1;
- GMimeContentType *content_type;
struct _header_raw *headers;
struct _boundary_stack *bounds;
@@ -1029,16 +1035,49 @@
return 0;
}
-static GMimeContentType *
+static void
+content_type_destroy (ContentType *content_type)
+{
+ g_free (content_type->subtype);
+ g_free (content_type->type);
+ g_free (content_type);
+}
+
+static gboolean
+content_type_is_type (ContentType *content_type, const char *type, const char *subtype)
+{
+ if (!strcmp (type, "*") || !g_ascii_strcasecmp (content_type->type, type)) {
+ if (!strcmp (subtype, "*")) {
+ /* special case */
+ return TRUE;
+ }
+
+ if (!g_ascii_strcasecmp (content_type->subtype, subtype))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static ContentType *
parser_content_type (GMimeParser *parser)
{
struct _GMimeParserPrivate *priv = parser->priv;
- const char *content_type;
+ register const char *inptr;
+ ContentType *content_type;
+ const char *value;
- if ((content_type = header_raw_find (priv->headers, "Content-Type", NULL)))
- return g_mime_content_type_new_from_string (content_type);
+ content_type = g_new (ContentType, 1);
- return NULL;
+ if (!(value = header_raw_find (priv->headers, "Content-Type", NULL)) ||
+ !g_mime_parse_content_type (&value, &content_type->type, &content_type->subtype)) {
+ content_type->type = g_strdup ("text");
+ content_type->subtype = g_strdup ("plain");
+ }
+
+ content_type->exists = value != NULL;
+
+ return content_type;
}
static int
@@ -1320,8 +1359,8 @@
parser_scan_message_part (GMimeParser *parser, GMimeMessagePart *mpart, int *found)
{
struct _GMimeParserPrivate *priv = parser->priv;
- GMimeContentType *content_type;
struct _header_raw *header;
+ ContentType *content_type;
GMimeMessage *message;
GMimeObject *object;
@@ -1343,14 +1382,13 @@
header = header->next;
}
- if (!(content_type = parser_content_type (parser)))
- content_type = g_mime_content_type_new ("text", "plain");
-
- if (g_mime_content_type_is_type (content_type, "multipart", "*"))
+ content_type = parser_content_type (parser);
+ if (content_type_is_type (content_type, "multipart", "*"))
object = parser_construct_multipart (parser, content_type, found);
else
object = parser_construct_leaf_part (parser, content_type, found);
+ content_type_destroy (content_type);
message->mime_part = object;
g_mime_message_part_set_message (mpart, message);
@@ -1358,7 +1396,7 @@
}
static GMimeObject *
-parser_construct_leaf_part (GMimeParser *parser, GMimeContentType *content_type, int *found)
+parser_construct_leaf_part (GMimeParser *parser, ContentType *content_type, int *found)
{
struct _GMimeParserPrivate *priv = parser->priv;
struct _header_raw *header;
@@ -1368,6 +1406,14 @@
object = g_mime_object_new_type (content_type->type, content_type->subtype);
+ if (!content_type->exists) {
+ GMimeContentType *mime_type;
+
+ mime_type = g_mime_content_type_new ("text", "plain");
+ _g_mime_object_set_content_type (object, mime_type);
+ g_object_unref (mime_type);
+ }
+
header = priv->headers;
while (header) {
g_mime_object_append_header (object, header->name, header->value);
@@ -1376,9 +1422,6 @@
header_raw_clear (&priv->headers);
- g_mime_object_set_content_type (object, content_type);
- g_object_unref (content_type);
-
g_mime_header_list_set_raw (object->headers, priv->rawbuf);
raw_header_reset (priv);
@@ -1468,7 +1511,7 @@
parser_scan_multipart_subparts (GMimeParser *parser, GMimeMultipart *multipart)
{
struct _GMimeParserPrivate *priv = parser->priv;
- GMimeContentType *content_type;
+ ContentType *content_type;
GMimeObject *subpart;
int found;
@@ -1491,15 +1534,14 @@
break;
}
- if (!(content_type = parser_content_type (parser)))
- content_type = g_mime_content_type_new ("text", "plain");
-
- if (g_mime_content_type_is_type (content_type, "multipart", "*"))
+ content_type = parser_content_type (parser);
+ if (content_type_is_type (content_type, "multipart", "*"))
subpart = parser_construct_multipart (parser, content_type, &found);
else
subpart = parser_construct_leaf_part (parser, content_type, &found);
g_mime_multipart_add (multipart, subpart);
+ content_type_destroy (content_type);
g_object_unref (subpart);
} while (found == FOUND_BOUNDARY && found_immediate_boundary (priv, FALSE));
@@ -1507,7 +1549,7 @@
}
static GMimeObject *
-parser_construct_multipart (GMimeParser *parser, GMimeContentType *content_type, int *found)
+parser_construct_multipart (GMimeParser *parser, ContentType *content_type, int *found)
{
struct _GMimeParserPrivate *priv = parser->priv;
struct _header_raw *header;
@@ -1527,9 +1569,6 @@
header_raw_clear (&priv->headers);
- g_mime_object_set_content_type (object, content_type);
- g_object_unref (content_type);
-
g_mime_header_list_set_raw (object->headers, priv->rawbuf);
raw_header_reset (priv);
@@ -1543,7 +1582,7 @@
}
}
- boundary = g_mime_content_type_get_parameter (content_type, "boundary");
+ boundary = g_mime_object_get_content_type_parameter (object, "boundary");
if (boundary) {
parser_push_boundary (parser, boundary);
@@ -1573,7 +1612,7 @@
parser_construct_part (GMimeParser *parser)
{
struct _GMimeParserPrivate *priv = parser->priv;
- GMimeContentType *content_type;
+ ContentType *content_type;
GMimeObject *object;
int found;
@@ -1583,14 +1622,14 @@
return NULL;
}
- if (!(content_type = parser_content_type (parser)))
- content_type = g_mime_content_type_new ("text", "plain");
-
- if (g_mime_content_type_is_type (content_type, "multipart", "*"))
+ content_type = parser_content_type (parser);
+ if (content_type_is_type (content_type, "multipart", "*"))
object = parser_construct_multipart (parser, content_type, &found);
else
object = parser_construct_leaf_part (parser, content_type, &found);
+ content_type_destroy (content_type);
+
return object;
}
@@ -1617,8 +1656,8 @@
{
struct _GMimeParserPrivate *priv = parser->priv;
unsigned long content_length = ULONG_MAX;
- GMimeContentType *content_type;
struct _header_raw *header;
+ ContentType *content_type;
GMimeMessage *message;
GMimeObject *object;
char *endptr;
@@ -1655,14 +1694,13 @@
priv->bounds->content_end = parser_offset (priv, NULL) + content_length;
}
- if (!(content_type = parser_content_type (parser)))
- content_type = g_mime_content_type_new ("text", "plain");
-
- if (content_type && g_mime_content_type_is_type (content_type, "multipart", "*"))
+ content_type = parser_content_type (parser);
+ if (content_type_is_type (content_type, "multipart", "*"))
object = parser_construct_multipart (parser, content_type, &found);
else
object = parser_construct_leaf_part (parser, content_type, &found);
+ content_type_destroy (content_type);
message->mime_part = object;
if (priv->scan_from) {
Modified: trunk/gmime/gmime-part.c
==============================================================================
--- trunk/gmime/gmime-part.c (original)
+++ trunk/gmime/gmime-part.c Sat Sep 6 14:39:15 2008
@@ -67,6 +67,9 @@
static char *mime_part_get_headers (GMimeObject *object);
static ssize_t mime_part_write_to_stream (GMimeObject *object, GMimeStream *stream);
+/* GMimePart class methods */
+static void set_content_object (GMimePart *mime_part, GMimeDataWrapper *content);
+
static GMimeObjectClass *parent_class = NULL;
@@ -113,6 +116,8 @@
object_class->get_header = mime_part_get_header;
object_class->get_headers = mime_part_get_headers;
object_class->write_to_stream = mime_part_write_to_stream;
+
+ klass->set_content_object = set_content_object;
}
static void
@@ -426,8 +431,8 @@
/**
* g_mime_part_new_with_type:
- * @type: content-type
- * @subtype: content-subtype
+ * @type: content-type string
+ * @subtype: content-subtype string
*
* Creates a new MIME Part with a sepcified type.
*
@@ -451,7 +456,7 @@
/**
* g_mime_part_set_content_description:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
* @description: content description
*
* Set the content description for the specified mime part.
@@ -461,9 +466,10 @@
{
g_return_if_fail (GMIME_IS_PART (mime_part));
- if (mime_part->content_description)
- g_free (mime_part->content_description);
+ if (mime_part->content_description == description)
+ return;
+ g_free (mime_part->content_description);
mime_part->content_description = g_strdup (description);
g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Description", description);
}
@@ -471,7 +477,7 @@
/**
* g_mime_part_get_content_description:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
*
* Gets the value of the Content-Description for the specified mime
* part if it exists or %NULL otherwise.
@@ -489,7 +495,7 @@
/**
* g_mime_part_set_content_id:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
* @content_id: content id
*
* Set the content id for the specified mime part.
@@ -505,7 +511,7 @@
/**
* g_mime_part_get_content_id:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
*
* Gets the content-id of the specified mime part if it exists, or
* %NULL otherwise.
@@ -523,7 +529,7 @@
/**
* g_mime_part_set_content_md5:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
* @content_md5: content md5 or %NULL to generate the md5 digest.
*
* Set the content md5 for the specified mime part.
@@ -542,8 +548,7 @@
g_return_if_fail (GMIME_IS_PART (mime_part));
- if (mime_part->content_md5)
- g_free (mime_part->content_md5);
+ g_free (mime_part->content_md5);
if (!content_md5) {
/* compute a md5sum */
@@ -585,7 +590,7 @@
/**
* g_mime_part_verify_content_md5:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
*
* Verify the content md5 for the specified mime part.
*
@@ -644,7 +649,7 @@
/**
* g_mime_part_get_content_md5:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
*
* Gets the md5sum contained in the Content-Md5 header of the
* specified mime part if it exists, or %NULL otherwise.
@@ -672,9 +677,10 @@
{
g_return_if_fail (GMIME_IS_PART (mime_part));
- if (mime_part->content_location)
- g_free (mime_part->content_location);
+ if (mime_part->content_location == content_location)
+ return;
+ g_free (mime_part->content_location);
mime_part->content_location = g_strdup (content_location);
g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Location", content_location);
}
@@ -700,7 +706,7 @@
/**
* g_mime_part_set_content_encoding:
- * @mime_part: a #GMimePart
+ * @mime_part: a #GMimePart object
* @encoding: a #GMimeContentEncoding
*
* Set the content encoding for the specified mime part.
@@ -718,7 +724,7 @@
/**
* g_mime_part_get_content_encoding:
- * @mime_part: a #GMimePart
+ * @mime_part: a #GMimePart object
*
* Gets the content encoding of the mime part.
*
@@ -735,7 +741,7 @@
/**
* g_mime_part_set_filename:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
* @filename: the filename of the Mime Part's content
*
* Sets the "filename" parameter on the Content-Disposition and also sets the
@@ -755,7 +761,7 @@
/**
* g_mime_part_get_filename:
- * @mime_part: Mime part
+ * @mime_part: a #GMimePart object
*
* Gets the filename of the specificed mime part, or %NULL if the mime
* part does not have the filename or name parameter set.
@@ -780,10 +786,20 @@
}
+static void
+set_content_object (GMimePart *mime_part, GMimeDataWrapper *content)
+{
+ if (mime_part->content)
+ g_object_unref (mime_part->content);
+
+ mime_part->content = content;
+ g_object_ref (content);
+}
+
/**
* g_mime_part_set_content_object:
- * @mime_part: MIME Part
- * @content: content object
+ * @mime_part: a #GMimePart object
+ * @content: a #GMimeDataWrapper content object
*
* Sets the content object on the mime part.
**/
@@ -792,19 +808,16 @@
{
g_return_if_fail (GMIME_IS_PART (mime_part));
- if (content)
- g_object_ref (content);
-
- if (mime_part->content)
- g_object_unref (mime_part->content);
+ if (mime_part->content == content)
+ return;
- mime_part->content = content;
+ GMIME_PART_GET_CLASS (mime_part)->set_content_object (mime_part, content);
}
/**
* g_mime_part_get_content_object:
- * @mime_part: MIME part object
+ * @mime_part: a #GMimePart object
*
* Gets the internal data-wrapper of the specified mime part, or %NULL
* on error.
Modified: trunk/gmime/gmime-part.h
==============================================================================
--- trunk/gmime/gmime-part.h (original)
+++ trunk/gmime/gmime-part.h Sat Sep 6 14:39:15 2008
@@ -50,7 +50,7 @@
* @content_md5: Content-MD5 string
* @content: a #GMimeDataWrapper representing the MIME part's content
*
- * Base leaf-node MIME part object.
+ * A leaf-node MIME part object.
**/
struct _GMimePart {
GMimeObject parent_object;
@@ -66,6 +66,7 @@
struct _GMimePartClass {
GMimeObjectClass parent_class;
+ void (* set_content_object) (GMimePart *mime_part, GMimeDataWrapper *content);
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]