[glib/resources] Return a proper GFileInputStream from GResourceFile open
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/resources] Return a proper GFileInputStream from GResourceFile open
- Date: Thu, 22 Dec 2011 12:38:58 +0000 (UTC)
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]