[glib/wip/resources] Allow looking up data for compressed resources



commit 885185a4b3abd6e2728775f386634f21024e09c2
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Jan 10 14:50:17 2012 +0100

    Allow looking up data for compressed resources

 gio/gioenums.h        |    2 +-
 gio/gresource.c       |   53 +++++++++++++++++++++++++++++++++++++++++++-----
 gio/tests/resources.c |   12 +++-------
 3 files changed, 52 insertions(+), 15 deletions(-)
---
diff --git a/gio/gioenums.h b/gio/gioenums.h
index f2971b8..241ae81 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -632,7 +632,7 @@ typedef enum {
 
 typedef enum {
   G_RESOURCE_ERROR_NOT_FOUND,
-  G_RESOURCE_ERROR_NOT_MAPPABLE
+  G_RESOURCE_ERROR_INTERNAL
 } GResourceError;
 
 typedef enum {
diff --git a/gio/gresource.c b/gio/gresource.c
index 4beab46..1b5def2 100644
--- a/gio/gresource.c
+++ b/gio/gresource.c
@@ -255,13 +255,54 @@ g_resource_lookup_data (GResource *resource,
 
   if (flags & G_RESOURCE_FLAGS_COMPRESSED)
     {
-      g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_MAPPABLE,
-		   _("The resource at '%s' is not directly mappable due to being compressed"),
-		   path);
-      return NULL;
-    }
+      char *uncompressed, *d;
+      const char *s;
+      GConverterResult res;
+      gsize d_size, s_size;
+      gsize bytes_read, bytes_written;
+
+
+      GZlibDecompressor *decompressor =
+	g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB);
+
+      uncompressed = g_malloc (size + 1);
+
+      s = data;
+      s_size = data_size;
+      d = uncompressed;
+      d_size = size;
 
-  return g_bytes_new_with_free_func (data, data_size, (GDestroyNotify)g_resource_unref, g_resource_ref (resource));
+      do
+	{
+	  res = g_converter_convert (G_CONVERTER (decompressor),
+				     s, s_size,
+				     d, d_size,
+				     G_CONVERTER_INPUT_AT_END,
+				     &bytes_read,
+				     &bytes_written,
+				     NULL);
+	  if (res == G_CONVERTER_ERROR)
+	    {
+	      g_free (uncompressed);
+	      g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL,
+			   _("The resource at '%s' failed to decompress"),
+			   path);
+	      return NULL;
+
+	    }
+	  s += bytes_read;
+	  s_size -= bytes_read;
+	  d += bytes_written;
+	  d_size -= bytes_written;
+	}
+      while (res != G_CONVERTER_FINISHED);
+
+      uncompressed[size] = 0; /* Zero terminate */
+
+      return g_bytes_new_take (uncompressed, size);
+    }
+  else
+    return g_bytes_new_with_free_func (data, data_size, (GDestroyNotify)g_resource_unref, g_resource_ref (resource));
 }
 
 gboolean
diff --git a/gio/tests/resources.c b/gio/tests/resources.c
index 8b66291..a0fb7d0 100644
--- a/gio/tests/resources.c
+++ b/gio/tests/resources.c
@@ -77,14 +77,12 @@ test_resource (GResource *resource)
   g_assert (size == 6);
   g_assert (flags == 0);
 
-  /* This will fail due to compression */
   data = g_resource_lookup_data (resource,
 				 "/test1.txt",
 				 G_RESOURCE_LOOKUP_FLAGS_NONE,
 				 &error);
-  g_assert (data == NULL);
-  g_assert (error != NULL);
-  g_clear_error (&error);
+  g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
+  g_assert (error == NULL);
 
   in = g_resource_open_stream (resource,
 			       "/test1.txt",
@@ -250,13 +248,11 @@ test_resource_registred (void)
   g_assert (size == 6);
   g_assert (flags == 0);
 
-  /* This will fail due to compression */
   data = g_resources_lookup_data ("/test1.txt",
 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
 				  &error);
-  g_assert (data == NULL);
-  g_assert (error != NULL);
-  g_clear_error (&error);
+  g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
+  g_assert (error == NULL);
 
   in = g_resources_open_stream ("/test1.txt",
 				G_RESOURCE_LOOKUP_FLAGS_NONE,



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