flexoff.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "flexoff.h"
00015 #include "dataform.h"
00016 #include "disco.h"
00017 #include "error.h"
00018
00019 #include <cstdlib>
00020
00021 namespace gloox
00022 {
00023
00024
00025 FlexibleOffline::Offline::Offline( const Tag* )
00026 : StanzaExtension( ExtFlexOffline )
00027 {
00028
00029 }
00030
00031 FlexibleOffline::Offline::Offline( int context, const StringList& msgs )
00032 : StanzaExtension( ExtFlexOffline ), m_context( context ), m_msgs( msgs )
00033 {
00034 }
00035
00036 FlexibleOffline::Offline::~Offline()
00037 {
00038 }
00039
00040 const std::string& FlexibleOffline::Offline::filterString() const
00041 {
00042 static const std::string filter = "/iq/offline[@xmlns='" + XMLNS_OFFLINE + "']";
00043 return filter;
00044 }
00045
00046 Tag* FlexibleOffline::Offline::tag() const
00047 {
00048 Tag* t = new Tag( "offline" );
00049 t->setXmlns( XMLNS_OFFLINE );
00050
00051 if( m_msgs.empty() )
00052 new Tag( t, m_context == FORequestMsgs ? "fetch" : "purge" );
00053 else
00054 {
00055 const std::string action = m_context == FORequestMsgs ? "view" : "remove";
00056 StringList::const_iterator it = m_msgs.begin();
00057 for( ; it != m_msgs.end(); ++it )
00058 {
00059 Tag* i = new Tag( t, "item", "action", action );
00060 i->addAttribute( "node", (*it) );
00061 }
00062 }
00063 return t;
00064 }
00065
00066
00067
00068 FlexibleOffline::FlexibleOffline( ClientBase* parent )
00069 : m_parent( parent ), m_flexibleOfflineHandler( 0 )
00070 {
00071 if( m_parent )
00072 m_parent->registerStanzaExtension( new Offline() );
00073 }
00074
00075 FlexibleOffline::~FlexibleOffline()
00076 {
00077 if( m_parent )
00078 m_parent->removeIDHandler( this );
00079 }
00080
00081 void FlexibleOffline::checkSupport()
00082 {
00083 m_parent->disco()->getDiscoInfo( m_parent->jid().server(), EmptyString, this, FOCheckSupport );
00084 }
00085
00086 void FlexibleOffline::getMsgCount()
00087 {
00088 m_parent->disco()->getDiscoInfo( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestNum );
00089 }
00090
00091 void FlexibleOffline::fetchHeaders()
00092 {
00093 m_parent->disco()->getDiscoItems( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestHeaders );
00094 }
00095
00096 void FlexibleOffline::messageOperation( int context, const StringList& msgs )
00097 {
00098 const std::string& id = m_parent->getID();
00099 IQ::IqType iqType = context == FORequestMsgs ? IQ::Get : IQ::Set;
00100 IQ iq( iqType, JID(), id );
00101 iq.addExtension( new Offline( context, msgs ) );
00102 m_parent->send( iq, this, context );
00103 }
00104
00105 void FlexibleOffline::registerFlexibleOfflineHandler( FlexibleOfflineHandler* foh )
00106 {
00107 m_flexibleOfflineHandler = foh;
00108 }
00109
00110 void FlexibleOffline::removeFlexibleOfflineHandler()
00111 {
00112 m_flexibleOfflineHandler = 0;
00113 }
00114
00115 void FlexibleOffline::handleDiscoInfo( const JID& , const Disco::Info& info, int context )
00116 {
00117 if( !m_flexibleOfflineHandler )
00118 return;
00119
00120 switch( context )
00121 {
00122 case FOCheckSupport:
00123 m_flexibleOfflineHandler->handleFlexibleOfflineSupport( info.hasFeature( XMLNS_OFFLINE ) );
00124 break;
00125
00126 case FORequestNum:
00127 int num = -1;
00128 if( info.form() && info.form()->hasField( "number_of_messages" ) )
00129 num = atoi( info.form()->field( "number_of_messages" )->value().c_str() );
00130
00131 m_flexibleOfflineHandler->handleFlexibleOfflineMsgNum( num );
00132 break;
00133 }
00134 }
00135
00136 void FlexibleOffline::handleDiscoItems( const JID& , const Disco::Items& items, int context )
00137 {
00138 if( context == FORequestHeaders && m_flexibleOfflineHandler )
00139 {
00140 if( items.node() == XMLNS_OFFLINE )
00141 m_flexibleOfflineHandler->handleFlexibleOfflineMessageHeaders( items.items() );
00142 }
00143 }
00144
00145 void FlexibleOffline::handleDiscoError( const JID& , const Error* , int )
00146 {
00147 }
00148
00149 void FlexibleOffline::handleIqID( const IQ& iq, int context )
00150 {
00151 if( !m_flexibleOfflineHandler )
00152 return;
00153
00154 switch( context )
00155 {
00156 case FORequestMsgs:
00157 switch( iq.subtype() )
00158 {
00159 case IQ::Result:
00160 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRequestSuccess );
00161 break;
00162 case IQ::Error:
00163 switch( iq.error()->error() )
00164 {
00165 case StanzaErrorForbidden:
00166 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
00167 break;
00168 case StanzaErrorItemNotFound:
00169 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
00170 break;
00171 default:
00172 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
00173 break;
00174 }
00175 break;
00176 default:
00177 break;
00178 }
00179 break;
00180 case FORemoveMsgs:
00181 switch( iq.subtype() )
00182 {
00183 case IQ::Result:
00184 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRemoveSuccess );
00185 break;
00186 case IQ::Error:
00187 switch( iq.error()->error() )
00188 {
00189 case StanzaErrorForbidden:
00190 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
00191 break;
00192 case StanzaErrorItemNotFound:
00193 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
00194 break;
00195 default:
00196 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
00197 break;
00198 }
00199 break;
00200 default:
00201 break;
00202 }
00203 break;
00204 }
00205 }
00206
00207 }