[evolution-data-server] Add CamelIMAPXLogger.



commit fe77b4a478b68d3be41e7ee1b3b122959f0fed2e
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Feb 4 12:38:04 2014 -0500

    Add CamelIMAPXLogger.
    
    This is a GConverter that just echos data to standard output if the I/O
    debugging setting is enabled ('CAMEL_DEBUG=imapx:io').  Attaches to the
    GInputStream and GOutputStream.

 camel/providers/imapx/Makefile.am          |    2 +
 camel/providers/imapx/camel-imapx-logger.c |  217 ++++++++++++++++++++++++++++
 camel/providers/imapx/camel-imapx-logger.h |   72 +++++++++
 camel/providers/imapx/camel-imapx-server.c |   80 +++++++----
 docs/reference/camel/camel-docs.sgml       |    1 +
 docs/reference/camel/camel-sections.txt    |   19 +++
 docs/reference/camel/camel.types           |    2 +
 7 files changed, 367 insertions(+), 26 deletions(-)
---
diff --git a/camel/providers/imapx/Makefile.am b/camel/providers/imapx/Makefile.am
index c4a6ab9..7bdfcab 100644
--- a/camel/providers/imapx/Makefile.am
+++ b/camel/providers/imapx/Makefile.am
@@ -27,6 +27,8 @@ libcamelimapx_la_SOURCES = \
        camel-imapx-job.h \
        camel-imapx-list-response.c \
        camel-imapx-list-response.h \
+       camel-imapx-logger.c \
+       camel-imapx-logger.h \
        camel-imapx-mailbox.c \
        camel-imapx-mailbox.h \
        camel-imapx-namespace.c \
diff --git a/camel/providers/imapx/camel-imapx-logger.c b/camel/providers/imapx/camel-imapx-logger.c
new file mode 100644
index 0000000..e317c52
--- /dev/null
+++ b/camel/providers/imapx/camel-imapx-logger.c
@@ -0,0 +1,217 @@
+/*
+ * camel-imapx-logger.c
+ *
+ * This library is free software you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * SECTION: camel-imapx-logger
+ * @include: camel-imapx-logger.h
+ * @short_description: Log input/output streams
+ *
+ * #CamelIMAPXLogger is a simple #GConverter that just echos data to standard
+ * output if the I/O debugging setting is enabled ('CAMEL_DEBUG=imapx:io').
+ * Attaches to the #GInputStream and #GOutputStream.
+ **/
+
+#include "camel-imapx-logger.h"
+
+#include <string.h>
+
+#include "camel-imapx-utils.h"
+
+#define CAMEL_IMAPX_LOGGER_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), CAMEL_TYPE_IMAPX_LOGGER, CamelIMAPXLoggerPrivate))
+
+struct _CamelIMAPXLoggerPrivate {
+       gchar prefix;
+};
+
+enum {
+       PROP_0,
+       PROP_PREFIX
+};
+
+/* Forward Declarations */
+static void    camel_imapx_logger_interface_init
+                                               (GConverterIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+       CamelIMAPXLogger,
+       camel_imapx_logger,
+       G_TYPE_OBJECT,
+       G_IMPLEMENT_INTERFACE (
+               G_TYPE_CONVERTER,
+               camel_imapx_logger_interface_init))
+
+static void
+imapx_logger_set_prefix (CamelIMAPXLogger *logger,
+                         gchar prefix)
+{
+       logger->priv->prefix = prefix;
+}
+
+static void
+imapx_logger_set_property (GObject *object,
+                           guint property_id,
+                           const GValue *value,
+                           GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_PREFIX:
+                       imapx_logger_set_prefix (
+                               CAMEL_IMAPX_LOGGER (object),
+                               g_value_get_schar (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+imapx_logger_get_property (GObject *object,
+                           guint property_id,
+                           GValue *value,
+                           GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_PREFIX:
+                       g_value_set_schar (
+                               value,
+                               camel_imapx_logger_get_prefix (
+                               CAMEL_IMAPX_LOGGER (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static GConverterResult
+imapx_logger_convert (GConverter *converter,
+                      gconstpointer inbuf,
+                      gsize inbuf_size,
+                      gpointer outbuf,
+                      gsize outbuf_size,
+                      GConverterFlags flags,
+                      gsize *bytes_read,
+                      gsize *bytes_written,
+                      GError **error)
+{
+       CamelIMAPXLoggerPrivate *priv;
+       GConverterResult result;
+       gsize min_size;
+
+       priv = CAMEL_IMAPX_LOGGER_GET_PRIVATE (converter);
+
+       min_size = MIN (inbuf_size, outbuf_size);
+
+       memcpy (outbuf, inbuf, min_size);
+       *bytes_read = *bytes_written = min_size;
+
+       camel_imapx_debug (
+               io, priv->prefix, "I/O: '%.*s'\n",
+               (gint) min_size, (gchar *) outbuf);
+
+       if ((flags & G_CONVERTER_INPUT_AT_END) != 0)
+               result = G_CONVERTER_FINISHED;
+       else if ((flags & G_CONVERTER_FLUSH) != 0)
+               result = G_CONVERTER_FLUSHED;
+       else
+               result = G_CONVERTER_CONVERTED;
+
+       return result;
+}
+
+static void
+imapx_logger_reset (GConverter *converter)
+{
+       /* Nothing to do. */
+}
+
+static void
+camel_imapx_logger_class_init (CamelIMAPXLoggerClass *class)
+{
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (CamelIMAPXLoggerPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = imapx_logger_set_property;
+       object_class->get_property = imapx_logger_get_property;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_PREFIX,
+               g_param_spec_char (
+                       "prefix",
+                       "Prefix",
+                       "Output prefix to distinguish connections",
+                       0x20, 0x7F, '*',
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
+}
+
+static void
+camel_imapx_logger_interface_init (GConverterIface *interface)
+{
+       interface->convert = imapx_logger_convert;
+       interface->reset = imapx_logger_reset;
+}
+
+static void
+camel_imapx_logger_init (CamelIMAPXLogger *logger)
+{
+       logger->priv = CAMEL_IMAPX_LOGGER_GET_PRIVATE (logger);
+}
+
+/**
+ * camel_imapx_logger_new:
+ * @prefix: a prefix character
+ *
+ * Creates a new #CamelIMAPXLogger.  Each output line generated by the
+ * logger will have a prefix string that includes the @prefix character
+ * to distinguish it from other active loggers.
+ *
+ * Returns: a #CamelIMAPXLogger
+ *
+ * Since: 3.12
+ **/
+GConverter *
+camel_imapx_logger_new (gchar prefix)
+{
+       return g_object_new (
+               CAMEL_TYPE_IMAPX_LOGGER,
+               "prefix", prefix, NULL);
+}
+
+/**
+ * camel_imapx_logger_get_prefix:
+ * @logger: a #CamelIMAPXLogger
+ *
+ * Returns the prefix character passed to camel_imapx_logger_new().
+ *
+ * Returns: the prefix character
+ *
+ * Since: 3.12
+ **/
+gchar
+camel_imapx_logger_get_prefix (CamelIMAPXLogger *logger)
+{
+       g_return_val_if_fail (CAMEL_IS_IMAPX_LOGGER (logger), NULL);
+
+       return logger->priv->prefix;
+}
+
diff --git a/camel/providers/imapx/camel-imapx-logger.h b/camel/providers/imapx/camel-imapx-logger.h
new file mode 100644
index 0000000..d92d1c9
--- /dev/null
+++ b/camel/providers/imapx/camel-imapx-logger.h
@@ -0,0 +1,72 @@
+/*
+ * camel-imapx-logger.h
+ *
+ * This library is free software you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef CAMEL_IMAPX_LOGGER_H
+#define CAMEL_IMAPX_LOGGER_H
+
+#include <gio/gio.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_IMAPX_LOGGER \
+       (camel_imapx_logger_get_type ())
+#define CAMEL_IMAPX_LOGGER(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), CAMEL_TYPE_IMAPX_LOGGER, CamelIMAPXLogger))
+#define CAMEL_IMAPX_LOGGER_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), CAMEL_TYPE_IMAPX_LOGGER, CamelIMAPXLoggerClass))
+#define CAMEL_IS_IMAPX_LOGGER(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), CAMEL_TYPE_IMAPX_LOGGER))
+#define CAMEL_IS_IMAPX_LOGGER_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), CAMEL_TYPE_IMAPX_LOGGER))
+#define CAMEL_IMAPX_LOGGER_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), CAMEL_TYPE_IMAPX_LOGGER, CamelIMAPXLoggerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelIMAPXLogger CamelIMAPXLogger;
+typedef struct _CamelIMAPXLoggerClass CamelIMAPXLoggerClass;
+typedef struct _CamelIMAPXLoggerPrivate CamelIMAPXLoggerPrivate;
+
+/**
+ * CamelIMAPXLogger:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ *
+ * Since: 3.12
+ **/
+struct _CamelIMAPXLogger {
+       GObject parent;
+       CamelIMAPXLoggerPrivate *priv;
+};
+
+struct _CamelIMAPXLoggerClass {
+       GObjectClass parent_class;
+};
+
+GType          camel_imapx_logger_get_type     (void) G_GNUC_CONST;
+GConverter *   camel_imapx_logger_new          (gchar prefix);
+gchar          camel_imapx_logger_get_prefix   (CamelIMAPXLogger *logger);
+
+G_END_DECLS
+
+#endif /* CAMEL_IMAPX_LOGGER_H */
+
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index c548950..275542a 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -41,6 +41,7 @@
 #include "camel-imapx-command.h"
 #include "camel-imapx-folder.h"
 #include "camel-imapx-job.h"
+#include "camel-imapx-logger.h"
 #include "camel-imapx-settings.h"
 #include "camel-imapx-store.h"
 #include "camel-imapx-stream.h"
@@ -4218,6 +4219,54 @@ imapx_maybe_select (CamelIMAPXServer *is,
        camel_imapx_command_unref (ic);
 }
 
+static void
+imapx_server_set_streams (CamelIMAPXServer *is,
+                          GInputStream *input_stream,
+                          GOutputStream *output_stream)
+{
+       GConverter *logger;
+
+       /* Wrapper the streams for debugging output. */
+
+       if (input_stream != NULL) {
+               logger = camel_imapx_logger_new (is->tagprefix);
+               input_stream = g_converter_input_stream_new (
+                       input_stream, logger);
+               g_clear_object (&logger);
+       }
+
+       if (output_stream != NULL) {
+               logger = camel_imapx_logger_new (is->tagprefix);
+               output_stream = g_converter_output_stream_new (
+                       output_stream, logger);
+               g_clear_object (&logger);
+       }
+
+       g_mutex_lock (&is->priv->stream_lock);
+
+       /* Don't close the base streams so STARTTLS works correctly. */
+
+       if (G_IS_FILTER_INPUT_STREAM (is->priv->input_stream)) {
+               g_filter_input_stream_set_close_base_stream (
+                       G_FILTER_INPUT_STREAM (is->priv->input_stream),
+                       FALSE);
+       }
+
+       if (G_IS_FILTER_OUTPUT_STREAM (is->priv->output_stream)) {
+               g_filter_output_stream_set_close_base_stream (
+                       G_FILTER_OUTPUT_STREAM (is->priv->output_stream),
+                       FALSE);
+       }
+
+       g_clear_object (&is->priv->input_stream);
+       is->priv->input_stream = input_stream;
+
+       g_clear_object (&is->priv->output_stream);
+       is->priv->output_stream = output_stream;
+
+       g_mutex_unlock (&is->priv->stream_lock);
+}
+
 static gboolean
 connect_to_server_process (CamelIMAPXServer *is,
                            const gchar *cmd,
@@ -4356,20 +4405,14 @@ connect_to_server_process (CamelIMAPXServer *is,
                GOutputStream *output_stream;
 
                g_mutex_lock (&is->priv->stream_lock);
-
                g_warn_if_fail (is->priv->subprocess == NULL);
-               g_warn_if_fail (is->priv->input_stream == NULL);
-               g_warn_if_fail (is->priv->output_stream == NULL);
-
                is->priv->subprocess = g_object_ref (subprocess);
+               g_mutex_unlock (&is->priv->stream_lock);
 
                input_stream = g_subprocess_get_stdout_pipe (subprocess);
-               is->priv->input_stream = g_object_ref (input_stream);
-
                output_stream = g_subprocess_get_stdin_pipe (subprocess);
-               is->priv->output_stream = g_object_ref (output_stream);
 
-               g_mutex_unlock (&is->priv->stream_lock);
+               imapx_server_set_streams (is, input_stream, output_stream);
 
                g_object_unref (subprocess);
        }
@@ -4446,18 +4489,10 @@ imapx_connect_to_server (CamelIMAPXServer *is,
                GInputStream *input_stream;
                GOutputStream *output_stream;
 
-               g_mutex_lock (&is->priv->stream_lock);
-
-               g_warn_if_fail (is->priv->input_stream == NULL);
-               g_warn_if_fail (is->priv->output_stream == NULL);
-
                input_stream = g_io_stream_get_input_stream (base_stream);
-               is->priv->input_stream = g_object_ref (input_stream);
-
                output_stream = g_io_stream_get_output_stream (base_stream);
-               is->priv->output_stream = g_object_ref (output_stream);
 
-               g_mutex_unlock (&is->priv->stream_lock);
+               imapx_server_set_streams (is, input_stream, output_stream);
 
                stream = camel_stream_new (base_stream);
                g_object_unref (base_stream);
@@ -4607,20 +4642,13 @@ imapx_connect_to_server (CamelIMAPXServer *is,
                        GInputStream *input_stream;
                        GOutputStream *output_stream;
 
-                       g_mutex_lock (&is->priv->stream_lock);
-
-                       g_clear_object (&is->priv->input_stream);
-                       g_clear_object (&is->priv->output_stream);
-
                        input_stream =
                                g_io_stream_get_input_stream (tls_stream);
-                       is->priv->input_stream = g_object_ref (input_stream);
-
                        output_stream =
                                g_io_stream_get_output_stream (tls_stream);
-                       is->priv->output_stream = g_object_ref (output_stream);
 
-                       g_mutex_unlock (&is->priv->stream_lock);
+                       imapx_server_set_streams (
+                               is, input_stream, output_stream);
 
                        camel_stream_set_base_stream (stream, tls_stream);
                        g_object_unref (tls_stream);
diff --git a/docs/reference/camel/camel-docs.sgml b/docs/reference/camel/camel-docs.sgml
index 080442a..7079437 100644
--- a/docs/reference/camel/camel-docs.sgml
+++ b/docs/reference/camel/camel-docs.sgml
@@ -224,6 +224,7 @@
       <xi:include href="xml/camel-imapx-command.xml"/>
       <xi:include href="xml/camel-imapx-folder.xml"/>
       <xi:include href="xml/camel-imapx-job.xml"/>
+      <xi:include href="xml/camel-imapx-logger.xml"/>
       <xi:include href="xml/camel-imapx-mailbox.xml"/>
       <xi:include href="xml/camel-imapx-namespace.xml"/>
       <xi:include href="xml/camel-imapx-namespace-response.xml"/>
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index 7e665e1..f5907ae 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -3448,6 +3448,25 @@ CamelIMAPXListResponsePrivate
 </SECTION>
 
 <SECTION>
+<FILE>camel-imapx-logger</FILE>
+<TITLE>CamelIMAPXLogger</TITLE>
+CamelIMAPXLogger
+camel_imapx_logger_new
+camel_imapx_logger_get_prefix
+<SUBSECTION Standard>
+CAMEL_IMAPX_LOGGER
+CAMEL_IS_IMAPX_LOGGER
+CAMEL_TYPE_IMAPX_LOGGER
+CAMEL_IMAPX_LOGGER_CLASS
+CAMEL_IS_IMAPX_LOGGER_CLASS
+CAMEL_IMAPX_LOGGER_GET_CLASS
+CamelIMAPXLoggerClass
+camel_imapx_logger_get_type
+<SUBSECTION Private>
+CamelIMAPXLoggerPrivate
+</SECTION>
+
+<SECTION>
 <FILE>camel-imapx-mailbox</FILE>
 <TITLE>CamelIMAPXMailbox</TITLE>
 CamelIMAPXMailbox
diff --git a/docs/reference/camel/camel.types b/docs/reference/camel/camel.types
index 96afd67..7c9dd93 100644
--- a/docs/reference/camel/camel.types
+++ b/docs/reference/camel/camel.types
@@ -20,6 +20,7 @@
 
 #include <imapx/camel-imapx-folder.h>
 #include <imapx/camel-imapx-list-response.h>
+#include <imapx/camel-imapx-logger.h>
 #include <imapx/camel-imapx-mailbox.h>
 #include <imapx/camel-imapx-namespace.h>
 #include <imapx/camel-imapx-namespace-response.h>
@@ -164,6 +165,7 @@ camel_spool_summary_get_type
 
 camel_imapx_folder_get_type
 camel_imapx_list_response_get_type
+camel_imapx_logger_get_type
 camel_imapx_mailbox_get_type
 camel_imapx_namespace_get_type
 camel_imapx_namespace_response_get_type


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