/*
    GSK - a library to write servers
    Copyright (C) 1999-2000 Dave Benson

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

    Contact:
        daveb@ffem.org <Dave Benson>
*/

/* GskActorBuffered: an actor with a write buffer and a simple input method.  */

#ifndef __GSK_ACTOR_BUFFERED_H_
#define __GSK_ACTOR_BUFFERED_H_

#include "gskactorstreamsocket.h"
#include "gskbuffer.h"

/* --- type macros --- */
GtkType gsk_actor_buffered_get_type();
#define GSK_TYPE_ACTOR_BUFFERED	             (gsk_actor_buffered_get_type ())
#define GSK_ACTOR_BUFFERED(obj)              (GTK_CHECK_CAST ((obj), GSK_TYPE_ACTOR_BUFFERED, GskActorBuffered))
#define GSK_ACTOR_BUFFERED_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GSK_TYPE_ACTOR_BUFFERED, GskActorBufferedClass))
#define GSK_IS_ACTOR_BUFFERED(obj)           (GTK_CHECK_TYPE ((obj), GSK_TYPE_ACTOR_BUFFERED))
#define GSK_IS_ACTOR_BUFFERED_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GSK_TYPE_ACTOR_BUFFERED))
#define GSK_ACTOR_BUFFERED_GET_CLASS(obj)    (GSK_ACTOR_BUFFERED_CLASS(GTK_OBJECT(obj)->klass))

/* --- structures & typedefs --- */
typedef struct _GskActorBuffered GskActorBuffered;
typedef struct _GskActorBufferedClass GskActorBufferedClass;

struct _GskActorBufferedClass
{
  GskActorStreamSocketClass actor_class;
  gboolean      (*on_input)        (GskActorBuffered* actor,
                                    const void*      data,
                                    int              length);
  gboolean      (*on_write_error)  (GskActorBuffered* actor);

  /*
   * Called when the amount of data in the buffer
   * is less than min_outgoing_data.
   *
   * Returns TRUE if the actor should continue;
   *         FALSE to say "I have nothing more to add-- shutdown
   *                       my end when you are done flushing buffers".
   */
  gboolean      (*on_underflow)     (GskActorBuffered *actor);

  /* Called when the underlying socket is reads end-of-file.  */
  void          (*got_eof)            (GskActorBuffered *actor);
};

struct _GskActorBuffered
{
  GskActorStreamSocket	actor;

  GskBuffer	outgoing_data;

  int		max_outgoing_data;
  int		min_outgoing_data;

  guint		deferred_write_shutdown : 1,

                /* if 1, the on_underflow() function may be called.  */
                ready_to_produce : 1,
                
                /* if 1, we've read 0 bytes, an end-of-file. */
                got_eof : 1;
};

		
/* --- methods --- */
void            gsk_actor_buffered_write       (GskActorBuffered *actor,
                                                const char       *buf,
					        int               len);
void            gsk_actor_buffered_stop_writing(GskActorBuffered *actor);
void            gsk_actor_buffered_stop_reading(GskActorBuffered *actor);
void            gsk_actor_buffered_stop        (GskActorBuffered *actor);

/* --- compatibility macros --- */
#ifndef GSK_DISABLE_COMPAT
#define gsk_actor_buffered_set_socket(actor, socket)		\
	gsk_actor_stream_socket_set_socket 			\
		(GSK_ACTOR_STREAM_SOCKET (actor), (socket))
#define defered_write_shutdown deferred_write_shutdown
#endif

#endif
