[gegl] gegl-gio: Implement support for data: URIs
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gegl-gio: Implement support for data: URIs
- Date: Wed, 17 Dec 2014 23:09:58 +0000 (UTC)
commit 997fb21d0a4ea6d74a36990c3ac157239c094bd6
Author: Jon Nordby <jononor gmail com>
Date: Wed Dec 17 23:26:37 2014 +0100
gegl-gio: Implement support for data: URIs
gegl/gegl-gio.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 50 insertions(+), 1 deletions(-)
---
diff --git a/gegl/gegl-gio.c b/gegl/gegl-gio.c
index 6f5fcbf..ee465ef 100644
--- a/gegl/gegl-gio.c
+++ b/gegl/gegl-gio.c
@@ -27,6 +27,48 @@
#include <gio/gunixinputstream.h>
#endif
+static const gint data_prefix_len = strlen("data:");
+
+// Supports data embedded in the URI itself
+// http://en.wikipedia.org/wiki/Data_URI_scheme
+// https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs
+static GInputStream *
+input_stream_datauri(const gchar *uri)
+{
+ GInputStream *stream = NULL;
+
+ // Determine data format
+ const gchar * header_end = g_strstr_len (uri, -1, ",");
+ g_return_val_if_fail(header_end, NULL);
+
+ const gint header_len = header_end - uri - data_prefix_len;
+ gchar *header = g_strndup(uri+data_prefix_len, header_len);
+
+ gchar **header_items = g_strsplit(header, ";", 3);
+ gint header_items_no = -1;
+ while (header_items[++header_items_no]) {
+ }
+
+ // Note: header_item[0] is content-type
+ const gboolean is_base64 = header_items_no > 1 && g_strcmp0(header_items[1], "base64") == 0;
+ g_free(header);
+ g_strfreev(header_items);
+
+ const gchar *raw_data = uri+data_prefix_len+header_len;
+
+ if (is_base64) {
+ gsize len = 0;
+ gchar * data = g_base64_decode (raw_data, &len);
+ stream = g_memory_input_stream_new_from_data (data, len, g_free);
+ } else {
+ gchar *data = g_strdup(raw_data);
+ const gint len = strlen(data);
+ stream = g_memory_input_stream_new_from_data (data, len, g_free);
+ }
+
+ return stream;
+}
+
/**
* gegl_gio_open_input_stream:
* @uri: (allow none) URI to open. @uri is preferred over @path if both are set
@@ -57,7 +99,14 @@ gegl_gio_open_input_stream(const gchar *uri, const gchar *path, GFile **out_file
}
else if (uri && strlen(uri) > 0)
{
- infile = g_file_new_for_uri(uri);
+ if (g_str_has_prefix(uri, "data:"))
+ {
+ fis = input_stream_datauri(uri);
+ }
+ else
+ {
+ infile = g_file_new_for_uri(uri);
+ }
}
else if (path && strlen(path) > 0)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]