[evolution-data-server] Add camel_imapx_stream_nstring_bytes().



commit 7d66c6578120deaae5c19fffe117692839191164
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Feb 5 14:21:37 2014 -0500

    Add camel_imapx_stream_nstring_bytes().
    
    Replaces camel_imapx_stream_nstring_stream().
    
    Produces a GBytes instead of a CamelStreamMem.  GBytes works better
    than GOutputStream would because it can be reused without seeking to
    the beginning.
    
    This basically converts message fetching to use GIO streams directly.

 camel/providers/imapx/Makefile.am          |    2 +
 camel/providers/imapx/camel-imapx-server.c |   59 ++++++-------
 camel/providers/imapx/camel-imapx-stream.c |   32 ++++----
 camel/providers/imapx/camel-imapx-stream.h |    6 +-
 camel/providers/imapx/camel-imapx-utils.c  |  126 +++++++++++++---------------
 camel/providers/imapx/camel-imapx-utils.h  |    6 +-
 docs/reference/camel/camel-sections.txt    |    2 +-
 7 files changed, 113 insertions(+), 120 deletions(-)
---
diff --git a/camel/providers/imapx/Makefile.am b/camel/providers/imapx/Makefile.am
index 7bdfcab..6f5dd77 100644
--- a/camel/providers/imapx/Makefile.am
+++ b/camel/providers/imapx/Makefile.am
@@ -13,6 +13,7 @@ libcamelimapx_la_CPPFLAGS = \
        -I$(top_builddir) \
        -I$(top_builddir)/camel \
        $(CAMEL_CFLAGS) \
+       $(GIO_UNIX_CFLAGS) \
        -DG_LOG_DOMAIN=\"camel-imapx\" \
        $(CODE_COVERAGE_CFLAGS) \
        $(NULL)
@@ -59,6 +60,7 @@ libcamelimapx_la_SOURCES = \
 libcamelimapx_la_LIBADD = \
        $(top_builddir)/camel/libcamel-1.2.la \
        $(CAMEL_LIBS) \
+       $(GIO_UNIX_LIBS) \
        $(NULL)
 
 libcamelimapx_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED) \
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 275542a..fa7bb17 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -96,7 +96,7 @@ struct _GetMessageData {
        gchar *uid;
        CamelDataCache *message_cache;
        /* in/out: message content stream output */
-       CamelStream *stream;
+       GIOStream *stream;
        /* working variables */
        gsize body_offset;
        gsize fetch_offset;
@@ -2250,7 +2250,10 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                 * fill out the body stream, in the right spot. */
 
                if (job != NULL) {
-                       gssize bytes_written;
+                       GOutputStream *output_stream;
+                       gconstpointer body_data;
+                       gsize body_size;
+                       gboolean success;
 
                        if (data->use_multi_fetch) {
                                data->body_offset = finfo->offset;
@@ -2260,9 +2263,16 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                                        NULL, NULL);
                        }
 
-                       bytes_written = camel_stream_write_to_stream (
-                               finfo->body, data->stream, cancellable, error);
-                       if (bytes_written == -1) {
+                       output_stream =
+                               g_io_stream_get_output_stream (data->stream);
+
+                       body_data = g_bytes_get_data (finfo->body, &body_size);
+
+                       success = g_output_stream_write_all (
+                               output_stream, body_data, body_size,
+                               NULL, cancellable, error);
+
+                       if (!success) {
                                g_prefix_error (
                                        error, "%s: ",
                                        _("Error writing to cache stream"));
@@ -2408,7 +2418,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
                        /* Do we want to save these headers for later too?  Do we care? */
 
                        mp = camel_mime_parser_new ();
-                       camel_mime_parser_init_with_stream (mp, finfo->header, NULL);
+                       camel_mime_parser_init_with_bytes (mp, finfo->header);
                        mi = camel_folder_summary_info_new_from_parser (folder->summary, mp);
                        g_object_unref (mp);
 
@@ -5068,14 +5078,7 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
        /* No more messages to fetch, let's wrap things up. */
 
        if (local_error == NULL) {
-               camel_stream_flush (data->stream, cancellable, &local_error);
-               g_prefix_error (
-                       &local_error, "%s: ",
-                       _("Failed to close the tmp stream"));
-       }
-
-       if (local_error == NULL) {
-               camel_stream_close (data->stream, cancellable, &local_error);
+               g_io_stream_close (data->stream, cancellable, &local_error);
                g_prefix_error (
                        &local_error, "%s: ",
                        _("Failed to close the tmp stream"));
@@ -5097,17 +5100,11 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is,
                g_free (dirname);
 
                if (g_rename (tmp_filename, cur_filename) == 0) {
-                       GIOStream *base_stream;
-
                        /* Exchange the "tmp" stream for the "cur" stream. */
                        g_clear_object (&data->stream);
-                       base_stream = camel_data_cache_get (
+                       data->stream = camel_data_cache_get (
                                data->message_cache, "cur",
                                data->uid, &local_error);
-                       if (base_stream != NULL) {
-                               data->stream = camel_stream_new (base_stream);
-                               g_object_unref (base_stream);
-                       }
                } else {
                        g_set_error (
                                &local_error, G_FILE_ERROR,
@@ -8425,7 +8422,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
        CamelStream *stream = NULL;
        CamelIMAPXJob *job;
        CamelMessageInfo *mi;
-       GIOStream *base_stream;
+       GIOStream *cache_stream;
        GetMessageData *data;
        gboolean registered;
 
@@ -8448,11 +8445,11 @@ imapx_server_get_message (CamelIMAPXServer *is,
                /* Disregard errors here.  If we failed to retreive the
                 * message from cache (implying the job we were waiting
                 * on failed or got cancelled), we'll just re-fetch it. */
-               base_stream = camel_data_cache_get (
+               cache_stream = camel_data_cache_get (
                        message_cache, "cur", message_uid, NULL);
-               if (base_stream != NULL) {
-                       stream = camel_stream_new (base_stream);
-                       g_object_unref (base_stream);
+               if (cache_stream != NULL) {
+                       stream = camel_stream_new (cache_stream);
+                       g_object_unref (cache_stream);
                        return stream;
                }
 
@@ -8470,9 +8467,9 @@ imapx_server_get_message (CamelIMAPXServer *is,
                return NULL;
        }
 
-       base_stream = camel_data_cache_add (
+       cache_stream = camel_data_cache_add (
                message_cache, "tmp", message_uid, error);
-       if (base_stream == NULL) {
+       if (cache_stream == NULL) {
                QUEUE_UNLOCK (is);
                return NULL;
        }
@@ -8480,7 +8477,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
        data = g_slice_new0 (GetMessageData);
        data->uid = g_strdup (message_uid);
        data->message_cache = g_object_ref (message_cache);
-       data->stream = camel_stream_new (base_stream);
+       data->stream = g_object_ref (cache_stream);
        data->size = ((CamelMessageInfoBase *) mi)->size;
        if (data->size > MULTI_SIZE)
                data->use_multi_fetch = TRUE;
@@ -8496,7 +8493,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
        camel_imapx_job_set_data (
                job, data, (GDestroyNotify) get_message_data_free);
 
-       g_clear_object (&base_stream);
+       g_clear_object (&cache_stream);
        camel_message_info_unref (mi);
 
        registered = imapx_register_job (is, job, error);
@@ -8504,7 +8501,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
        QUEUE_UNLOCK (is);
 
        if (registered && camel_imapx_job_run (job, is, error))
-               stream = g_object_ref (data->stream);
+               stream = camel_stream_new (data->stream);
 
        camel_imapx_job_unref (job);
 
diff --git a/camel/providers/imapx/camel-imapx-stream.c b/camel/providers/imapx/camel-imapx-stream.c
index fa619d0..a18cc10 100644
--- a/camel/providers/imapx/camel-imapx-stream.c
+++ b/camel/providers/imapx/camel-imapx-stream.c
@@ -529,22 +529,23 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is,
        }
 }
 
-/* parse an nstring as a stream */
+/* parse an nstring as a GBytes */
 gboolean
-camel_imapx_stream_nstring_stream (CamelIMAPXStream *is,
-                                   CamelStream **stream,
-                                   GCancellable *cancellable,
-                                   GError **error)
+camel_imapx_stream_nstring_bytes (CamelIMAPXStream *is,
+                                  GBytes **out_bytes,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
        camel_imapx_token_t tok;
        guchar *token;
        guint len;
        CamelStream *mem = NULL;
+       GByteArray *byte_array;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_STREAM (is), FALSE);
-       g_return_val_if_fail (stream != NULL, FALSE);
+       g_return_val_if_fail (out_bytes != NULL, FALSE);
 
-       *stream = NULL;
+       *out_bytes = NULL;
 
        tok = camel_imapx_stream_token (is, &token, &len, cancellable, error);
 
@@ -553,25 +554,24 @@ camel_imapx_stream_nstring_stream (CamelIMAPXStream *is,
                        return FALSE;
 
                case IMAPX_TOK_STRING:
-                       mem = camel_stream_mem_new_with_buffer (
-                               (gchar *) token, len);
-                       *stream = mem;
+                       *out_bytes = g_bytes_new (token, len);
                        return TRUE;
 
                case IMAPX_TOK_LITERAL:
                        /* If len is big, we could
                         * automatically use a file backing. */
                        camel_imapx_stream_set_literal (is, len);
+                       byte_array = g_byte_array_new ();
                        mem = camel_stream_mem_new ();
+                       camel_stream_mem_set_byte_array (
+                               CAMEL_STREAM_MEM (mem), byte_array);
                        if (camel_stream_write_to_stream ((CamelStream *) is, mem, cancellable, error) == -1) 
{
+                               g_byte_array_unref (byte_array);
                                g_object_unref (mem);
                                return FALSE;
                        }
-
-                       g_seekable_seek (
-                               G_SEEKABLE (mem), 0,
-                               G_SEEK_SET, NULL, NULL);
-                       *stream = mem;
+                       *out_bytes = g_byte_array_free_to_bytes (byte_array);
+                       g_object_unref (mem);
                        return TRUE;
 
                case IMAPX_TOK_TOKEN:
@@ -579,7 +579,7 @@ camel_imapx_stream_nstring_stream (CamelIMAPXStream *is,
                            toupper (token[1]) == 'I' &&
                            toupper (token[2]) == 'L' &&
                            token[3] == 0) {
-                               *stream = NULL;
+                               *out_bytes = NULL;
                                return TRUE;
                        }
                        /* fall through */
diff --git a/camel/providers/imapx/camel-imapx-stream.h b/camel/providers/imapx/camel-imapx-stream.h
index ec3d982..c3365a4 100644
--- a/camel/providers/imapx/camel-imapx-stream.h
+++ b/camel/providers/imapx/camel-imapx-stream.h
@@ -116,10 +116,10 @@ gboolean  camel_imapx_stream_nstring      (CamelIMAPXStream *is,
                                                 guchar **start,
                                                 GCancellable *cancellable,
                                                 GError **error);
-/* gets a NIL or string into a stream, stream==NULL if NIL */
-gboolean       camel_imapx_stream_nstring_stream
+/* gets a NIL or string into a GBytes, bytes==NULL if NIL */
+gboolean       camel_imapx_stream_nstring_bytes
                                                (CamelIMAPXStream *is,
-                                                CamelStream **stream,
+                                                GBytes **out_bytes,
                                                 GCancellable *cancellable,
                                                 GError **error);
 /* gets 'text' */
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index 1807c34..251cce7 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -19,6 +19,8 @@
 #include <errno.h>
 #include <string.h>
 
+#include <gio/gunixoutputstream.h>
+
 #include "camel-imapx-command.h"
 #include "camel-imapx-folder.h"
 #include "camel-imapx-settings.h"
@@ -1414,11 +1416,11 @@ imapx_free_fetch (struct _fetch_info *finfo)
                return;
 
        if (finfo->body)
-               g_object_unref (finfo->body);
+               g_bytes_unref (finfo->body);
        if (finfo->text)
-               g_object_unref (finfo->text);
+               g_bytes_unref (finfo->text);
        if (finfo->header)
-               g_object_unref (finfo->header);
+               g_bytes_unref (finfo->header);
        if (finfo->minfo)
                camel_message_info_unref (finfo->minfo);
        if (finfo->cinfo)
@@ -1434,9 +1436,9 @@ imapx_free_fetch (struct _fetch_info *finfo)
 void
 imapx_dump_fetch (struct _fetch_info *finfo)
 {
-       CamelStream *sout;
-       gchar *string;
-       gint fd;
+       GOutputStream *output_stream;
+       gconstpointer data;
+       gsize size;
 
        d ('?', "Fetch info:\n");
        if (finfo == NULL) {
@@ -1444,68 +1446,60 @@ imapx_dump_fetch (struct _fetch_info *finfo)
                return;
        }
 
-       fd = dup (1);
-       sout = camel_stream_fs_new_with_fd (fd);
-       if (finfo->body) {
-               camel_stream_write_string (sout, "Body content:\n", NULL, NULL);
-               camel_stream_write_to_stream (finfo->body, sout, NULL, NULL);
-               g_seekable_seek (
-                       G_SEEKABLE (finfo->body),
-                       0, G_SEEK_SET, NULL, NULL);
+       output_stream = g_unix_output_stream_new (STDOUT_FILENO, FALSE);
+
+       /* XXX g_output_stream_write_bytes_all() would be awfully
+        *     handy here.  g_output_stream_write_bytes() may not
+        *     write the entire GBytes. */
+
+       if (finfo->body != NULL) {
+               g_print ("Body content:\n");
+               data = g_bytes_get_data (finfo->body, &size);
+               g_output_stream_write_all (
+                       output_stream, data,
+                       size, NULL, NULL, NULL);
        }
-       if (finfo->text) {
-               camel_stream_write_string (sout, "Text content:\n", NULL, NULL);
-               camel_stream_write_to_stream (finfo->text, sout, NULL, NULL);
-               g_seekable_seek (
-                       G_SEEKABLE (finfo->text),
-                       0, G_SEEK_SET, NULL, NULL);
+
+       if (finfo->text != NULL) {
+               g_print ("Text content:\n");
+               data = g_bytes_get_data (finfo->text, &size);
+               g_output_stream_write_all (
+                       output_stream, data,
+                       size, NULL, NULL, NULL);
        }
-       if (finfo->header) {
-               camel_stream_write_string (sout, "Header content:\n", NULL, NULL);
-               camel_stream_write_to_stream (finfo->header, sout, NULL, NULL);
-               g_seekable_seek (
-                       G_SEEKABLE (finfo->header),
-                       0, G_SEEK_SET, NULL, NULL);
+
+       if (finfo->header != NULL) {
+               g_print ("Header content:\n");
+               data = g_bytes_get_data (finfo->header, &size);
+               g_output_stream_write_all (
+                       output_stream, data,
+                       size, NULL, NULL, NULL);
        }
-       if (finfo->minfo) {
-               camel_stream_write_string (sout, "Message Info:\n", NULL, NULL);
+
+       if (finfo->minfo != NULL) {
+               g_print ("Message Info:\n");
                camel_message_info_dump (finfo->minfo);
        }
-       if (finfo->cinfo) {
-               camel_stream_write_string (sout, "Content Info:\n", NULL, NULL);
-               //camel_content_info_dump (finfo->cinfo, 0);
-       }
-       if (finfo->got & FETCH_SIZE) {
-               string = g_strdup_printf ("Size: %d\n", (gint) finfo->size);
-               camel_stream_write_string (sout, string, NULL, NULL);
-               g_free (string);
-       }
-       if (finfo->got & FETCH_BODY) {
-               string = g_strdup_printf ("Offset: %d\n", (gint) finfo->offset);
-               camel_stream_write_string (sout, string, NULL, NULL);
-               g_free (string);
-       }
-       if (finfo->got & FETCH_FLAGS) {
-               string = g_strdup_printf ("Flags: %08x\n", (gint) finfo->flags);
-               camel_stream_write_string (sout, string, NULL, NULL);
-               g_free (string);
-       }
-       if (finfo->date) {
-               string = g_strdup_printf ("Data: '%s'\n", finfo->date);
-               camel_stream_write_string (sout, string, NULL, NULL);
-               g_free (string);
-       }
-       if (finfo->section) {
-               string = g_strdup_printf ("Section: '%s'\n", finfo->section);
-               camel_stream_write_string (sout, string, NULL, NULL);
-               g_free (string);
-       }
-       if (finfo->uid) {
-               string = g_strdup_printf ("UID: '%s'\n", finfo->uid);
-               camel_stream_write_string (sout, string, NULL, NULL);
-               g_free (string);
-       }
-       g_object_unref (sout);
+
+       if (finfo->got & FETCH_SIZE)
+               g_print ("Size: %d\n", (gint) finfo->size);
+
+       if (finfo->got & FETCH_BODY)
+               g_print ("Offset: %d\n", (gint) finfo->offset);
+
+       if (finfo->got & FETCH_FLAGS)
+               g_print ("Flags: %08x\n", (gint) finfo->flags);
+
+       if (finfo->date != NULL)
+               g_print ("Date: '%s'\n", finfo->date);
+
+       if (finfo->section != NULL)
+               g_print ("Section: '%s'\n", finfo->section);
+
+       if (finfo->uid != NULL)
+               g_print ("UID: '%s'\n", finfo->uid);
+
+       g_object_unref (output_stream);
 }
 
 static gboolean
@@ -1557,7 +1551,7 @@ imapx_parse_fetch_body (CamelIMAPXStream *is,
                        camel_imapx_stream_ungettoken (is, tok, token, len);
                }
 
-               success = camel_imapx_stream_nstring_stream (
+               success = camel_imapx_stream_nstring_bytes (
                        is, &finfo->body, cancellable, error);
 
                /* Sanity check. */
@@ -1663,7 +1657,7 @@ imapx_parse_fetch_rfc822_header (CamelIMAPXStream *is,
 {
        gboolean success;
 
-       success = camel_imapx_stream_nstring_stream (
+       success = camel_imapx_stream_nstring_bytes (
                is, &finfo->header, cancellable, error);
 
        /* Sanity check. */
@@ -1702,7 +1696,7 @@ imapx_parse_fetch_rfc822_text (CamelIMAPXStream *is,
 {
        gboolean success;
 
-       success = camel_imapx_stream_nstring_stream (
+       success = camel_imapx_stream_nstring_bytes (
                is, &finfo->text, cancellable, error);
 
        /* Sanity check. */
diff --git a/camel/providers/imapx/camel-imapx-utils.h b/camel/providers/imapx/camel-imapx-utils.h
index 92032ad..c26bcc5 100644
--- a/camel/providers/imapx/camel-imapx-utils.h
+++ b/camel/providers/imapx/camel-imapx-utils.h
@@ -235,9 +235,9 @@ void                imapx_free_body                 (struct _CamelMessageContentInfo 
*cinfo);
 /* this assumes the caller/server doesn't send any one of these types twice */
 struct _fetch_info {
        guint32 got;            /* what we got, see below */
-       CamelStream *body;      /* BODY[.*](<.*>)? */
-       CamelStream *text;      /* RFC822.TEXT */
-       CamelStream *header;    /* RFC822.HEADER */
+       GBytes *body;           /* BODY[.*](<.*>)? */
+       GBytes *text;           /* RFC822.TEXT */
+       GBytes *header;         /* RFC822.HEADER */
        CamelMessageInfo *minfo;        /* ENVELOPE */
        CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */
        guint32 size;           /* RFC822.SIZE */
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index f5907ae..012c9c5 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -3769,7 +3769,7 @@ camel_imapx_stream_getl
 camel_imapx_stream_atom
 camel_imapx_stream_astring
 camel_imapx_stream_nstring
-camel_imapx_stream_nstring_stream
+camel_imapx_stream_nstring_bytes
 camel_imapx_stream_text
 camel_imapx_stream_number
 camel_imapx_stream_skip


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