
/***************************************************************************
                   gwbytestream.cpp  -  Byte Stream using KNetwork sockets
                             -------------------
    begin                : Wed Jul 7 2004
    copyright            : (C) 2004 by Till Gerken <till@tantalo.net>

			   Kopete (C) 2004 Kopete developers <kopete-devel@kde.org>
 ***************************************************************************/

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

#include <tqobject.h>
#include <kbufferedsocket.h>
#include <kdebug.h>
#include <kresolver.h>

#include "oscarbytestream.h"

KNetworkByteStream::KNetworkByteStream( TQObject *parent, const char */*name*/ )
 : ByteStream ( parent )
{
	kdDebug( 14151 ) << k_funcinfo << "Instantiating new KNetwork byte stream." << endl;

	// reset close tracking flag
	mClosing = false;

	mSocket = new KNetwork::TDEBufferedSocket;

	// make sure we get a signal whenever there's data to be read
	mSocket->enableRead( true );

	// connect signals and slots
	TQObject::connect( mSocket, TQ_SIGNAL ( gotError ( int ) ), this, TQ_SLOT ( slotError ( int ) ) );
	TQObject::connect( mSocket, TQ_SIGNAL ( connected ( const KResolverEntry& ) ), this, TQ_SLOT ( slotConnected () ) );
	TQObject::connect( mSocket, TQ_SIGNAL ( closed () ), this, TQ_SLOT ( slotConnectionClosed () ) );
	TQObject::connect( mSocket, TQ_SIGNAL ( readyRead () ), this, TQ_SLOT ( slotReadyRead () ) );
	TQObject::connect( mSocket, TQ_SIGNAL ( bytesWritten ( int ) ), this, TQ_SLOT ( slotBytesWritten ( int ) ) );
}

bool KNetworkByteStream::connect( TQString host, TQString service )
{
	kdDebug( 14151 ) << k_funcinfo << "Connecting to " << host << ", service " << service << endl;

	return socket()->connect( host, service );
}

bool KNetworkByteStream::isOpen() const
{
	// determine if socket is open
	return socket()->isOpen();
}

void KNetworkByteStream::close ()
{
#ifdef OSCAR_EXCESSIVE_DEBUG
	kdDebug ( 14151 ) << k_funcinfo << "Closing stream." << endl;
#endif
	// close the socket and set flag that we are closing it ourselves
	mClosing = true;
	socket()->close();
}

int KNetworkByteStream::tryWrite ()
{
	// send all data from the buffers to the socket
	TQByteArray writeData = takeWrite();
#ifdef OSCAR_EXCESSIVE_DEBUG
	kdDebug(14151) << k_funcinfo << "writing " << writeData.size() << " bytes." << endl;
#endif
	socket()->writeBlock( writeData.data (), writeData.size () );
	return writeData.size();
}

KNetwork::TDEBufferedSocket *KNetworkByteStream::socket() const
{
	return mSocket;
}

KNetworkByteStream::~KNetworkByteStream()
{
	delete mSocket;
}

void KNetworkByteStream::slotConnected()
{
	emit connected();
}

void KNetworkByteStream::slotConnectionClosed()
{
	kdDebug( 14151 ) << k_funcinfo << "Socket has been closed." << endl;

	// depending on who closed the socket, emit different signals
	if ( mClosing )
	{
		kdDebug( 14151 ) << "..by ourselves!" << endl;
		kdDebug( 14151 ) << "socket error is " << socket()->TDESocketBase::errorString( socket()->error() ) << endl;
		emit connectionClosed ();
	}
	else
	{
		kdDebug( 14151 ) << "..by the other end" << endl;
		emit delayedCloseFinished ();
	}
}

void KNetworkByteStream::slotReadyRead()
{
	// stuff all available data into our buffers
	TQByteArray readBuffer( socket()->bytesAvailable () );

	socket()->readBlock( readBuffer.data (), readBuffer.size () );

	appendRead( readBuffer );

	emit readyRead();
}

void KNetworkByteStream::slotBytesWritten( int bytes )
{
	emit bytesWritten( bytes );
}

void KNetworkByteStream::slotError( int code )
{
	kdDebug( 14151 ) << k_funcinfo << "Socket error " << code << endl;

	emit error( code );
}

#include "oscarbytestream.moc"
