/*****
 NAME
 	casyncserver.m - source code for CAsyncServer
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#include <coconut/gnet/casyncserver.h>
#include <coconut/cerror.h>
#include <coconut/cmessage.h>
#include <coconut/ceventsystem.h>

static void gnet_async_accept(GTcpSocket * server, GTcpSocket * client,
  gpointer data) ;

@implementation CAsyncServer

- init
{
	return [super init] ;
}

- (void) dealloc
{
	[self close] ;
	[super dealloc] ;
}

- (id <PError>) openToRead: (int) portnum output: (id <PStream>) output
{
	GTcpSocket *			serversock ;

	serversock = gnet_tcp_socket_server_new(portnum) ;
	if(serversock == NULL)
		return [CError can_not_open] ;
	[super setStream: nil and: output] ;
	gnet_tcp_socket_server_accept_async(serversock, 
	  &gnet_async_accept, self);
	return nil ;
}

- (id <PError>) openToWrite: (int) portnum input: (id <PStream>) input 
{
	GTcpSocket *			serversock ;
	serversock = gnet_tcp_socket_server_new(portnum) ;
	if(serversock == NULL)
		return [CError can_not_open] ;
	[super setStream: input and: nil] ;
	gnet_tcp_socket_server_accept_async(serversock, 
	  &gnet_async_accept, self);
	return nil ;
}

- (id <PError>) close
{
	return [super closeChannel] ;
}

- (boolean) isServer
{
	return TRUE ;
}

- (void) asyncConnect: (GTcpSocket *) server client: (GTcpSocket *) client
{
	guint		mask ;
	GIOChannel *	clientchan ;

	/* g_message("server: asyncConnect\n") ; */
	clientchan = gnet_tcp_socket_get_iochannel(client) ;
	g_assert(clientchan != NULL) ;

	[CEventSystem retainMainLoop] ;
	mask = G_IO_ERR | G_IO_HUP | G_IO_NVAL ;
	if(input_stream) mask |= G_IO_OUT ;
	if(output_stream) mask |= G_IO_IN ;
	g_io_add_watch(clientchan, mask, &gnet_async_io, self) ;
}

@end

static void gnet_async_accept(GTcpSocket * server, GTcpSocket * client,
  gpointer data)
{
	CAsyncServer *	obj = (CAsyncServer *) data ;
	[obj asyncConnect: server client: client] ;
}

