[librsvg] Split IO handling to rsvg-io.[ch]
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Split IO handling to rsvg-io.[ch]
- Date: Thu, 12 Jan 2012 23:13:33 +0000 (UTC)
commit 1291ebc3a5cb8addfa97aa56365f15e2427beb22
Author: Christian Persch <chpe gnome org>
Date: Thu Jan 12 22:13:02 2012 +0100
Split IO handling to rsvg-io.[ch]
Add rsvg-io.[ch], move the code there, clean it up, and adapt the callers.
Makefile.am | 2 +
rsvg-base-file-util.c | 20 ++--
rsvg-base.c | 155 ++++++++++++++++++++--------------
rsvg-defs.c | 12 ++-
rsvg-file-util.c | 28 ++++---
rsvg-image.c | 156 ++--------------------------------
rsvg-io.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++
rsvg-io.h | 38 ++++++++
rsvg-private.h | 3 -
rsvg-styles.c | 33 ++++----
rsvg-styles.h | 1 -
11 files changed, 417 insertions(+), 256 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index e53d569..7c69839 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,6 +31,8 @@ librsvg_ RSVG_API_MAJOR_VERSION@_la_SOURCES = \
rsvg-defs.h \
rsvg-image.c \
rsvg-image.h \
+ rsvg-io.c \
+ rsvg-io.h \
rsvg-paint-server.c \
rsvg-paint-server.h \
rsvg-path.c \
diff --git a/rsvg-base-file-util.c b/rsvg-base-file-util.c
index 902c436..2c9eae1 100644
--- a/rsvg-base-file-util.c
+++ b/rsvg-base-file-util.c
@@ -26,6 +26,7 @@
#include "config.h"
#include "rsvg.h"
+#include "rsvg-io.h"
#include "rsvg-private.h"
static gboolean
@@ -85,24 +86,23 @@ RsvgHandle *
rsvg_handle_new_from_file (const gchar * file_name, GError ** error)
{
gchar *base_uri;
- GByteArray *f;
+ guint8 *data;
+ gsize data_len;
RsvgHandle *handle = NULL;
rsvg_return_val_if_fail (file_name != NULL, NULL, error);
base_uri = rsvg_get_base_uri_from_filename (file_name);
- f = _rsvg_acquire_xlink_href_resource (file_name, base_uri, error);
+ data = _rsvg_io_acquire_data (file_name, base_uri, &data_len, error);
- if (f) {
+ if (data) {
handle = rsvg_handle_new ();
- if (handle) {
- rsvg_handle_set_base_uri (handle, base_uri);
- if (!rsvg_handle_fill_with_data (handle, f->data, f->len, error)) {
- g_object_unref (handle);
- handle = NULL;
- }
+ rsvg_handle_set_base_uri (handle, base_uri);
+ if (!rsvg_handle_fill_with_data (handle, data, data_len, error)) {
+ g_object_unref (handle);
+ handle = NULL;
}
- g_byte_array_free (f, TRUE);
+ g_free (data);
}
g_free (base_uri);
diff --git a/rsvg-base.c b/rsvg-base.c
index 3dce61c..1b2c20b 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -33,6 +33,7 @@
#include "rsvg-shapes.h"
#include "rsvg-structure.h"
#include "rsvg-image.h"
+#include "rsvg-io.h"
#include "rsvg-text.h"
#include "rsvg-filter.h"
#include "rsvg-mask.h"
@@ -524,57 +525,81 @@ static void
rsvg_start_xinclude (RsvgHandle * ctx, RsvgPropertyBag * atts)
{
RsvgSaxHandlerXinclude *handler;
- GByteArray *data;
- const char *href;
+ const char *href, *parse;
gboolean success = FALSE;
href = rsvg_property_bag_lookup (atts, "href");
- if (href) {
- data = _rsvg_acquire_xlink_href_resource (href, rsvg_handle_get_base_uri (ctx), NULL);
- if (data) {
- const char *parse;
-
- parse = rsvg_property_bag_lookup (atts, "parse");
- if (parse && !strcmp (parse, "text")) {
- const char *encoding;
- char *text_data;
- gsize text_data_len;
- gboolean text_data_needs_free = FALSE;
-
- encoding = rsvg_property_bag_lookup (atts, "encoding");
- if (encoding) {
- text_data =
- g_convert ((const char *) data->data, data->len, "utf-8", encoding, NULL,
+ if (href == NULL)
+ goto fallback;
+
+ parse = rsvg_property_bag_lookup (atts, "parse");
+ if (parse && !strcmp (parse, "text")) {
+ guint8 *data;
+ gsize data_len;
+ const char *encoding;
+
+ data = _rsvg_io_acquire_data (href, rsvg_handle_get_base_uri (ctx), &data_len, NULL);
+ if (data == NULL)
+ goto fallback;
+
+ encoding = rsvg_property_bag_lookup (atts, "encoding");
+ if (encoding && g_ascii_strcasecmp (encoding, "UTF-8") != 0) {
+ char *text_data;
+ gsize text_data_len;
+
+ text_data = g_convert (data, data_len, "utf-8", encoding, NULL,
&text_data_len, NULL);
- text_data_needs_free = TRUE;
- } else {
- text_data = (char *) data->data;
- text_data_len = data->len;
- }
+ g_free (data);
- rsvg_characters_impl (ctx, (const xmlChar *) text_data, text_data_len);
+ data = text_data;
+ data_len = text_data_len;
+ }
- if (text_data_needs_free)
- g_free (text_data);
- } else {
- /* xml */
- xmlDocPtr xml_doc;
- xmlParserCtxtPtr xml_parser;
+ rsvg_characters_impl (ctx, (const xmlChar *) data, data_len);
- xml_parser = xmlCreatePushParserCtxt (&rsvgSAXHandlerStruct, ctx, NULL, 0, NULL);
- (void) xmlParseChunk (xml_parser, (char *) data->data, data->len, 0);
- (void) xmlParseChunk (xml_parser, "", 0, TRUE);
+ g_free (data);
+ } else {
+ /* xml */
+ GInputStream *stream;
+ GError *err = NULL;
+ xmlDocPtr xml_doc;
+ xmlParserCtxtPtr xml_parser;
+ xmlParserInputBufferPtr buffer;
+ xmlParserInputPtr input;
+ int result;
- xml_doc = xml_parser->myDoc;
- xmlFreeParserCtxt (xml_parser);
- xmlFreeDoc (xml_doc);
- }
+ stream = _rsvg_io_acquire_stream (href, rsvg_handle_get_base_uri (ctx), NULL);
+ if (stream == NULL)
+ goto fallback;
- g_byte_array_free (data, TRUE);
- success = TRUE;
+ xml_parser = xmlCreatePushParserCtxt (&rsvgSAXHandlerStruct, ctx, NULL, 0, NULL);
+
+ buffer = _rsvg_xml_input_buffer_new_from_stream (stream, NULL /* cancellable */, XML_CHAR_ENCODING_NONE, &err);
+ g_object_unref (stream);
+
+ input = xmlNewIOInputStream (xml_parser, buffer /* adopts */, XML_CHAR_ENCODING_NONE);
+
+ if (xmlPushInput (xml_parser, input) < 0) {
+ g_clear_error (&err);
+ xmlFreeInputStream (input);
+ xmlFreeParserCtxt (xml_parser);
+ goto fallback;
}
+
+ (void) xmlParseDocument (xml_parser);
+
+ xml_doc = xml_parser->myDoc;
+ xmlFreeParserCtxt (xml_parser);
+ if (xml_doc)
+ xmlFreeDoc (xml_doc);
+
+ g_clear_error (&err);
}
+ success = TRUE;
+
+ fallback:
+
/* needed to handle xi:fallback */
handler = g_new0 (RsvgSaxHandlerXinclude, 1);
@@ -776,20 +801,25 @@ rsvg_entity_decl (void *data, const xmlChar * name, int type,
resolvedPublicId = xmlBuildRelativeURI (publicId, (xmlChar*) rsvg_handle_get_base_uri (ctx));
if (type == XML_EXTERNAL_PARAMETER_ENTITY && !content) {
- GByteArray *arr = NULL;
-
- if (systemId)
- arr = _rsvg_acquire_xlink_href_resource ((const char *) systemId,
- rsvg_handle_get_base_uri (ctx), NULL);
- else if (publicId)
- arr = _rsvg_acquire_xlink_href_resource ((const char *) publicId,
- rsvg_handle_get_base_uri (ctx), NULL);
- if (arr) {
- content = xmlCharStrndup ((const char*)arr->data, arr->len);
- g_byte_array_free(arr, TRUE);
- }
+ guint8 *entity_data;
+ gsize entity_data_len;
+
+ if (systemId)
+ entity_data = _rsvg_io_acquire_data ((const char *) systemId,
+ rsvg_handle_get_base_uri (ctx),
+ &entity_data_len,
+ NULL);
+ else if (publicId)
+ entity_data = _rsvg_io_acquire_data ((const char *) publicId,
+ rsvg_handle_get_base_uri (ctx),
+ &entity_data_len,
+ NULL);
+ if (entity_data) {
+ content = xmlCharStrndup (entity_data, entity_data_len);
+ g_free (entity_data);
+ }
}
-
+
entity = xmlNewEntity(NULL, name, type, resolvedPublicId, resolvedSystemId, content);
xmlFree(resolvedPublicId);
@@ -852,15 +882,16 @@ rsvg_processing_instruction (void *ctx, const xmlChar * target, const xmlChar *
if (value && strcmp (value, "text/css") == 0) {
value = rsvg_property_bag_lookup (atts, "href");
if (value && value[0]) {
- GByteArray *style;
-
- style =
- _rsvg_acquire_xlink_href_resource (value,
- rsvg_handle_get_base_uri (handle),
- NULL);
- if (style) {
- rsvg_parse_cssbuffer (handle, (char *) style->data, style->len);
- g_byte_array_free (style, TRUE);
+ guint8 *style_data;
+ gsize style_data_len;
+
+ style_data = _rsvg_io_acquire_data (value,
+ rsvg_handle_get_base_uri (handle),
+ &style_data_len,
+ NULL);
+ if (style_data) {
+ rsvg_parse_cssbuffer (handle, (char *) style_data, style_data_len);
+ g_free (style_data);
}
}
}
diff --git a/rsvg-defs.c b/rsvg-defs.c
index 18176f9..0c3df9f 100644
--- a/rsvg-defs.c
+++ b/rsvg-defs.c
@@ -28,6 +28,7 @@
#include "rsvg-defs.h"
#include "rsvg-styles.h"
#include "rsvg-image.h"
+#include "rsvg-io.h"
#include <glib.h>
@@ -72,25 +73,26 @@ rsvg_defs_load_extern (const RsvgDefs * defs, const char *name)
{
RsvgHandle *handle;
gchar *filename, *base_uri;
- GByteArray *chars;
+ guint8 *data;
+ gsize data_len;
filename = rsvg_get_file_path (name, defs->base_uri);
- chars = _rsvg_acquire_xlink_href_resource (name, defs->base_uri, NULL);
+ data = _rsvg_io_acquire_data (name, defs->base_uri, &data_len, NULL);
- if (chars) {
+ if (data) {
handle = rsvg_handle_new ();
base_uri = rsvg_get_base_uri_from_filename (filename);
rsvg_handle_set_base_uri (handle, base_uri);
g_free (base_uri);
- if (rsvg_handle_write (handle, chars->data, chars->len, NULL) &&
+ if (rsvg_handle_write (handle, data, data_len, NULL) &&
rsvg_handle_close (handle, NULL)) {
g_hash_table_insert (defs->externs, g_strdup (name), handle);
}
- g_byte_array_free (chars, TRUE);
+ g_free (data);
}
g_free (filename);
diff --git a/rsvg-file-util.c b/rsvg-file-util.c
index a1b67b6..39cfe2b 100644
--- a/rsvg-file-util.c
+++ b/rsvg-file-util.c
@@ -36,6 +36,7 @@
#include "config.h"
#include "rsvg.h"
#include "rsvg-private.h"
+#include "rsvg-io.h"
#include <errno.h>
#include <stdio.h>
@@ -157,9 +158,11 @@ rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
}
static GdkPixbuf *
-rsvg_pixbuf_from_stdio_file_with_size_data (GByteArray * f,
- struct RsvgSizeCallbackData *data,
- gchar * base_uri, GError ** error)
+rsvg_pixbuf_from_stdio_file_with_size_data (guint8 *data,
+ gsize data_len,
+ struct RsvgSizeCallbackData *cb_data,
+ gchar * base_uri,
+ GError ** error)
{
RsvgHandle *handle;
GdkPixbuf *retval;
@@ -171,10 +174,10 @@ rsvg_pixbuf_from_stdio_file_with_size_data (GByteArray * f,
return NULL;
}
- rsvg_handle_set_size_callback (handle, _rsvg_size_callback, data, NULL);
+ rsvg_handle_set_size_callback (handle, _rsvg_size_callback, cb_data, NULL);
rsvg_handle_set_base_uri (handle, base_uri);
- if (!rsvg_handle_write (handle, f->data, f->len, error)) {
+ if (!rsvg_handle_write (handle, data, data_len, error)) {
g_object_unref (handle);
return NULL;
}
@@ -192,17 +195,20 @@ rsvg_pixbuf_from_stdio_file_with_size_data (GByteArray * f,
static GdkPixbuf *
rsvg_pixbuf_from_file_with_size_data (const gchar * file_name,
- struct RsvgSizeCallbackData *data, GError ** error)
+ struct RsvgSizeCallbackData *cb_data,
+ GError ** error)
{
GdkPixbuf *pixbuf;
- GByteArray *f;
+ guint8 *data;
+ gsize data_len;
GString *base_uri = g_string_new (file_name);
- f = _rsvg_acquire_xlink_href_resource (file_name, base_uri->str, error);
+ data = _rsvg_io_acquire_data (file_name, base_uri->str, &data_len, error);
- if (f) {
- pixbuf = rsvg_pixbuf_from_stdio_file_with_size_data (f, data, base_uri->str, error);
- g_byte_array_free (f, TRUE);
+ if (data) {
+ pixbuf = rsvg_pixbuf_from_stdio_file_with_size_data (data, data_len,
+ cb_data, base_uri->str, error);
+ g_free (data);
} else {
pixbuf = NULL;
}
diff --git a/rsvg-image.c b/rsvg-image.c
index 0ccc7f6..9c4a3f9 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -34,170 +34,28 @@
#include <math.h>
#include <errno.h>
#include "rsvg-css.h"
-#include <gio/gio.h>
-
-static GByteArray *
-rsvg_acquire_base64_resource (const char *data, GError ** error)
-{
- GByteArray *array = NULL;
- gsize data_len, written_len;
- int state = 0;
- guint save = 0;
-
- rsvg_return_val_if_fail (data != NULL, NULL, error);
-
- while (*data)
- if (*data++ == ',')
- break;
-
- data_len = strlen (data);
- array = g_byte_array_sized_new (data_len / 4 * 3);
- written_len = g_base64_decode_step (data, data_len, array->data,
- &state, &save);
- g_byte_array_set_size (array, written_len);
-
- return array;
-}
-
-gchar *
-rsvg_get_file_path (const gchar * filename, const gchar * base_uri)
-{
- gchar *absolute_filename;
-
- if (g_file_test (filename, G_FILE_TEST_EXISTS) || g_path_is_absolute (filename)) {
- absolute_filename = g_strdup (filename);
- } else {
- gchar *tmpcdir;
- gchar *base_filename;
-
- if (base_uri) {
- base_filename = g_filename_from_uri (base_uri, NULL, NULL);
- if (base_filename != NULL) {
- tmpcdir = g_path_get_dirname (base_filename);
- g_free (base_filename);
- } else
- return NULL;
- } else
- tmpcdir = g_get_current_dir ();
-
- absolute_filename = g_build_filename (tmpcdir, filename, NULL);
- g_free (tmpcdir);
- }
-
- return absolute_filename;
-}
-
-static GByteArray *
-rsvg_acquire_file_resource (const char *filename, const char *base_uri, GError ** error)
-{
- GByteArray *array;
- gchar *path;
- gchar *data = NULL;
- gsize length;
-
- rsvg_return_val_if_fail (filename != NULL, NULL, error);
-
- path = rsvg_get_file_path (filename, base_uri);
- if (path == NULL)
- return NULL;
-
- if (!g_file_get_contents (path, &data, &length, error)) {
- g_free (path);
- return NULL;
- }
-
- array = g_byte_array_new ();
-
- g_byte_array_append (array, (guint8 *)data, length);
- g_free (data);
- g_free (path);
-
- return array;
-}
-
-static GByteArray *
-rsvg_acquire_vfs_resource (const char *filename, const char *base_uri, GError ** error)
-{
- GByteArray *array;
-
- GFile *file;
- char *data;
- gsize size;
- gboolean res = FALSE;
-
- rsvg_return_val_if_fail (filename != NULL, NULL, error);
-
- file = g_file_new_for_uri (filename);
-
- if (!(res = g_file_load_contents (file, NULL, &data, &size, NULL, error))) {
- if (base_uri != NULL) {
- GFile *base;
-
- g_clear_error (error);
-
- g_object_unref (file);
-
- base = g_file_new_for_uri (base_uri);
- file = g_file_resolve_relative_path (base, filename);
- g_object_unref (base);
-
- res = g_file_load_contents (file, NULL, &data, &size, NULL, error);
- }
- }
-
- g_object_unref (file);
-
- if (res) {
- array = g_byte_array_new ();
-
- g_byte_array_append (array, (guint8 *)data, size);
- g_free (data);
- } else {
- return NULL;
- }
-
- return array;
-}
-
-GByteArray *
-_rsvg_acquire_xlink_href_resource (const char *href, const char *base_uri, GError ** err)
-{
- GByteArray *arr = NULL;
-
- if (!(href && *href))
- return NULL;
-
- if (!strncmp (href, "data:", 5))
- arr = rsvg_acquire_base64_resource (href, NULL);
-
- if (!arr)
- arr = rsvg_acquire_file_resource (href, base_uri, NULL);
-
- if (!arr)
- arr = rsvg_acquire_vfs_resource (href, base_uri, NULL);
-
- return arr;
-}
+#include "rsvg-io.h"
cairo_surface_t *
rsvg_cairo_surface_new_from_href (const char *href,
const char *base_uri,
GError **error)
{
- GByteArray *arr;
+ guint8 *data;
+ gsize data_len;
GdkPixbufLoader *loader;
GdkPixbuf *pixbuf = NULL;
int res;
cairo_surface_t *surface;
- arr = _rsvg_acquire_xlink_href_resource (href, base_uri, error);
- if (arr == NULL)
+ data = _rsvg_io_acquire_data (href, base_uri, &data_len, error);
+ if (data == NULL)
return NULL;
loader = gdk_pixbuf_loader_new ();
- res = gdk_pixbuf_loader_write (loader, arr->data, arr->len, error);
- g_byte_array_free (arr, TRUE);
+ res = gdk_pixbuf_loader_write (loader, data, data_len, error);
+ g_free (data);
if (!res) {
gdk_pixbuf_loader_close (loader, NULL);
diff --git a/rsvg-io.c b/rsvg-io.c
new file mode 100644
index 0000000..921d113
--- /dev/null
+++ b/rsvg-io.c
@@ -0,0 +1,225 @@
+/*
+ Copyright (C) 2000 Eazel, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Dom Lachowicz <cinamod hotmail com>
+ Copyright (C) 2003, 2004, 2005 Caleb Moore <c moore student unsw edu au>
+ Copyright  2011, 2012 Christian Persch
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "config.h"
+
+#include "rsvg-io.h"
+#include "rsvg-private.h"
+
+#include <string.h>
+
+static guint8 *
+rsvg_acquire_base64_data (const char *data,
+ const char *base_uri,
+ gsize *len,
+ GError **error)
+{
+ guint8 *bytes;
+ gsize data_len, written_len;
+ int state = 0;
+ guint save = 0;
+
+ /* FIXME: be more correct! Check that is indeed a base64 data: URI */
+ while (*data)
+ if (*data++ == ',')
+ break;
+
+ data_len = strlen (data);
+ bytes = g_try_malloc (data_len / 4 * 3);
+ if (bytes == NULL)
+ return NULL;
+
+ written_len = g_base64_decode_step (data, data_len, bytes, &state, &save);
+
+ *len = written_len;
+
+ return bytes;
+}
+
+gchar *
+rsvg_get_file_path (const gchar * filename, const gchar * base_uri)
+{
+ gchar *absolute_filename;
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS) || g_path_is_absolute (filename)) {
+ absolute_filename = g_strdup (filename);
+ } else {
+ gchar *tmpcdir;
+ gchar *base_filename;
+
+ if (base_uri) {
+ base_filename = g_filename_from_uri (base_uri, NULL, NULL);
+ if (base_filename != NULL) {
+ tmpcdir = g_path_get_dirname (base_filename);
+ g_free (base_filename);
+ } else
+ return NULL;
+ } else
+ tmpcdir = g_get_current_dir ();
+
+ absolute_filename = g_build_filename (tmpcdir, filename, NULL);
+ g_free (tmpcdir);
+ }
+
+ return absolute_filename;
+}
+
+static guint8 *
+rsvg_acquire_file_data (const char *filename,
+ const char *base_uri,
+ gsize *len,
+ GError **error)
+{
+ GFile *file;
+ gchar *path, *data;
+ GInputStream *stream;
+
+ rsvg_return_val_if_fail (filename != NULL, NULL, error);
+
+ path = rsvg_get_file_path (filename, base_uri);
+ if (path == NULL)
+ return NULL;
+
+ if (!g_file_get_contents (path, &data, len, error))
+ return NULL;
+
+ return data;
+}
+
+static GInputStream *
+rsvg_acquire_gvfs_stream (const char *uri,
+ const char *base_uri,
+ GError **error)
+{
+ GFile *base, *file;
+ GInputStream *stream;
+ GError *err = NULL;
+ gchar *data;
+
+ file = g_file_new_for_uri (uri);
+
+ stream = (GInputStream *) g_file_read (file, NULL /* cancellable */, &err);
+ g_object_unref (file);
+
+ if (stream == NULL &&
+ g_error_matches (err, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ g_clear_error (&err);
+
+ base = g_file_new_for_uri (base_uri);
+ file = g_file_resolve_relative_path (base, uri);
+ g_object_unref (base);
+
+ stream = (GInputStream *) g_file_read (file, NULL /* cancellable */, &err);
+ g_object_unref (file);
+ }
+
+ if (stream == NULL)
+ g_propagate_error (error, err);
+
+ return stream;
+}
+
+static guint8 *
+rsvg_acquire_gvfs_data (const char *uri,
+ const char *base_uri,
+ gsize *len,
+ GError **error)
+{
+ GFile *base, *file;
+ GInputStream *stream;
+ GError *err;
+ gchar *data;
+ gboolean res;
+
+ file = g_file_new_for_uri (uri);
+
+ err = NULL;
+ data = NULL;
+ if (!(res = g_file_load_contents (file, NULL, &data, len, NULL, &err)) &&
+ g_error_matches (err, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
+ base_uri != NULL) {
+ g_clear_error (&err);
+
+ base = g_file_new_for_uri (base_uri);
+ file = g_file_resolve_relative_path (base, uri);
+ g_object_unref (base);
+
+ res = g_file_load_contents (file, NULL, &data, len, NULL, &err);
+ }
+
+ g_object_unref (file);
+
+ if (err == NULL)
+ return data;
+
+ g_propagate_error (error, err);
+ return NULL;
+}
+
+guint8 *
+_rsvg_io_acquire_data (const char *href,
+ const char *base_uri,
+ gsize *len,
+ GError **error)
+{
+ guint8 *data;
+
+ if (!(href && *href))
+ return NULL;
+
+ if (strncmp (href, "data:", 5) == 0 &&
+ (data = rsvg_acquire_base64_data (href, NULL, len, error)))
+ return data;
+
+ if ((data = rsvg_acquire_file_data (href, base_uri, len, error)))
+ return data;
+
+ if ((data = rsvg_acquire_gvfs_data (href, base_uri, len, error)))
+ return data;
+
+ return NULL;
+}
+
+GInputStream *
+_rsvg_io_acquire_stream (const char *href,
+ const char *base_uri,
+ GError **error)
+{
+ GInputStream *stream;
+ guint8 *data;
+ gsize len;
+
+ if (!(href && *href))
+ return NULL;
+
+ if (strncmp (href, "data:", 5) == 0 &&
+ (data = rsvg_acquire_base64_data (href, NULL, &len, error)))
+ return g_memory_input_stream_new_from_data (data, len, (GDestroyNotify) g_free);
+
+ if ((data = rsvg_acquire_file_data (href, base_uri, &len, error)))
+ return g_memory_input_stream_new_from_data (data, len, (GDestroyNotify) g_free);
+
+ if ((stream = rsvg_acquire_gvfs_stream (href, base_uri, error)))
+ return stream;
+
+ return NULL;
+}
diff --git a/rsvg-io.h b/rsvg-io.h
new file mode 100644
index 0000000..be3db8c
--- /dev/null
+++ b/rsvg-io.h
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2000 Eazel, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Dom Lachowicz <cinamod hotmail com>
+ Copyright (C) 2003, 2004, 2005 Caleb Moore <c moore student unsw edu au>
+ Copyright  2011, 2012 Christian Persch
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef RSVG_IO_H
+#define RSVG_IO_H
+
+#include <glib.h>
+#include <gio/gio.h>
+
+guint8* _rsvg_io_acquire_data (const char *uri,
+ const char *base_uri,
+ gsize *len,
+ GError **error);
+
+GInputStream *_rsvg_io_acquire_stream (const char *uri,
+ const char *base_uri,
+ GError **error);
+
+#endif /* RSVG_IO_H */
diff --git a/rsvg-private.h b/rsvg-private.h
index 4e7fc73..eaaae2d 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -361,9 +361,6 @@ GdkPixbuf *rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
gboolean rsvg_eval_switch_attributes (RsvgPropertyBag * atts, gboolean * p_has_cond);
gchar *rsvg_get_base_uri_from_filename (const gchar * file_name);
-GByteArray *_rsvg_acquire_xlink_href_resource (const char *href,
- const char *base_uri, GError ** err);
-
void rsvg_pop_discrete_layer (RsvgDrawingCtx * ctx);
void rsvg_push_discrete_layer (RsvgDrawingCtx * ctx);
void rsvg_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path);
diff --git a/rsvg-styles.c b/rsvg-styles.c
index dead491..eed23e8 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -32,6 +32,7 @@
#include "rsvg-private.h"
#include "rsvg-filter.h"
#include "rsvg-css.h"
+#include "rsvg-io.h"
#include "rsvg-styles.h"
#include "rsvg-shapes.h"
#include "rsvg-mask.h"
@@ -1161,21 +1162,23 @@ ccss_import_style (CRDocHandler * a_this,
GList * a_media_list,
CRString * a_uri, CRString * a_uri_default_ns, CRParsingLocation * a_location)
{
- if (a_uri) {
- GByteArray *stylesheet_data;
- CSSUserData *user_data;
-
- user_data = (CSSUserData *) a_this->app_data;
-
- stylesheet_data =
- _rsvg_acquire_xlink_href_resource ((gchar *) cr_string_peek_raw_str (a_uri),
- rsvg_handle_get_base_uri (user_data->ctx), NULL);
- if (stylesheet_data) {
- rsvg_parse_cssbuffer (user_data->ctx, (const char *) stylesheet_data->data,
- (size_t) stylesheet_data->len);
- g_byte_array_free (stylesheet_data, TRUE);
- }
- }
+ CSSUserData *user_data = (CSSUserData *) a_this->app_data;
+ guint8 *stylesheet_data;
+ gsize stylesheet_data_len;
+
+ if (a_uri == NULL)
+ return;
+
+ stylesheet_data = _rsvg_io_acquire_data ((gchar *) cr_string_peek_raw_str (a_uri),
+ rsvg_handle_get_base_uri (user_data->ctx),
+ &stylesheet_data_len,
+ NULL);
+ if (stylesheet_data == NULL)
+ return;
+
+ rsvg_parse_cssbuffer (user_data->ctx, (const char *) stylesheet_data,
+ stylesheet_data_len);
+ g_free (stylesheet_data);
}
/* Parse an SVG transform string into an affine matrix. Reference: SVG
diff --git a/rsvg-styles.h b/rsvg-styles.h
index 87c36eb..22053f0 100644
--- a/rsvg-styles.h
+++ b/rsvg-styles.h
@@ -201,7 +201,6 @@ void rsvg_state_free_all (RsvgState * state);
void rsvg_parse_style_pairs (RsvgHandle * ctx, RsvgState * state, RsvgPropertyBag * atts);
void rsvg_parse_style (RsvgHandle * ctx, RsvgState * state, const char *str);
void rsvg_parse_cssbuffer (RsvgHandle * ctx, const char *buff, size_t buflen);
-
void rsvg_parse_style_attrs (RsvgHandle * ctx, RsvgState * state, const char *tag,
const char *klazz, const char *id, RsvgPropertyBag * atts);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]