inbandbytestream.cpp

00001 /*
00002   Copyright (c) 2006 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "inbandbytestream.h"
00015 #include "inbandbytestreamdatahandler.h"
00016 #include "messagesession.h"
00017 #include "disco.h"
00018 #include "clientbase.h"
00019 #include "base64.h"
00020 
00021 #include <sstream>
00022 
00023 namespace gloox
00024 {
00025 
00026   InBandBytestream::InBandBytestream( MessageSession *session, ClientBase *clientbase )
00027     : MessageFilter( session ), m_clientbase( clientbase ),
00028       m_inbandBytestreamDataHandler( 0 ), m_blockSize( 4096 ), m_sequence( -1 ),
00029       m_lastChunkReceived( -1 ), m_open( true )
00030   {
00031   }
00032 
00033   InBandBytestream::~InBandBytestream()
00034   {
00035     if( m_open )
00036       close();
00037 
00038     if( m_parent )
00039       m_parent->removeMessageFilter( this );
00040   }
00041 
00042   void InBandBytestream::decorate( Tag * /*tag*/ )
00043   {
00044   }
00045 
00046   void InBandBytestream::filter( Stanza *stanza )
00047   {
00048     if( !m_inbandBytestreamDataHandler || !m_open )
00049       return;
00050 
00051     if( stanza->subtype() == StanzaMessageError )
00052     {
00053       m_inbandBytestreamDataHandler->handleInBandError( m_sid, stanza->from(), stanza->error() );
00054       m_open = false;
00055     }
00056 
00057     Tag *data = 0;
00058     if( ( data = stanza->findChild( "data", "xmlns", XMLNS_IBB ) ) == 0 )
00059       return;
00060 
00061     const std::string sid = data->findAttribute( "sid" );
00062     if( sid.empty() || sid != m_sid )
00063       return;
00064 
00065     const std::string seq = data->findAttribute( "seq" );
00066     if( seq.empty() )
00067     {
00068       m_open = false;
00069       return;
00070     }
00071 
00072     std::stringstream str;
00073     int sequence = 0;
00074     str << seq;
00075     str >> sequence;
00076 
00077     if( m_lastChunkReceived + 1 != sequence )
00078     {
00079       m_open = false;
00080       return;
00081     }
00082     m_lastChunkReceived = sequence;
00083 
00084     if( !data->cdata().length() )
00085     {
00086       m_open = false;
00087       return;
00088     }
00089 
00090     m_inbandBytestreamDataHandler->handleInBandData( Base64::decode64( data->cdata() ), sid );
00091   }
00092 
00093   bool InBandBytestream::sendBlock( const std::string& data )
00094   {
00095     if( !m_open || !m_parent || !m_clientbase || data.length() > m_blockSize )
00096       return false;
00097 
00098     Tag *m = new Tag( "message" );
00099     m->addAttribute( "to", m_parent->target().full() );
00100     m->addAttribute( "id", m_clientbase->getID() );
00101     Tag *d = new Tag( m, "data", Base64::encode64( data ) );
00102     d->addAttribute( "sid", m_sid );
00103     d->addAttribute( "seq", ++m_sequence );
00104     d->addAttribute( "xmlns", XMLNS_IBB );
00105 
00106     // FIXME: hard-coded AMP
00107     Tag *a = new Tag( m, "amp" );
00108     a->addAttribute( "xmlns", XMLNS_AMP );
00109     Tag *r = new Tag( a, "rule" );
00110     r->addAttribute( "condition", "deliver-at" );
00111     r->addAttribute( "value", "stored" );
00112     r->addAttribute( "action", "error" );
00113     r = new Tag( a, "rule" );
00114     r->addAttribute( "condition", "match-resource" );
00115     r->addAttribute( "value", "exact" );
00116     r->addAttribute( "action", "error" );
00117 
00118     m_clientbase->send( m );
00119     return true;
00120   }
00121 
00122   void InBandBytestream::closed()
00123   {
00124     if( m_inbandBytestreamDataHandler )
00125       m_inbandBytestreamDataHandler->handleInBandClose( m_sid, m_parent->target() );
00126 
00127     m_open = false;
00128 
00129     if( !m_parent )
00130       return;
00131   }
00132 
00133   void InBandBytestream::close()
00134   {
00135     m_open = false;
00136 
00137     if( !m_parent )
00138       return;
00139 
00140     const std::string id = m_clientbase->getID();
00141     Tag *iq = new Tag( "iq" );
00142     iq->addAttribute( "type", "set" );
00143     iq->addAttribute( "to", m_parent->target().full() );
00144     iq->addAttribute( "id", id );
00145     Tag *c = new Tag( iq, "close" );
00146     c->addAttribute( "sid", m_sid );
00147     c->addAttribute( "xmlns", XMLNS_IBB );
00148 
00149     m_clientbase->send( iq );
00150   }
00151 
00152   void InBandBytestream::registerInBandBytestreamDataHandler( InBandBytestreamDataHandler *ibbdh )
00153   {
00154     m_inbandBytestreamDataHandler = ibbdh;
00155   }
00156 
00157   void InBandBytestream::removeInBandBytestreamDataHandler()
00158   {
00159     m_inbandBytestreamDataHandler = 0;
00160   }
00161 
00162 }

Generated on Tue May 1 14:20:20 2007 for gloox by  doxygen 1.5.1