[glib/resources] Return a proper GFileInputStream from GResourceFile open



commit f37dba270e7036d8201e41a80029a5c31484e979
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Dec 22 13:38:35 2011 +0100

    Return a proper GFileInputStream from GResourceFile open

 gio/gresourcefile.c |  195 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 191 insertions(+), 4 deletions(-)
---
diff --git a/gio/gresourcefile.c b/gio/gresourcefile.c
index f6e7277..9f288f0 100644
--- a/gio/gresourcefile.c
+++ b/gio/gresourcefile.c
@@ -30,6 +30,8 @@
 #include <gfileattribute-priv.h>
 #include <gfileinfo-priv.h>
 #include "gfile.h"
+#include "gseekable.h"
+#include "gfileinputstream.h"
 #include "gfileinfo.h"
 #include "gfileenumerator.h"
 #include "gioerror.h"
@@ -76,7 +78,15 @@ static GFileAttributeInfoList *resource_writable_namespaces = NULL;
 #define G_IS_RESOURCE_FILE_ENUMERATOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_RESOURCE_FILE_ENUMERATOR))
 #define G_RESOURCE_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_RESOURCE_FILE_ENUMERATOR, GResourceFileEnumeratorClass))
 
+#define G_TYPE_RESOURCE_FILE_INPUT_STREAM         (_g_resource_file_input_stream_get_type ())
+#define G_RESOURCE_FILE_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_RESOURCE_FILE_INPUT_STREAM, GResourceFileInputStream))
+#define G_RESOURCE_FILE_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_RESOURCE_FILE_INPUT_STREAM, GResourceFileInputStreamClass))
+#define G_IS_RESOURCE_FILE_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_RESOURCE_FILE_INPUT_STREAM))
+#define G_IS_RESOURCE_FILE_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_RESOURCE_FILE_INPUT_STREAM))
+#define G_RESOURCE_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_RESOURCE_FILE_INPUT_STREAM, GResourceFileInputStreamClass))
 
+typedef struct _GResourceFileInputStream         GResourceFileInputStream;
+typedef struct _GResourceFileInputStreamClass    GResourceFileInputStreamClass;
 
 #define g_resource_file_get_type _g_resource_file_get_type
 G_DEFINE_TYPE_WITH_CODE (GResourceFile, g_resource_file, G_TYPE_OBJECT,
@@ -92,6 +102,12 @@ static GFileEnumerator *_g_resource_file_enumerator_new (GResourceFile *file,
 							 GCancellable         *cancellable,
 							 GError              **error);
 
+
+static GType              _g_resource_file_input_stream_get_type (void) G_GNUC_CONST;
+
+static GFileInputStream *_g_resource_file_input_stream_new (GInputStream *stream, GFile *file);
+
+
 static void
 g_resource_file_finalize (GObject *object)
 {
@@ -128,7 +144,7 @@ canonicalize_filename (const char *filename)
   /* Skip multiple inital slashes */
   while (filename[0] == '/' && filename[1] == '/')
     filename++;
-  
+
   if (*filename != '/')
     canon = g_strconcat ("/", filename, NULL);
   else
@@ -191,7 +207,7 @@ g_resource_file_new_for_path (const char *path)
   GResourceFile *resource = g_object_new (G_TYPE_RESOURCE_FILE, NULL);
 
   resource->path = canonicalize_filename (path);
-  
+
   return G_FILE (resource);
 }
 
@@ -491,6 +507,7 @@ g_resource_file_read (GFile         *file,
   GResourceFile *resource = G_RESOURCE_FILE (file);
   GError *my_error = NULL;
   GInputStream *stream;
+  GFileInputStream *res;
 
   stream = g_resources_open_stream (resource->path, &my_error);
 
@@ -509,8 +526,9 @@ g_resource_file_read (GFile         *file,
       return NULL;
     }
 
-  /* TODO: This isn't right, we need to wrap the stream */
-  return (GFileInputStream *)stream;
+  res = _g_resource_file_input_stream_new (stream, file);
+  g_object_unref (stream);
+  return res;
 }
 
 static void
@@ -653,3 +671,172 @@ g_resource_file_enumerator_close (GFileEnumerator  *enumerator,
 {
   return TRUE;
 }
+
+
+struct _GResourceFileInputStream
+{
+  GFileInputStream parent_instance;
+  GInputStream *stream;
+  GFile *file;
+};
+
+struct _GResourceFileInputStreamClass
+{
+  GFileInputStreamClass parent_class;
+};
+
+#define g_resource_file_input_stream_get_type _g_resource_file_input_stream_get_type
+G_DEFINE_TYPE (GResourceFileInputStream, g_resource_file_input_stream, G_TYPE_FILE_INPUT_STREAM);
+
+static gssize     g_resource_file_input_stream_read       (GInputStream      *stream,
+							   void              *buffer,
+							   gsize              count,
+							   GCancellable      *cancellable,
+							   GError           **error);
+static gssize     g_resource_file_input_stream_skip       (GInputStream      *stream,
+							   gsize              count,
+							   GCancellable      *cancellable,
+							   GError           **error);
+static gboolean   g_resource_file_input_stream_close      (GInputStream      *stream,
+							   GCancellable      *cancellable,
+							   GError           **error);
+static goffset    g_resource_file_input_stream_tell       (GFileInputStream  *stream);
+static gboolean   g_resource_file_input_stream_can_seek   (GFileInputStream  *stream);
+static gboolean   g_resource_file_input_stream_seek       (GFileInputStream  *stream,
+							   goffset            offset,
+							   GSeekType          type,
+							   GCancellable      *cancellable,
+							   GError           **error);
+static GFileInfo *g_resource_file_input_stream_query_info (GFileInputStream  *stream,
+							   const char        *attributes,
+							   GCancellable      *cancellable,
+							   GError           **error);
+
+static void
+g_resource_file_input_stream_finalize (GObject *object)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (object);
+
+  g_object_unref (file->stream);
+  g_object_unref (file->file);
+  G_OBJECT_CLASS (g_resource_file_input_stream_parent_class)->finalize (object);
+}
+
+static void
+g_resource_file_input_stream_class_init (GResourceFileInputStreamClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
+  GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
+
+  gobject_class->finalize = g_resource_file_input_stream_finalize;
+
+  stream_class->read_fn = g_resource_file_input_stream_read;
+  stream_class->skip = g_resource_file_input_stream_skip;
+  stream_class->close_fn = g_resource_file_input_stream_close;
+  file_stream_class->tell = g_resource_file_input_stream_tell;
+  file_stream_class->can_seek = g_resource_file_input_stream_can_seek;
+  file_stream_class->seek = g_resource_file_input_stream_seek;
+  file_stream_class->query_info = g_resource_file_input_stream_query_info;
+}
+
+static void
+g_resource_file_input_stream_init (GResourceFileInputStream *info)
+{
+}
+
+static GFileInputStream *
+_g_resource_file_input_stream_new (GInputStream *in_stream, GFile *file)
+{
+  GResourceFileInputStream *stream;
+
+  stream = g_object_new (G_TYPE_RESOURCE_FILE_INPUT_STREAM, NULL);
+  stream->stream = g_object_ref (in_stream);
+  stream->file = g_object_ref (file);
+
+  return G_FILE_INPUT_STREAM (stream);
+}
+
+static gssize
+g_resource_file_input_stream_read (GInputStream  *stream,
+				   void          *buffer,
+				   gsize          count,
+				   GCancellable  *cancellable,
+				   GError       **error)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);
+  return g_input_stream_read (file->stream,
+			      buffer, count, cancellable, error);
+}
+
+static gssize
+g_resource_file_input_stream_skip (GInputStream  *stream,
+				   gsize          count,
+				   GCancellable  *cancellable,
+				   GError       **error)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);
+  return g_input_stream_skip (file->stream,
+			      count, cancellable, error);
+}
+
+static gboolean
+g_resource_file_input_stream_close (GInputStream  *stream,
+				    GCancellable  *cancellable,
+				    GError       **error)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);
+  return g_input_stream_close (file->stream,
+			       cancellable, error);
+}
+
+
+static goffset
+g_resource_file_input_stream_tell (GFileInputStream *stream)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);;
+
+  if (!G_IS_SEEKABLE (file->stream));
+      return 0;
+
+  return g_seekable_tell (G_SEEKABLE (file->stream));
+}
+
+static gboolean
+g_resource_file_input_stream_can_seek (GFileInputStream *stream)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);
+
+  return G_IS_SEEKABLE (file->stream) && g_seekable_can_seek (G_SEEKABLE (file->stream));
+}
+
+static gboolean
+g_resource_file_input_stream_seek (GFileInputStream  *stream,
+				   goffset            offset,
+				   GSeekType          type,
+				   GCancellable      *cancellable,
+				   GError           **error)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);
+
+  if (!G_IS_SEEKABLE (file->stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			   _("Input stream doesn't implement seek"));
+      return FALSE;
+    }
+
+  return g_seekable_seek (G_SEEKABLE (file->stream),
+			  offset, type, cancellable, error);
+}
+
+static GFileInfo *
+g_resource_file_input_stream_query_info (GFileInputStream  *stream,
+					 const char        *attributes,
+					 GCancellable      *cancellable,
+					 GError           **error)
+{
+  GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream);
+
+  return g_file_query_info (file->file, attributes, 0, cancellable, error);
+}



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