[librsvg] Add GIO convenience to librsvg



commit 3d28e419d726d972b178325c25b4f8d17aca17c1
Author: Christian Persch <chpe gnome org>
Date:   Tue Jun 15 21:11:39 2010 +0200

    Add GIO convenience to librsvg
    
    Adds rsvg_handle_read_stream_sync() to read the handle's data from a
    GInputStream, and rsvg_handle_new_from_{gfile,stream}_sync convenience
    functions analogous to rsvg_handle_new_from_{file,data}.
    
    Bug #621699.

 Makefile.am               |    4 +-
 doc/rsvg-sections.txt     |   10 ++-
 doc/tmpl/rsvg-unused.sgml |   42 +++++++++
 doc/tmpl/rsvg.sgml        |   53 +++++++++++
 librsvg.def               |    5 +
 librsvg.pc.in             |    4 +-
 rsvg-base.c               |  212 +++++++++++++++++++++++++++++++++++++++++++++
 rsvg-gobject.c            |    5 +
 rsvg-private.h            |    1 +
 rsvg.h                    |   28 ++++++
 10 files changed, 358 insertions(+), 6 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ce74c72..578ffae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -62,7 +62,9 @@ librsvg_ RSVG_API_MAJOR_VERSION@_la_SOURCES = 		\
 	rsvg-cairo-clip.c	\
 	rsvg.c			\
 	rsvg-gobject.c		\
-	rsvg-file-util.c
+	rsvg-file-util.c	\
+	rsvg-xml.c		\
+	rsvg-xml.h
 
 librsvg_ RSVG_API_MAJOR_VERSION@_la_LDFLAGS = -version-info @RSVG_LT_VERSION_INFO@ -export-dynamic -no-undefined -export-symbols $(srcdir)/librsvg.def
 librsvg_ RSVG_API_MAJOR_VERSION@_la_LIBADD = $(LIBGSF_LIBS) $(LIBCROCO_LIBS) $(LIBRSVG_LIBS) -lm
diff --git a/doc/rsvg-sections.txt b/doc/rsvg-sections.txt
index 6cdd07d..1b29b01 100644
--- a/doc/rsvg-sections.txt
+++ b/doc/rsvg-sections.txt
@@ -27,6 +27,13 @@ rsvg_handle_get_dimensions
 rsvg_handle_get_dimensions_sub
 rsvg_handle_get_position_sub
 rsvg_handle_has_sub
+
+<SUBSECTION>
+RsvgHandleFlags
+rsvg_handle_set_base_gfile
+rsvg_handle_read_stream_sync
+rsvg_handle_new_from_gfile_sync
+rsvg_handle_new_from_stream_sync
 </SECTION>
 
 <SECTION>
@@ -35,7 +42,6 @@ rsvg_handle_has_sub
 rsvg_handle_render_cairo
 rsvg_handle_render_cairo_sub
 </SECTION>
-
 <SECTION>
 <FILE>rsvg-file-util</FILE>
 <TITLE>GdkPixbuf</TITLE>
@@ -47,5 +53,3 @@ rsvg_pixbuf_from_file_at_size
 rsvg_pixbuf_from_file_at_max_size
 rsvg_pixbuf_from_file_at_zoom_with_max
 </SECTION>
-
-
diff --git a/doc/tmpl/rsvg-unused.sgml b/doc/tmpl/rsvg-unused.sgml
index d744ec0..68e92b3 100644
--- a/doc/tmpl/rsvg-unused.sgml
+++ b/doc/tmpl/rsvg-unused.sgml
@@ -39,6 +39,29 @@ Creating a SVGZ reader
 @handle: 
 @id: 
 
+<!-- ##### FUNCTION rsvg_handle_new_from_gfile ##### -->
+<para>
+
+</para>
+
+ file: 
+ flags: 
+ cancellable: 
+ error: 
+ Returns: 
+
+<!-- ##### FUNCTION rsvg_handle_new_from_stream ##### -->
+<para>
+
+</para>
+
+ input_stream: 
+ base_file: 
+ flags: 
+ cancellable: 
+ error: 
+ Returns: 
+
 <!-- ##### FUNCTION rsvg_handle_new_gz ##### -->
 <para>
 
@@ -46,6 +69,25 @@ Creating a SVGZ reader
 
 @Returns: 
 
+<!-- ##### FUNCTION rsvg_handle_read_stream ##### -->
+<para>
+
+</para>
+
+ handle: 
+ stream: 
+ cancellable: 
+ error: 
+ Returns: 
+
+<!-- ##### FUNCTION rsvg_handle_set_base_uri_from_gfile ##### -->
+<para>
+
+</para>
+
+ handle: 
+ file: 
+
 <!-- ##### FUNCTION rsvg_pixbuf_from_file_at_max_size_ex ##### -->
 <para>
 
diff --git a/doc/tmpl/rsvg.sgml b/doc/tmpl/rsvg.sgml
index cdec9d5..d1c54e0 100644
--- a/doc/tmpl/rsvg.sgml
+++ b/doc/tmpl/rsvg.sgml
@@ -268,3 +268,56 @@ librsvg is a component used within software applications to enable support for S
 @Returns: 
 
 
+<!-- ##### ENUM RsvgHandleFlags ##### -->
+<para>
+
+</para>
+
+ RSVG_HANDLE_FLAGS_NONE: 
+
+<!-- ##### FUNCTION rsvg_handle_set_base_gfile ##### -->
+<para>
+
+</para>
+
+ handle: 
+ base_file: 
+
+
+<!-- ##### FUNCTION rsvg_handle_read_stream_sync ##### -->
+<para>
+
+</para>
+
+ handle: 
+ stream: 
+ cancellable: 
+ error: 
+ Returns: 
+
+
+<!-- ##### FUNCTION rsvg_handle_new_from_gfile_sync ##### -->
+<para>
+
+</para>
+
+ file: 
+ flags: 
+ cancellable: 
+ error: 
+ Returns: 
+
+
+<!-- ##### FUNCTION rsvg_handle_new_from_stream_sync ##### -->
+<para>
+
+</para>
+
+ input_stream: 
+ base_file: 
+ flags: 
+ cancellable: 
+ error: 
+ Returns: 
+
+
diff --git a/librsvg.def b/librsvg.def
index 3810812..22c8654 100644
--- a/librsvg.def
+++ b/librsvg.def
@@ -14,6 +14,7 @@ rsvg_handle_get_pixbuf_sub
 rsvg_handle_free
 rsvg_handle_get_base_uri
 rsvg_handle_set_base_uri
+rsvg_handle_set_base_gfile
 rsvg_handle_get_dimensions
 rsvg_handle_get_dimensions_sub
 rsvg_handle_get_position_sub
@@ -38,3 +39,7 @@ _rsvg_register_types
 rsvg_defs_lookup
 rsvg_pixbuf_from_data_with_size_data
 rsvg_css_parse_color
+rsvg_cairo_to_pixbuf
+rsvg_handle_read_stream_sync
+rsvg_handle_new_from_gfile_sync
+rsvg_handle_new_from_stream_sync
diff --git a/librsvg.pc.in b/librsvg.pc.in
index 6e34580..aa1ad49 100644
--- a/librsvg.pc.in
+++ b/librsvg.pc.in
@@ -9,7 +9,7 @@ css_supported= CSS_SUPPORTED@
 Name: librsvg
 Description: library that renders svg files
 Version: @VERSION@
-Requires: glib-2.0 gdk-pixbuf- GTK_API_VERSION@ cairo
-Requires.private: gio-2.0
+Requires: glib-2.0 gio-2.0 gdk-pixbuf- GTK_API_VERSION@ cairo
+Requires.private:
 Libs: -L${libdir} -lrsvg- RSVG_API_MAJOR_VERSION@ -lm
 Cflags: -I${includedir}/librsvg- RSVG_API_VERSION@
diff --git a/rsvg-base.c b/rsvg-base.c
index e80c4fb..85ce8e5 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -47,6 +47,8 @@
 #include "rsvg-cairo-render.h"
 
 #include <libxml/uri.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
 
 #include <math.h>
 #include <string.h>
@@ -55,6 +57,7 @@
 #include "rsvg-bpath-util.h"
 #include "rsvg-path.h"
 #include "rsvg-paint-server.h"
+#include "rsvg-xml.h"
 
 /*
  * This is configurable at runtime
@@ -1058,6 +1061,39 @@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
 }
 
 /**
+ * rsvg_handle_set_base_gfile:
+ * @handle: a #RsvgHandle
+ * @file: a #GFile
+ *
+ * Set the base URI for @handle from @file.
+ * Note: This function may only be called before rsvg_handle_write()
+ * or rsvg_handle_read_stream() has been called.
+ *
+ * Since: 2.32
+ */
+void
+rsvg_handle_set_base_gfile (RsvgHandle *handle,
+                            GFile      *base_file)
+{
+    RsvgHandlePrivate *priv;
+
+    g_return_if_fail (RSVG_IS_HANDLE (handle));
+    g_return_if_fail (G_IS_FILE (base_file));
+
+    priv = handle->priv;
+
+    g_object_ref (base_file);
+    if (priv->base_gfile)
+        g_object_unref (priv->base_gfile);
+    priv->base_gfile = base_file;
+    
+    g_free (priv->base_uri);
+    priv->base_uri = g_file_get_uri (base_file);
+
+    rsvg_defs_set_base_uri (priv->defs, priv->base_uri);
+}
+
+/**
  * rsvg_handle_get_base_uri:
  * @handle: A #RsvgHandle
  *
@@ -1756,6 +1792,182 @@ rsvg_handle_close (RsvgHandle * handle, GError ** error)
 }
 
 /**
+ * rsvg_handle_read_stream_sync:
+ * @handle: a #RsvgHandle
+ * @stream: a #GInputStream
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Reads @stream and writes the data from it to @handle.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the
+ * operation was cancelled, the error G_IO_ERROR_CANCELLED will be
+ * returned.
+ *
+ * Returns: %TRUE if reading @stream succeeded, or %FALSE otherwise
+ *   with @error filled in
+ *
+ * Since: 2.32
+ */
+gboolean
+rsvg_handle_read_stream_sync (RsvgHandle   *handle,
+                              GInputStream *stream,
+                              GCancellable *cancellable,
+                              GError      **error)
+{
+    RsvgHandlePrivate *priv;
+    xmlParserInputBufferPtr buffer;
+    xmlParserInputPtr input;
+    int result;
+    xmlDocPtr doc;
+    GError *err = NULL;
+
+    g_return_val_if_fail (RSVG_IS_HANDLE (handle), 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);
+
+    priv = handle->priv;
+
+    priv->error = &err;
+    if (priv->ctxt == NULL) {
+        priv->ctxt = xmlCreatePushParserCtxt (&rsvgSAXHandlerStruct, handle, NULL, 0,
+                                              rsvg_handle_get_base_uri (handle));
+
+        /* if false, external entities work, but internal ones don't. if true, internal entities
+           work, but external ones don't. favor internal entities, in order to not cause a
+           regression */
+        /* FIXMEchpe: FIX THIS! */
+        priv->ctxt->replaceEntities = TRUE;
+    }
+
+    buffer = _rsvg_xml_input_buffer_new_from_stream (stream, cancellable, XML_CHAR_ENCODING_NONE, &err);
+    input = xmlNewIOInputStream (priv->ctxt, buffer, XML_CHAR_ENCODING_NONE);
+    if (xmlPushInput (priv->ctxt, input) < 0) {
+        rsvg_set_error (error, priv->ctxt);
+        xmlFreeInputStream (input);
+        return FALSE;
+    }
+
+    result = xmlParseDocument (priv->ctxt);
+    if (result != 0) {
+        if (err)
+            g_propagate_error (error, err);
+        else
+            rsvg_set_error (error, handle->priv->ctxt);
+
+        return FALSE;
+    }
+
+    priv->error = NULL;
+
+    if (err != NULL) {
+        g_propagate_error (error, err);
+        return FALSE;
+    }
+
+    doc = priv->ctxt->myDoc;
+    xmlFreeParserCtxt (priv->ctxt);
+    priv->ctxt = NULL;
+
+    xmlFreeDoc (doc);
+
+    rsvg_defs_resolve_all (priv->defs);
+    priv->finished = TRUE;
+
+    return TRUE;
+}
+
+/**
+ * rsvg_handle_new_from_gfile_sync:
+ * @file: a #GFile
+ * @flags: flags from #RsvgHandleFlags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Creates a new #RsvgHandle for @file.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the
+ * operation was cancelled, the error G_IO_ERROR_CANCELLED will be
+ * returned.
+ *
+ * Returns: a new #RsvgHandle on success, or %NULL with @error filled in
+ *
+ * Since: 2.32
+ */
+RsvgHandle *
+rsvg_handle_new_from_gfile_sync (GFile          *file,
+                                 RsvgHandleFlags flags,
+                                 GCancellable   *cancellable,
+                                 GError        **error)
+{
+    RsvgHandle *handle;
+    GFileInputStream *stream;
+
+    g_return_val_if_fail (G_IS_FILE (file), NULL);
+    g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+    g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+    stream = g_file_read (file, cancellable, error);
+    if (stream == NULL)
+        return NULL;
+
+    handle = rsvg_handle_new_from_stream_sync (G_INPUT_STREAM (stream), file,
+                                               flags, cancellable, error);
+    g_object_unref (stream);
+
+    return handle;
+}
+
+/**
+ * rsvg_handle_new_from_stream_sync:
+ * @stream: a #GInputStream
+ * @base_file: (allow-none): a #GFile, or %NULL
+ * @flags: flags from #RsvgHandleFlags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Creates a new #RsvgHandle for @stream.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the
+ * operation was cancelled, the error G_IO_ERROR_CANCELLED will be
+ * returned.
+ *
+ * Returns: a new #RsvgHandle on success, or %NULL with @error filled in
+ *
+ * Since: 2.32
+ */
+RsvgHandle *
+rsvg_handle_new_from_stream_sync (GInputStream   *stream,
+                                  GFile          *base_file,
+                                  RsvgHandleFlags flags,
+                                  GCancellable    *cancellable,
+                                  GError         **error)
+{
+    RsvgHandle *handle;
+
+    g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
+    g_return_val_if_fail (base_file == NULL || G_IS_FILE (base_file), NULL);
+    g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+    g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+    handle = rsvg_handle_new ();
+
+    if (base_file)
+        rsvg_handle_set_base_gfile (handle, base_file);
+
+    if (!rsvg_handle_read_stream_sync (handle, stream, cancellable, error)) {
+        g_object_unref (handle);
+        return NULL;
+    }
+
+    return handle;
+}
+
+/**
  * rsvg_init:
  *
  * Initializes librsvg
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 62c6670..358f690 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -120,6 +120,11 @@ instance_dispose (GObject * instance)
 
     g_free (self->priv);
 
+    if (self->priv->base_gfile) {
+        g_object_unref (self->priv->base_gfile);
+        self->priv->base_gfile = NULL;
+    }
+
     rsvg_parent_class->dispose (instance);
 }
 
diff --git a/rsvg-private.h b/rsvg-private.h
index c4fed2d..d18b922 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -162,6 +162,7 @@ struct RsvgHandlePrivate {
     GString *metadata;
 
     gchar *base_uri;
+    GFile *base_gfile;
 
     gboolean finished;
 
diff --git a/rsvg.h b/rsvg.h
index 85ce82f..37e7930 100644
--- a/rsvg.h
+++ b/rsvg.h
@@ -26,6 +26,9 @@
 #ifndef RSVG_H
 #define RSVG_H
 
+#include <glib-object.h>
+#include <gio/gio.h>
+
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
 G_BEGIN_DECLS
@@ -133,6 +136,31 @@ gboolean rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * p
 
 gboolean rsvg_handle_has_sub (RsvgHandle * handle, const char *id);
 
+/* GIO APIs */
+
+typedef enum {
+    RSVG_HANDLE_FLAGS_NONE        = 0,
+} RsvgHandleFlags;
+
+void        rsvg_handle_set_base_gfile (RsvgHandle *handle,
+                                        GFile      *base_file);
+
+gboolean    rsvg_handle_read_stream_sync (RsvgHandle   *handle,
+                                          GInputStream *stream,
+                                          GCancellable *cancellable,
+                                          GError      **error);
+
+RsvgHandle *rsvg_handle_new_from_gfile_sync (GFile          *file,
+                                             RsvgHandleFlags flags,
+                                             GCancellable   *cancellable,
+                                             GError        **error);
+
+RsvgHandle *rsvg_handle_new_from_stream_sync (GInputStream   *input_stream,
+                                              GFile          *base_file,
+                                              RsvgHandleFlags flags,
+                                              GCancellable   *cancellable,
+                                              GError        **error);
+
 /* Accessibility API */
 
 G_CONST_RETURN char *rsvg_handle_get_title	(RsvgHandle * handle);



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