14 #include "inbandbytestream.h"
16 #include "bytestreamdatahandler.h"
18 #include "clientbase.h"
29 static const char* typeValues[] =
31 "open",
"data",
"close"
35 : StanzaExtension(
ExtIBB ), m_sid ( sid ), m_seq( 0 ), m_blockSize( blocksize ),
41 : StanzaExtension(
ExtIBB ), m_sid ( sid ), m_seq( seq ), m_blockSize( 0 ),
42 m_data( data ), m_type( IBBData )
47 : StanzaExtension(
ExtIBB ), m_sid ( sid ), m_seq( 0 ), m_blockSize( 0 ),
53 : StanzaExtension(
ExtIBB ), m_type( IBBInvalid )
58 m_type = (IBBType)util::lookup( tag->name(), typeValues );
59 m_blockSize = atoi( tag->findAttribute(
"block-size" ).c_str() );
60 m_seq = atoi( tag->findAttribute(
"seq" ).c_str() );
61 m_sid = tag->findAttribute(
"sid" );
65 InBandBytestream::IBB::~IBB()
69 const std::string& InBandBytestream::IBB::filterString()
const
71 static const std::string filter =
"/iq/open[@xmlns='" +
XMLNS_IBB +
"']"
73 "|/message/data[@xmlns='" +
XMLNS_IBB +
"']"
78 Tag* InBandBytestream::IBB::tag()
const
80 if( m_type == IBBInvalid )
83 Tag* t =
new Tag( util::lookup( m_type, typeValues ) );
85 t->addAttribute(
"sid", m_sid );
86 if( m_type == IBBData )
89 t->addAttribute(
"seq", m_seq );
91 else if( m_type == IBBOpen )
92 t->addAttribute(
"block-size", m_blockSize );
99 InBandBytestream::InBandBytestream( ClientBase* clientbase, LogSink& logInstance,
const JID& initiator,
100 const JID& target,
const std::string& sid )
101 : Bytestream( Bytestream::IBB, logInstance, initiator, target, sid ),
102 m_clientbase( clientbase ), m_blockSize( 4096 ), m_sequence( -1 ), m_lastChunkReceived( -1 )
106 m_clientbase->registerStanzaExtension(
new IBB() );
107 m_clientbase->registerIqHandler(
this,
ExtIBB );
108 m_clientbase->registerMessageHandler(
this );
135 const std::string&
id = m_clientbase->
getID();
138 m_clientbase->
send( iq,
this, IBBOpen );
169 if( i->type() == IBBOpen )
171 returnResult( iq.
from(), iq.
id() );
179 if( i->type() == IBBClose )
181 returnResult( iq.
from(), iq.
id() );
186 if( ( m_lastChunkReceived + 1 ) != i->seq() )
193 if( i->data().empty() )
200 returnResult( iq.
from(), iq.
id() );
202 m_lastChunkReceived++;
218 if( m_lastChunkReceived != i->seq() )
224 if( i->data().empty() )
231 m_lastChunkReceived++;
234 void InBandBytestream::returnResult(
const JID& to,
const std::string&
id )
237 m_clientbase->
send( iq );
243 iq.addExtension(
new Error( type, error ) );
244 m_clientbase->
send( iq );
249 if( !
m_open || !m_clientbase )
253 size_t len = data.length();
256 const std::string&
id = m_clientbase->
getID();
258 iq.
addExtension(
new IBB( m_sid, ++m_sequence, data.substr( pos, m_blockSize ) ) );
259 m_clientbase->
send( iq,
this, IBBData );
262 if( m_sequence == 65535 )
270 void InBandBytestream::closed()
288 const std::string&
id = m_clientbase->
getID();
291 m_clientbase->
send( iq,
this, IBBClose );