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

Reply via email to