00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "capabilities.h"
00015
00016 #include "base64.h"
00017 #include "disco.h"
00018 #include "sha.h"
00019 #include "tag.h"
00020
00021 namespace gloox
00022 {
00023
00024 Capabilities::Capabilities( Disco* disco )
00025 : StanzaExtension( ExtCaps ), m_disco( disco ), m_node( GLOOX_CAPS_NODE ), m_valid( false )
00026 {
00027 if( m_disco )
00028 m_valid = true;
00029 }
00030
00031 Capabilities::Capabilities( const Tag* tag )
00032 : StanzaExtension( ExtCaps ), m_disco( 0 ), m_valid( false )
00033 {
00034 if( !tag || tag->name() != "c" || !tag->hasAttribute( XMLNS, XMLNS_CAPS )
00035 || !tag->hasAttribute( "node" ) || !tag->hasAttribute( "ver" ) )
00036 return;
00037
00038 m_node = tag->findAttribute( "node" );
00039 m_ver = tag->findAttribute( "ver" );
00040 m_valid = true;
00041 }
00042
00043 Capabilities::~Capabilities()
00044 {
00045 if( m_disco )
00046 m_disco->removeNodeHandlers( const_cast<Capabilities*>( this ) );
00047 }
00048
00049 const std::string Capabilities::ver() const
00050 {
00051 if( !m_disco )
00052 return m_ver;
00053
00054 StringList sl;
00055 const Disco::IdentityList& il = m_disco->identities();
00056 Disco::IdentityList::const_iterator it = il.begin();
00057 for( ; it != il.end(); ++it )
00058 sl.push_back( (*it)->category() + '/' + (*it)->type() );
00059 sl.sort();
00060
00061 std::string s;
00062 StringList::const_iterator it2 = sl.begin();
00063 for( ; it2 != sl.end(); ++it2 )
00064 {
00065 s += (*it2);
00066 s += '<';
00067 }
00068
00069 StringList f = m_disco->features();
00070 f.sort();
00071 it2 = f.begin();
00072 for( ; it2 != f.end(); ++it2 )
00073 {
00074 s += (*it2);
00075 s += '<';
00076 }
00077 SHA sha;
00078 sha.feed( s );
00079 const std::string& hash = Base64::encode64( sha.binary() );
00080 m_disco->registerNodeHandler( const_cast<Capabilities*>( this ), m_node + '#' + hash );
00081 return hash;
00082 }
00083
00084 const std::string& Capabilities::filterString() const
00085 {
00086 static const std::string filter = "/presence/c[@xmlns='" + XMLNS_CAPS + "']";
00087 return filter;
00088 }
00089
00090 Tag* Capabilities::tag() const
00091 {
00092 if( !m_valid || m_node.empty() )
00093 return 0;
00094
00095 Tag* t = new Tag( "c" );
00096 t->setXmlns( XMLNS_CAPS );
00097 t->addAttribute( "hash", "sha-1" );
00098 t->addAttribute( "node", m_node );
00099 t->addAttribute( "ver", ver() );
00100 return t;
00101 }
00102
00103 StringList Capabilities::handleDiscoNodeFeatures( const JID&, const std::string& )
00104 {
00105 return m_disco->features();
00106 }
00107
00108 Disco::IdentityList Capabilities::handleDiscoNodeIdentities( const JID&, const std::string& )
00109 {
00110 const Disco::IdentityList& il = m_disco->identities();
00111 Disco::IdentityList ret;
00112 Disco::IdentityList::const_iterator it = il.begin();
00113 for( ; it != il.end(); ++it )
00114 {
00115 ret.push_back( new Disco::Identity( *(*it) ) );
00116 }
00117 return ret;
00118 }
00119
00120 Disco::ItemList Capabilities::handleDiscoNodeItems( const JID&, const std::string& )
00121 {
00122 return Disco::ItemList();
00123 }
00124
00125 }