You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
6.3 KiB
238 lines
6.3 KiB
/*
|
|
Kopete Yahoo Protocol
|
|
|
|
Copyright (c) 2004 Duncan Mac-Vicar P. <duncan@kde.org>
|
|
|
|
Based on code
|
|
Copyright (c) 2004 SuSE Linux AG <http://www.suse.com>
|
|
Copyright (C) 2003 Justin Karneges <justin@affinix.com>
|
|
|
|
Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
|
|
|
|
*************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
*************************************************************************
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <iostream>
|
|
|
|
#include <tqdatastream.h>
|
|
#include <tqdatetime.h>
|
|
#include <tqtextstream.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <kurl.h>
|
|
|
|
#include "coreprotocol.h"
|
|
#include "ymsgprotocol.h"
|
|
#include "ymsgtransfer.h"
|
|
|
|
CoreProtocol::CoreProtocol() : TQObject()
|
|
{
|
|
m_YMSGProtocol = new YMSGProtocol( this, "ymsgprotocol" );
|
|
}
|
|
|
|
CoreProtocol::~CoreProtocol()
|
|
{
|
|
}
|
|
|
|
int CoreProtocol::state()
|
|
{
|
|
return m_state;
|
|
}
|
|
|
|
void CoreProtocol::addIncomingData( const TQByteArray & incomingBytes )
|
|
{
|
|
// store locally
|
|
int oldsize = m_in.size();
|
|
kdDebug(YAHOO_RAW_DEBUG) << incomingBytes.size() << " bytes. already had " << oldsize << " bytes" << endl;
|
|
|
|
m_in.resize( oldsize + incomingBytes.size() );
|
|
memcpy( m_in.data() + oldsize, incomingBytes.data(), incomingBytes.size() );
|
|
|
|
m_state = Available;
|
|
// convert every event in the chunk to a Transfer, signalling it back to the clientstream
|
|
|
|
int parsedBytes = 0;
|
|
int transferCount = 0;
|
|
// while there is data left in the input buffer, and we are able to parse something out of it
|
|
|
|
while ( m_in.size() && ( parsedBytes = wireToTransfer(m_in) ) )
|
|
{
|
|
transferCount++;
|
|
kdDebug(YAHOO_RAW_DEBUG) << " parsed transfer " << transferCount << " in chunk of "<< parsedBytes << " bytes" << endl;
|
|
int size = m_in.size();
|
|
if ( parsedBytes < size )
|
|
{
|
|
kdDebug(YAHOO_RAW_DEBUG) << " more data in chunk! ( I have parsed " << parsedBytes << " and total data of " << size << ")" << endl;
|
|
// remove parsed bytes from the buffer
|
|
//m_in.remove( 0, parsedBytes );
|
|
|
|
// copy the unparsed bytes into a new qbytearray and replace m_in with that
|
|
TQByteArray remainder( size - parsedBytes );
|
|
memcpy( remainder.data(), m_in.data() + parsedBytes, remainder.size() );
|
|
m_in = remainder;
|
|
}
|
|
else
|
|
m_in.truncate( 0 );
|
|
}
|
|
if ( m_state == NeedMore )
|
|
kdDebug(YAHOO_RAW_DEBUG) << " message was incomplete, waiting for more..." << endl;
|
|
/*
|
|
if ( m_eventProtocol->state() == EventProtocol::OutOfSync )
|
|
{
|
|
tqDebug( " - protocol thinks it's out of sync, discarding the rest of the buffer and hoping the server regains sync soon..." );
|
|
m_in.truncate( 0 );
|
|
}
|
|
*/
|
|
kdDebug(YAHOO_RAW_DEBUG) << " done processing chunk" << endl;
|
|
|
|
}
|
|
|
|
Transfer* CoreProtocol::incomingTransfer()
|
|
{
|
|
kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
|
|
if ( m_state == Available )
|
|
{
|
|
// kdDebug(YAHOO_RAW_DEBUG) << " - got a transfer";
|
|
m_state = NoData;
|
|
return m_inTransfer;
|
|
m_inTransfer = 0;
|
|
}
|
|
else
|
|
{
|
|
kdDebug(YAHOO_RAW_DEBUG) << " no milk today" << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void cp_dump( const TQByteArray &bytes )
|
|
{
|
|
#ifdef YAHOO_COREPROTOCOL_DEBUG
|
|
kdDebug(YAHOO_RAW_DEBUG) << " contains " << bytes.count() << " bytes" << endl;
|
|
for ( uint i = 0; i < bytes.count(); ++i )
|
|
{
|
|
printf( "%02x ", bytes[ i ] );
|
|
}
|
|
printf( "\n" );
|
|
#else
|
|
Q_UNUSED( bytes );
|
|
#endif
|
|
}
|
|
|
|
void CoreProtocol::outgoingTransfer( Transfer* outgoing )
|
|
{
|
|
kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
|
|
if ( outgoing->type() == Transfer::YMSGTransfer )
|
|
{
|
|
kdDebug(YAHOO_RAW_DEBUG) << " got YMSGTransfer" << endl;
|
|
YMSGTransfer *yt = (YMSGTransfer *) outgoing;
|
|
TQByteArray bytesOut = yt->serialize();
|
|
|
|
//TQTextStream dout( bytesOut, TQIODevice::WriteOnly );
|
|
//dout.setEncoding( TQTextStream::Latin1 );
|
|
//dout.setByteOrder( TQDataStream::LittleEndian );
|
|
//dout << bytesOut;
|
|
//kdDebug(YAHOO_RAW_DEBUG) << " " << bytesOut;
|
|
emit outgoingData( bytesOut );
|
|
// now convert
|
|
//fieldsToWire( fields );
|
|
}
|
|
delete outgoing;
|
|
}
|
|
|
|
|
|
|
|
int CoreProtocol::wireToTransfer( const TQByteArray& wire )
|
|
{
|
|
kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
|
|
// processing incoming data and reassembling it into transfers
|
|
// may be an event or a response
|
|
|
|
uint bytesParsed = 0;
|
|
|
|
if ( wire.size() < 20 ) // minimal value of a YMSG header
|
|
{
|
|
m_state = NeedMore;
|
|
return bytesParsed;
|
|
}
|
|
|
|
TQByteArray tempWire = wire;
|
|
TQDataStream din( tempWire, IO_ReadOnly );
|
|
|
|
// look at first four bytes and decide what to do with the chunk
|
|
if ( okToProceed( din ) )
|
|
{
|
|
if ( (wire[0] == 'Y') && (wire[1] == 'M') && (wire[2] == 'S') && (wire[3] == 'G'))
|
|
{
|
|
// kdDebug(YAHOO_RAW_DEBUG) << " - looks like a valid YMSG packet";
|
|
YMSGTransfer *t = static_cast<YMSGTransfer *>(m_YMSGProtocol->parse( wire, bytesParsed ));
|
|
// kdDebug(YAHOO_RAW_DEBUG) << " - YMSG Protocol parsed " << bytesParsed << " bytes";
|
|
if ( t )
|
|
{
|
|
if( wire.size() < t->packetLength() )
|
|
{
|
|
m_state = NeedMore;
|
|
delete t;
|
|
return 0;
|
|
}
|
|
m_inTransfer = t;
|
|
// kdDebug(YAHOO_RAW_DEBUG) << " - got a valid packet ";
|
|
|
|
m_state = Available;
|
|
emit incomingData();
|
|
}
|
|
else
|
|
bytesParsed = 0;
|
|
}
|
|
else
|
|
{
|
|
kdDebug(YAHOO_RAW_DEBUG) << " - not a valid YMSG packet. Trying to recover." << endl;
|
|
TQTextStream s( wire, IO_ReadOnly );
|
|
TQString remaining = s.read();
|
|
int pos = remaining.find( "YMSG", bytesParsed );
|
|
if( pos >= 0 )
|
|
{
|
|
kdDebug(YAHOO_RAW_DEBUG) << "Recover successful." << endl;
|
|
bytesParsed += pos;
|
|
}
|
|
else
|
|
{
|
|
kdDebug(YAHOO_RAW_DEBUG) << "Recover failed. Dump it!" << endl;
|
|
bytesParsed = wire.size();
|
|
}
|
|
}
|
|
}
|
|
return bytesParsed;
|
|
}
|
|
|
|
void CoreProtocol::reset()
|
|
{
|
|
m_in.resize( 0 );
|
|
}
|
|
|
|
void CoreProtocol::slotOutgoingData( const TQByteArray &out )
|
|
{
|
|
tqDebug( "%s", out.data() );
|
|
}
|
|
|
|
bool CoreProtocol::okToProceed( TQDataStream &din)
|
|
{
|
|
if ( din.atEnd() )
|
|
{
|
|
m_state = NeedMore;
|
|
kdDebug(YAHOO_RAW_DEBUG) << " saved message prematurely" << endl;
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
#include "coreprotocol.moc"
|