[evince/wip/bug654832: 10/16] libdocument: Add API to load/save EvDocument from GIO streams



commit 4fdd9db11ee0ce59bd45b8ea2e646a1e95e1b424
Author: Christian Persch <chpe gnome org>
Date:   Wed May 9 19:22:47 2012 +0200

    libdocument: Add API to load/save EvDocument from GIO streams
    
    Part of bug #654832.

 .../libdocument/libevdocument-sections.txt         |    2 +
 libdocument/ev-document.c                          |  249 +++++++++++++-------
 libdocument/ev-document.h                          |   30 +++
 3 files changed, 201 insertions(+), 80 deletions(-)
---
diff --git a/help/reference/libdocument/libevdocument-sections.txt b/help/reference/libdocument/libevdocument-sections.txt
index 8059ae3..a2457de 100644
--- a/help/reference/libdocument/libevdocument-sections.txt
+++ b/help/reference/libdocument/libevdocument-sections.txt
@@ -343,7 +343,9 @@ ev_document_fc_mutex_trylock
 ev_document_get_info
 ev_document_get_backend_info
 ev_document_load
+ev_document_load_stream_sync
 ev_document_save
+ev_document_write_stream_sync
 ev_document_get_n_pages
 ev_document_get_page
 ev_document_get_page_size
diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c
index a75862c..419b8cb 100644
--- a/libdocument/ev-document.c
+++ b/libdocument/ev-document.c
@@ -208,6 +208,79 @@ ev_document_fc_mutex_trylock (void)
 	return g_mutex_trylock (p_ev_fc_mutex);
 }
 
+static void
+ev_document_setup_cache (EvDocument *document)
+{
+        EvDocumentPrivate *priv = document->priv;
+        gint i;
+
+        /* Cache some info about the document to avoid
+          * going to the backends since it requires locks
+          */
+        priv->n_pages = _ev_document_get_n_pages (document);
+
+        for (i = 0; i < priv->n_pages; i++) {
+                EvPage     *page = ev_document_get_page (document, i);
+                gdouble     page_width = 0;
+                gdouble     page_height = 0;
+                EvPageSize *page_size;
+                gchar      *page_label;
+
+                _ev_document_get_page_size (document, page, &page_width, &page_height);
+
+                if (i == 0) {
+                        priv->uniform_width = page_width;
+                        priv->uniform_height = page_height;
+                        priv->max_width = priv->uniform_width;
+                        priv->max_height = priv->uniform_height;
+                        priv->min_width = priv->uniform_width;
+                        priv->min_height = priv->uniform_height;
+                } else if (priv->uniform &&
+                            (priv->uniform_width != page_width ||
+                            priv->uniform_height != page_height)) {
+                        /* It's a different page size.  Backfill the array. */
+                        int j;
+
+                        priv->page_sizes = g_new0 (EvPageSize, priv->n_pages);
+
+                        for (j = 0; j < i; j++) {
+                                page_size = &(priv->page_sizes[j]);
+                                page_size->width = priv->uniform_width;
+                                page_size->height = priv->uniform_height;
+                        }
+                        priv->uniform = FALSE;
+                }
+                if (!priv->uniform) {
+                        page_size = &(priv->page_sizes[i]);
+
+                        page_size->width = page_width;
+                        page_size->height = page_height;
+
+                        if (page_width > priv->max_width)
+                                priv->max_width = page_width;
+                        if (page_width < priv->min_width)
+                                priv->min_width = page_width;
+
+                        if (page_height > priv->max_height)
+                                priv->max_height = page_height;
+                        if (page_height < priv->min_height)
+                                priv->min_height = page_height;
+                }
+
+                page_label = _ev_document_get_page_label (document, page);
+                if (page_label) {
+                        if (!priv->page_labels)
+                                priv->page_labels = g_new0 (gchar *, priv->n_pages);
+
+                        priv->page_labels[i] = page_label;
+                        priv->max_label = MAX (priv->max_label,
+                                                g_utf8_strlen (page_label, 256));
+                }
+
+                g_object_unref (page);
+        }
+}
+
 /**
  * ev_document_load:
  * @document: a #EvDocument
@@ -249,90 +322,68 @@ ev_document_load (EvDocument  *document,
 					     "Internal error in backend");
 		}
 	} else {
-		gint i;
-		EvDocumentPrivate *priv = document->priv;
-
-		/* Cache some info about the document to avoid
-		 * going to the backends since it requires locks
-		 */
-		priv->uri = g_strdup (uri);
-		priv->n_pages = _ev_document_get_n_pages (document);
-
-		for (i = 0; i < priv->n_pages; i++) {
-			EvPage     *page = ev_document_get_page (document, i);
-			gdouble     page_width = 0;
-			gdouble     page_height = 0;
-			EvPageSize *page_size;
-			gchar      *page_label;
-
-			_ev_document_get_page_size (document, page, &page_width, &page_height);
-
-			if (i == 0) {
-				priv->uniform_width = page_width;
-				priv->uniform_height = page_height;
-				priv->max_width = priv->uniform_width;
-				priv->max_height = priv->uniform_height;
-				priv->min_width = priv->uniform_width;
-				priv->min_height = priv->uniform_height;
-			} else if (priv->uniform &&
-				   (priv->uniform_width != page_width ||
-				    priv->uniform_height != page_height)) {
-				/* It's a different page size.  Backfill the array. */
-				int j;
-
-				priv->page_sizes = g_new0 (EvPageSize, priv->n_pages);
-
-				for (j = 0; j < i; j++) {
-					page_size = &(priv->page_sizes[j]);
-					page_size->width = priv->uniform_width;
-					page_size->height = priv->uniform_height;
-				}
-				priv->uniform = FALSE;
-			}
-			if (!priv->uniform) {
-				page_size = &(priv->page_sizes[i]);
+                EvDocumentPrivate *priv = document->priv;
 
-				page_size->width = page_width;
-				page_size->height = page_height;
+                ev_document_setup_cache (document);
 
-				if (page_width > priv->max_width)
-					priv->max_width = page_width;
-				if (page_width < priv->min_width)
-					priv->min_width = page_width;
+                priv->uri = g_strdup (uri);
+                priv->info = _ev_document_get_info (document);
+                if (_ev_document_support_synctex (document)) {
+                        gchar *filename;
 
-				if (page_height > priv->max_height)
-					priv->max_height = page_height;
-				if (page_height < priv->min_height)
-					priv->min_height = page_height;
-			}
-
-			page_label = _ev_document_get_page_label (document, page);
-			if (page_label) {
-				if (!priv->page_labels)
-					priv->page_labels = g_new0 (gchar *, priv->n_pages);
+                        filename = g_filename_from_uri (uri, NULL, NULL);
+                        if (filename != NULL) {
+                                priv->synctex_scanner =
+                                        synctex_scanner_new_with_output_file (filename, NULL, 1);
+                                g_free (filename);
+                        }
+                }
+        }
 
-				priv->page_labels[i] = page_label;
-				priv->max_label = MAX (priv->max_label,
-						       g_utf8_strlen (page_label, 256));
-			}
+	return retval;
+}
 
-			g_object_unref (page);
-		}
+/**
+ * ev_document_load_stream_sync:
+ * @document: a #EvDocument
+ * @stream: a #GInputStream
+ * @flags: flags from #EvDocumentLoadFlags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError location to store an error, or %NULL
+ *
+ * Loads the document from @stream. See ev_document_load() for more information.
+ *
+ * Returns: %TRUE if loading succeeded, or %FALSE on error with @error filled in
+ *
+ * Since: 3.6
+ */
+gboolean
+ev_document_load_stream_sync (EvDocument         *document,
+                              GInputStream       *stream,
+                              EvDocumentLoadFlags flags,
+                              GCancellable       *cancellable,
+                              GError            **error)
+{
+        EvDocumentClass *klass;
+
+        g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+        g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
+        g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+        klass = EV_DOCUMENT_GET_CLASS (document);
+        if (!klass->load_stream_sync) {
+                g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                                     "Backend does not support loading from stream");
+                return FALSE;
+        }
 
-		priv->info = _ev_document_get_info (document);
-		if (_ev_document_support_synctex (document)) {
-			gchar *filename;
+        if (!klass->load_stream_sync (document, stream, flags, cancellable, error))
+                return FALSE;
 
-			filename = g_filename_from_uri (uri, NULL, NULL);
-			if (filename != NULL) {
-				priv->synctex_scanner =
-					synctex_scanner_new_with_output_file (filename, NULL, 1);
-				g_free (filename);
-			}
-		}
-	}
+        ev_document_setup_cache (document);
 
-	return retval;
+        return TRUE;
 }
 
 /**
@@ -355,6 +406,44 @@ ev_document_save (EvDocument  *document,
 	return klass->save (document, uri, error);
 }
 
+/**
+ * ev_document_write_stream_sync:
+ * @document: a #EvDocument
+ * @stream: a #GOutputStream
+ * @flags: flags from #EvDocumentWriteFlags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError location to store an error, or %NULL
+ *
+ * Writes the document to @stream. See ev_document_save() for more information.
+ *
+ * Returns: %TRUE if saving succeeded, or %FALSE on error with @error filled in
+ *
+ * Since: 3.6
+ */
+gboolean
+ev_document_write_stream_sync (EvDocument          *document,
+                               GOutputStream       *stream,
+                               EvDocumentWriteFlags flags,
+                               GCancellable        *cancellable,
+                               GError             **error)
+{
+        EvDocumentClass *klass;
+
+        g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+        g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
+        g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+        klass = EV_DOCUMENT_GET_CLASS (document);
+        if (!klass->write_stream_sync) {
+                g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                                     "Backend does not support saving to stream");
+                return FALSE;
+        }
+
+        return klass->write_stream_sync (document, stream, flags, cancellable, error);
+}
+
 EvPage *
 ev_document_get_page (EvDocument *document,
 		      gint        index)
diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h
index e1e01c0..4abb7b6 100644
--- a/libdocument/ev-document.h
+++ b/libdocument/ev-document.h
@@ -53,6 +53,14 @@ typedef struct _EvDocumentPrivate EvDocumentPrivate;
 #define EV_DOC_MUTEX_LOCK (ev_document_doc_mutex_lock ())
 #define EV_DOC_MUTEX_UNLOCK (ev_document_doc_mutex_unlock ())
 
+typedef enum /*< flags >*/ {
+        EV_DOCUMENT_LOAD_FLAG_NONE = 0
+} EvDocumentLoadFlags;
+
+typedef enum /*< flags >*/ {
+        EV_DOCUMENT_WRITE_FLAG_NONE = 0
+} EvDocumentWriteFlags;
+
 typedef enum
 {
         EV_DOCUMENT_ERROR_INVALID,
@@ -110,6 +118,18 @@ struct _EvDocumentClass
         gboolean          (* get_backend_info)(EvDocument      *document,
                                                EvDocumentBackendInfo *info);
         gboolean	  (* support_synctex) (EvDocument      *document);
+
+        /* GIO streams */
+        gboolean          (* load_stream_sync)  (EvDocument          *document,
+                                                 GInputStream        *stream,
+                                                 EvDocumentLoadFlags  flags,
+                                                 GCancellable        *cancellable,
+                                                 GError             **error);
+        gboolean          (* write_stream_sync) (EvDocument          *document,
+                                                 GOutputStream       *stream,
+                                                 EvDocumentWriteFlags flags,
+                                                 GCancellable        *cancellable,
+                                                 GError             **error);
 };
 
 GType            ev_document_get_type             (void) G_GNUC_CONST;
@@ -133,9 +153,19 @@ gboolean         ev_document_get_backend_info     (EvDocument      *document,
 gboolean         ev_document_load                 (EvDocument      *document,
 						   const char      *uri,
 						   GError         **error);
+gboolean         ev_document_load_stream_sync     (EvDocument         *document,
+                                                   GInputStream       *stream,
+                                                   EvDocumentLoadFlags flags,
+                                                   GCancellable       *cancellable,
+                                                   GError            **error);
 gboolean         ev_document_save                 (EvDocument      *document,
 						   const char      *uri,
 						   GError         **error);
+gboolean         ev_document_write_stream_sync    (EvDocument          *document,
+                                                   GOutputStream       *stream,
+                                                   EvDocumentWriteFlags flags,
+                                                   GCancellable        *cancellable,
+                                                   GError             **error);
 gint             ev_document_get_n_pages          (EvDocument      *document);
 EvPage          *ev_document_get_page             (EvDocument      *document,
 						   gint             index);



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