From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/JabberG/jabber_xml.cpp | 552 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 552 insertions(+) create mode 100644 protocols/JabberG/jabber_xml.cpp (limited to 'protocols/JabberG/jabber_xml.cpp') diff --git a/protocols/JabberG/jabber_xml.cpp b/protocols/JabberG/jabber_xml.cpp new file mode 100644 index 0000000000..33a5ddad21 --- /dev/null +++ b/protocols/JabberG/jabber_xml.cpp @@ -0,0 +1,552 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Copyright ( C ) 2002-04 Santithorn Bunchua +Copyright ( C ) 2005-11 George Hazan +Copyright ( C ) 2007 Maxim Mluhov + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or ( at your option ) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Revision : $Revision: 13452 $ +Last change on : $Date: 2011-03-17 21:12:56 +0200 (Чт, 17 мар 2011) $ +Last change by : $Author: george.hazan $ + +*/ + +#include "jabber.h" + +#define TAG_MAX_LEN 128 +#define ATTR_MAX_LEN 8192 + +#if defined( _UNICODE ) + #define T2UTF(A) A +#else + +struct T2UTF +{ + T2UTF( const TCHAR* str ) : + m_text( mir_utf8encodeT( str )) + {} + + ~T2UTF() + { mir_free( m_text ); + } + + __inline operator TCHAR*() const + { return m_text; + } + +private: + TCHAR* m_text; +}; + +#endif + +///////////////////////////////////////////////////////////////////////////////////////// +// XmlNodeIq class members + +XmlNodeIq::XmlNodeIq( const TCHAR* type, int id, LPCTSTR to ) : + XmlNode( _T( "iq" )) +{ + if ( type != NULL ) *this << XATTR( _T("type"), type ); + if ( to != NULL ) *this << XATTR( _T("to"), to ); + if ( id != -1 ) *this << XATTRID( id ); +} + +XmlNodeIq::XmlNodeIq( const TCHAR* type, LPCTSTR idStr, LPCTSTR to ) : + XmlNode( _T( "iq" )) +{ + if ( type != NULL ) *this << XATTR( _T("type"), type ); + if ( to != NULL ) *this << XATTR( _T("to"), to ); + if ( idStr != NULL ) *this << XATTR( _T("id"), idStr ); +} + +XmlNodeIq::XmlNodeIq( const TCHAR* type, HXML node, LPCTSTR to ) : + XmlNode( _T( "iq" )) +{ + if ( type != NULL ) *this << XATTR( _T("type"), type ); + if ( to != NULL ) *this << XATTR( _T("to"), to ); + if ( node != NULL ) { + const TCHAR *iqId = xmlGetAttrValue( *this, _T( "id" )); + if ( iqId != NULL ) *this << XATTR( _T("id"), iqId ); + } +} + +XmlNodeIq::XmlNodeIq( CJabberIqInfo* pInfo ) : + XmlNode( _T( "iq" )) +{ + if ( pInfo ) { + if ( pInfo->GetCharIqType() != NULL ) *this << XATTR( _T("type"), _A2T(pInfo->GetCharIqType())); + if ( pInfo->GetReceiver() != NULL ) *this << XATTR( _T("to"), pInfo->GetReceiver() ); + if ( pInfo->GetIqId() != -1 ) *this << XATTRID( pInfo->GetIqId() ); + } +} + +XmlNodeIq::XmlNodeIq( const TCHAR* type, CJabberIqInfo* pInfo ) : + XmlNode( _T( "iq" )) +{ + if ( type != NULL ) *this << XATTR( _T("type"), type ); + if ( pInfo ) { + if ( pInfo->GetFrom() != NULL ) *this << XATTR( _T("to"), pInfo->GetFrom() ); + if ( pInfo->GetIdStr() != NULL ) *this << XATTR( _T("id"), pInfo->GetIdStr() ); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// XmlNode class members + +XmlNode::XmlNode( LPCTSTR pszName ) +{ + m_hXml = xi.createNode( T2UTF(pszName), NULL, 0 ); +} + +XmlNode::XmlNode( LPCTSTR pszName, LPCTSTR ptszText ) +{ + m_hXml = xi.createNode( T2UTF(pszName), ptszText, 0 ); +} + +XmlNode::XmlNode( const XmlNode& n ) +{ + m_hXml = xi.copyNode( n ); +} + +XmlNode& XmlNode::operator =( const XmlNode& n ) +{ + if ( m_hXml ) + xi.destroyNode( m_hXml ); + m_hXml = xi.copyNode( n ); + return *this; +} + +XmlNode::~XmlNode() +{ + if ( m_hXml ) { + xi.destroyNode( m_hXml ); + m_hXml = NULL; +} } + +///////////////////////////////////////////////////////////////////////////////////////// + +HXML __fastcall operator<<( HXML node, const XCHILDNS& child ) +{ + HXML res = xmlAddChild( node, child.name ); + xmlAddAttr( res, _T("xmlns"), child.ns ); + return res; +} + +HXML __fastcall operator<<( HXML node, const XQUERY& child ) +{ + HXML n = xmlAddChild( node, _T("query")); + if ( n ) + xmlAddAttr( n, _T("xmlns"), child.ns ); + return n; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void __fastcall xmlAddAttr( HXML hXml, LPCTSTR name, LPCTSTR value ) +{ + if ( value ) + xi.addAttr( hXml, name, T2UTF(value)); +} + +void __fastcall xmlAddAttr( HXML hXml, LPCTSTR pszName, int value ) +{ + xi.addAttrInt( hXml, T2UTF(pszName), value ); +} + +void __fastcall xmlAddAttr( HXML hXml, LPCTSTR pszName, unsigned __int64 value ) +{ + TCHAR buf[60]; + _ui64tot( value, buf, 10 ); + + xi.addAttr( hXml, T2UTF(pszName), T2UTF(buf)); +} + +void __fastcall xmlAddAttrID( HXML hXml, int id ) +{ + TCHAR text[ 100 ]; + mir_sntprintf( text, SIZEOF(text), _T("mir_%d"), id ); + xmlAddAttr( hXml, _T("id"), text ); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LPCTSTR __fastcall xmlGetAttr( HXML hXml, int n ) +{ + return xi.getAttr( hXml, n ); +} + +int __fastcall xmlGetAttrCount( HXML hXml ) +{ + return xi.getAttrCount( hXml ); +} + +LPCTSTR __fastcall xmlGetAttrName( HXML hXml, int n ) +{ + return xi.getAttrName( hXml, n ); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void __fastcall xmlAddChild( HXML hXml, HXML n ) +{ + xi.addChild2( n, hXml ); +} + +HXML __fastcall xmlAddChild( HXML hXml, LPCTSTR name ) +{ + return xi.addChild( hXml, T2UTF(name), NULL ); +} + +HXML __fastcall xmlAddChild( HXML hXml, LPCTSTR name, LPCTSTR value ) +{ + return xi.addChild( hXml, T2UTF(name), T2UTF(value)); +} + +HXML __fastcall xmlAddChild( HXML hXml, LPCTSTR name, int value ) +{ + TCHAR buf[40]; + _itot( value, buf, 10 ); + return xi.addChild( hXml, T2UTF(name), buf ); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LPCTSTR __fastcall xmlGetAttrValue( HXML hXml, LPCTSTR key ) +{ + return xi.getAttrValue( hXml, key ); +} + +HXML __fastcall xmlGetChild( HXML hXml, int n ) +{ + return xi.getChild( hXml, n ); +} + +HXML __fastcall xmlGetChild( HXML hXml, LPCTSTR key ) +{ + return xi.getNthChild( hXml, key, 0 ); +} + +#if defined( _UNICODE ) +HXML __fastcall xmlGetChild( HXML hXml, LPCSTR key ) +{ + LPTSTR wszKey = mir_a2t( key ); + HXML result = xi.getNthChild( hXml, wszKey, 0 ); + mir_free( wszKey ); + return result; +} + +HXML __fastcall xmlGetChildByTag( HXML hXml, LPCTSTR key, LPCTSTR attrName, LPCTSTR attrValue ) +{ + return xi.getChildByAttrValue( hXml, key, attrName, attrValue ); +} +#endif + +HXML __fastcall xmlGetChildByTag( HXML hXml, LPCSTR key, LPCSTR attrName, LPCTSTR attrValue ) +{ + LPTSTR wszKey = mir_a2t( key ), wszName = mir_a2t( attrName ); + HXML result = xi.getChildByAttrValue( hXml, wszKey, wszName, attrValue ); + mir_free( wszKey ), mir_free( wszName ); + return result; +} + +int __fastcall xmlGetChildCount( HXML hXml ) +{ + return xi.getChildCount( hXml ); +} + +HXML __fastcall xmlGetNthChild( HXML hXml, LPCTSTR tag, int nth ) +{ + int i, num; + + if ( !hXml || tag == NULL || _tcslen( tag ) <= 0 || nth < 1 ) + return NULL; + + num = 1; + for ( i=0; ; i++ ) { + HXML n = xi.getChild( hXml, i ); + if ( !n ) + break; + if ( !lstrcmp( tag, xmlGetName( n ))) { + if ( num == nth ) + return n; + + num++; + } } + + return NULL; +} + +LPCTSTR __fastcall xmlGetName( HXML xml ) +{ + return xi.getName( xml ); +} + +LPCTSTR __fastcall xmlGetText( HXML xml ) +{ + return xi.getText( xml ); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void XPath::ProcessPath(LookupInfo &info, bool bCreate) +{ + if (!info.nodeName) return; + + TCHAR *nodeName = (TCHAR *)alloca(sizeof(TCHAR) * (info.nodeName.length+1)); + lstrcpyn(nodeName, info.nodeName.p, info.nodeName.length+1); + + if (info.attrName && info.attrValue) + { + TCHAR *attrName = (TCHAR *)alloca(sizeof(TCHAR) * (info.attrName.length+1)); + lstrcpyn(attrName, info.attrName.p, info.attrName.length+1); + TCHAR *attrValue = (TCHAR *)alloca(sizeof(TCHAR) * (info.attrValue.length+1)); + lstrcpyn(attrValue, info.attrValue.p, info.attrValue.length+1); + HXML hXml = xmlGetChildByTag(m_hXml, nodeName, attrName, attrValue); + + m_hXml = (hXml || !bCreate) ? hXml : (m_hXml << XCHILD(nodeName) << XATTR(attrName, attrValue)); + } else + if (info.nodeIndex) + { + int idx = _ttoi(info.nodeIndex.p); + m_hXml = lstrcmp(nodeName, _T("*")) ? xmlGetNthChild(m_hXml, nodeName, idx) : xmlGetChild(m_hXml, idx-1); + + // no support for such creation mode + } else + { + HXML hXml = xmlGetChild(m_hXml, nodeName); + m_hXml = (hXml || !bCreate) ? hXml : (m_hXml << XCHILD(nodeName)); + } + + info.Reset(); +} + +XPath::PathType XPath::LookupImpl(bool bCreate) +{ + LookupState state = S_START; + LookupInfo info = {0}; + + for (LPCTSTR p = m_szPath; state < S_FINAL; ++p) + { + switch (state) + { + case S_START: + { + ProcessPath(info, bCreate); + if (!m_hXml) + { + state = S_FINAL_ERROR; + break; + } + + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T('@'): + info.attrName.Begin(p+1); + state = S_ATTR_STEP; + break; + case _T('/'): + break; + default: + info.nodeName.Begin(p); + state = S_NODE_NAME; + break; + }; + break; + } + case S_ATTR_STEP: + { + switch (*p) + { + case 0: + info.attrName.End(p); + state = S_FINAL_ATTR; + break; + default: + break; + }; + break; + } + case S_NODE_NAME: + { + switch (*p) + { + case 0: + info.nodeName.End(p); + state = S_FINAL_NODESET; + break; + case _T('['): + info.nodeName.End(p); + state = S_NODE_OPENBRACKET; + break; + case _T('/'): + info.nodeName.End(p); + state = S_START; + break; + default: + break; + }; + break; + } + case S_NODE_OPENBRACKET: + { + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T('@'): + info.attrName.Begin(p+1); + state = S_NODE_ATTRNAME; + break; + case _T('0'): case _T('1'): case _T('2'): case _T('3'): case _T('4'): + case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'): + info.nodeIndex.Begin(p); + state = S_NODE_INDEX; + break; + default: + state = S_FINAL_ERROR; + break; + }; + break; + } + case S_NODE_INDEX: + { + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T(']'): + info.nodeIndex.End(p); + state = S_NODE_CLOSEBRACKET; + break; + case _T('0'): case _T('1'): case _T('2'): case _T('3'): case _T('4'): + case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'): + break; + default: + state = S_FINAL_ERROR; + break; + }; + break; + } + case S_NODE_ATTRNAME: + { + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T('='): + info.attrName.End(p); + state = S_NODE_ATTREQUALS; + break; + default: + break; + }; + break; + } + case S_NODE_ATTREQUALS: + { + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T('\''): + info.attrValue.Begin(p+1); + state = S_NODE_ATTRVALUE; + break; + default: + state = S_FINAL_ERROR; + break; + }; + break; + } + case S_NODE_ATTRVALUE: + { + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T('\''): + info.attrValue.End(p); + state = S_NODE_ATTRCLOSEVALUE; + break; + default: + break; + }; + break; + } + case S_NODE_ATTRCLOSEVALUE: + { + switch (*p) + { + case 0: + state = S_FINAL_ERROR; + break; + case _T(']'): + state = S_NODE_CLOSEBRACKET; + break; + default: + state = S_FINAL_ERROR; + break; + }; + break; + } + case S_NODE_CLOSEBRACKET: + { + switch (*p) + { + case 0: + state = S_FINAL_NODE; + break; + case _T('/'): + state = S_START; + break; + default: + state = S_FINAL_ERROR; + break; + }; + break; + } + } + + if (!*p && (state < S_FINAL)) + { + state = S_FINAL_ERROR; + } + } + + switch (state) + { + case S_FINAL_ATTR: + m_szParam = info.attrName.p; + return T_ATTRIBUTE; + case S_FINAL_NODE: + ProcessPath(info, bCreate); + return T_NODE; + case S_FINAL_NODESET: + m_szParam = info.nodeName.p; + return T_NODESET; + } + + return T_ERROR; +} -- cgit v1.2.3