On Sun, 2006-09-24 at 14:33 +0200, Philip Van Hoof wrote: > > Here is my current GInputStream: > > > > struct _GInputStreamClass > > { > > GObjectClass parent_class; > > Using GTypeInterfaceClass here would make it much more easy to let > library and application developers implement the GInputStream interface > in a for-their needs suitable way.
Also look at these prior art thingies: http://tinymail.org/API/libtinymail-1.0/libtinymail-tny-stream.html http://pvanhoof.be/files/libcamel-api/html/CamelStream.html http://pvanhoof.be/files/libcamel-api/html/CamelSeekableStream.html I know this API proposal MIGHT sound more complex. In reality, it most certainly isn't. Just try it out. Fiddle around with it. Or see how I in tinymail (and notzed and fejj in Camel) used something like this. #ifndef _G_INPUT_STREAM_H #define _G_INPUT_STREAM_H #include <glib.h> #include <glib-object.h> G_BEGIN_DECLS typedef struct _GInputStream GInputStream; typedef struct _GInputStreamIface GInputStreamIface; #define G_TYPE_INPUT_STREAM (g_input_stream_get_type ()) #define G_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_INPUT_STREAM, GInputStream)) #define G_IS_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_INPUT_STREAM)) #define G_INPUT_STREAM_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_INPUT_STREAM, TnyDeviceIface)) struct _GInputStreamIface { GTypeInterface parent_iface; /* Sync ops: */ gssize (* read) (GInputStream *stream, void *buffer, gsize count, GError **error); gssize (* skip) (GInputStream *stream, gsize count, GError **error); gboolean (* close) (GInputStream *stream, GError **error); /* Async ops: (optional in derived classes) */ guint (* read_async) (GInputStream *stream, void *buffer, gsize count, int io_priority, GMainContext *context, GAsyncReadCallback callback, gpointer data, GDestroyNotify notify); guint (* close_async) (GInputStream *stream, GMainContext *context, GAsyncCloseCallback callback, gpointer data, GDestroyNotify notify); void (* cancel) (GInputStream *stream, guint tag); } GType g_input_stream_get_type (void); gssize g_input_stream_read (GInputStream *stream, void *buffer, gsize count, GError **error); gssize g_input_stream_skip (GInputStream *stream, gsize count, GError **error); gboolean g_input_stream_close (GInputStream *stream, GError **error); guint g_input_stream_read_async (GInputStream *stream, void *buffer, gsize count, int io_priority, GMainContext *context, GAsyncReadCallback callback, gpointer data, GDestroyNotify notify); guint g_input_stream_close_async (GInputStream *stream, GMainContext *context, GAsyncCloseCallback callback, gpointer data, GDestroyNotify notify); void g_input_stream_cancel (GInputStream *stream, guint tag); G_END_DECLS #endif #ifndef _G_SEEKABLE_H #define _G_SEEKABLE_H #include <glib.h> #include <glib-object.h> G_BEGIN_DECLS typedef struct _GSeekable GSeekable; typedef struct _GSeekableIface GSeekableIface; #define G_TYPE_SEEKABLE (g_seekable_get_type ()) #define G_SEEKABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SEEKABLE, GSeekable)) #define G_IS_SEEKABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SEEKABLE)) #define G_SEEKABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_SEEKABLE, TnyDeviceIface)) struct _GSeekableIface { GTypeInterface parent_iface; off_t (*seek) (GSeekable *self, off_t offset, GSeekPolicy policy); off_t (*tell) (GSeekable *stream); } GType g_seekable_get_type (void); off_t g_seekable_seek (GSeekable *self, off_t offset, GSeekPolicy policy); off_t g_seekable_tell (GSeekable *stream); G_END_DECLS #endif GType g_fs_stream_get_type (void) { static GType type = 0; if (G_UNLIKELY(type == 0)) { static const GTypeInfo info = { sizeof (GFsStreamClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) g_fs_stream_class_init, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GFsStream), 0, /* n_preallocs */ g_fs_stream_instance_init, /* instance_init */ NULL }; static const GInterfaceInfo g_stream_info = { (GInterfaceInitFunc) g_stream_init, /* interface_init */ NULL, /* interface_finalize */ NULL /* interface_data */ }; static const GInterfaceInfo g_seekable_info = { (GInterfaceInitFunc) g_seekable_init, /* interface_init */ NULL, /* interface_finalize */ NULL /* interface_data */ }; type = g_type_register_static (G_TYPE_OBJECT, "GFsStream", &info, 0); g_type_add_interface_static (type, G_TYPE_STREAM, &tny_stream_info); g_type_add_interface_static (type, G_TYPE_SEEKABLE, &tny_seekable_info); } return type; } -- Philip Van Hoof, software developer at x-tend home: me at pvanhoof dot be gnome: pvanhoof at gnome dot org work: vanhoof at x-tend dot be http://www.pvanhoof.be - http://www.x-tend.be _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list