summaryrefslogtreecommitdiff
path: root/protocols/JabberG
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/JabberG')
-rwxr-xr-xprotocols/JabberG/src/jabber_caps.cpp41
-rwxr-xr-xprotocols/JabberG/src/jabber_caps.h1
-rwxr-xr-xprotocols/JabberG/src/jabber_iqid.cpp75
-rw-r--r--protocols/JabberG/src/jabber_notes.cpp14
-rw-r--r--protocols/JabberG/src/jabber_notes.h1
-rwxr-xr-xprotocols/JabberG/src/jabber_strm_mgmt.cpp2
-rwxr-xr-xprotocols/JabberG/src/jabber_thread.cpp10
-rw-r--r--protocols/JabberG/src/jabber_xml.cpp188
-rw-r--r--protocols/JabberG/src/jabber_xml.h133
-rw-r--r--protocols/JabberG/src/jabber_xstatus.cpp2
10 files changed, 74 insertions, 393 deletions
diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp
index 305cf845eb..94e949cbbf 100755
--- a/protocols/JabberG/src/jabber_caps.cpp
+++ b/protocols/JabberG/src/jabber_caps.cpp
@@ -161,25 +161,30 @@ void CJabberProto::OnIqResultCapsDiscoInfo(const TiXmlElement*, CJabberIqInfo *p
}
for (auto *xform : TiXmlFilter(query, "x")) {
- const char *szFormTypeValue = XPath(xform, "field[@var='FORM_TYPE']/value");
- if (!mir_strcmp(szFormTypeValue, "urn:xmpp:dataforms:softwareinfo")) {
- JSONNode root;
- if (pCaps->m_szOs = mir_strdup(XPath(xform, "field[@var='os']/value")))
- root.push_back(JSONNode("o", pCaps->m_szOs.get()));
- if (pCaps->m_szOsVer = mir_strdup(XPath(xform, "field[@var='os_version']/value")))
- root.push_back(JSONNode("ov", pCaps->m_szOsVer.get()));
- if (pCaps->m_szSoft = mir_strdup(XPath(xform, "field[@var='software']/value")))
- root.push_back(JSONNode("s", pCaps->m_szSoft.get()));
- if (pCaps->m_szSoftVer = mir_strdup(XPath(xform, "field[@var='software_version']/value")))
- root.push_back(JSONNode("sv", pCaps->m_szSoftVer.get()));
- if (pCaps->m_szSoftMir = mir_strdup(XPath(xform, "field[@var='x-miranda-core-version']/value")))
- root.push_back(JSONNode("sm", pCaps->m_szSoftMir.get()));
- root.push_back(JSONNode("c", CMStringA(FORMAT, "%lld", jcbCaps)));
-
- CMStringA szName(FORMAT, "%s#%s", pCaps->GetNode(), pCaps->GetHash());
- json_string szValue = root.write();
- db_set_s(0, "JabberCaps", szName, szValue.c_str());
+ // check that this is a form of required type
+ auto *formType = XmlGetChildText(XmlGetChildByTag(xform, "field", "var", "FORM_TYPE"), "value");
+ if (!formType || mir_strcmp(formType, "urn:xmpp:dataforms:softwareinfo"))
+ continue;
+
+ JSONNode root;
+ for (auto *field : TiXmlFilter(xform, "field")) {
+ const char *fieldName = field->Attribute("var"), *fieldValue = XmlGetChildText(field, "value");
+ if (!mir_strcmp(fieldName, "os"))
+ root.push_back(JSONNode("o", pCaps->m_szOs = mir_strdup(fieldValue)));
+ else if (!mir_strcmp(fieldName, "os_version"))
+ root.push_back(JSONNode("ov", pCaps->m_szOsVer = mir_strdup(fieldValue)));
+ else if (!mir_strcmp(fieldName, "software"))
+ root.push_back(JSONNode("s", pCaps->m_szSoft = mir_strdup(fieldValue)));
+ else if (!mir_strcmp(fieldName, "software_version"))
+ root.push_back(JSONNode("sv", pCaps->m_szSoftVer = mir_strdup(fieldValue)));
+ else if (!mir_strcmp(fieldName, "x-miranda-core-version"))
+ root.push_back(JSONNode("sm", pCaps->m_szSoftMir = mir_strdup(fieldValue)));
}
+ root.push_back(JSONNode("c", CMStringA(FORMAT, "%lld", jcbCaps)));
+
+ CMStringA szName(FORMAT, "%s#%s", pCaps->GetNode(), pCaps->GetHash());
+ json_string szValue = root.write();
+ db_set_s(0, "JabberCaps", szName, szValue.c_str());
}
pCaps->SetCaps(jcbCaps, pInfo->GetIqId());
diff --git a/protocols/JabberG/src/jabber_caps.h b/protocols/JabberG/src/jabber_caps.h
index 4c8e985990..683b44b897 100755
--- a/protocols/JabberG/src/jabber_caps.h
+++ b/protocols/JabberG/src/jabber_caps.h
@@ -132,6 +132,7 @@ typedef unsigned __int64 JabberCapsBits;
#define JABBER_CAPS_ARCHIVE_MANAGE ((JabberCapsBits)1<<35)
#define JABBER_FEAT_CAPTCHA "urn:xmpp:captcha"
+#define JABBER_FEAT_BIND "urn:ietf:params:xml:ns:xmpp-bind"
#define JABBER_FEAT_ATTENTION "urn:xmpp:attention:0"
#define JABBER_CAPS_ATTENTION ((JabberCapsBits)1<<36)
diff --git a/protocols/JabberG/src/jabber_iqid.cpp b/protocols/JabberG/src/jabber_iqid.cpp
index 627f404a8a..ad5b04c556 100755
--- a/protocols/JabberG/src/jabber_iqid.cpp
+++ b/protocols/JabberG/src/jabber_iqid.cpp
@@ -82,14 +82,14 @@ void CJabberProto::OnIqResultServerDiscoInfo(const TiXmlElement *iqNode, CJabber
void CJabberProto::OnIqResultNestedRosterGroups(const TiXmlElement *iqNode, CJabberIqInfo *pInfo)
{
- const char *szGroupDelimeter = nullptr;
+ const char *szGroupDelimiter = nullptr;
bool bPrivateStorageSupport = false;
if (iqNode && pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT) {
bPrivateStorageSupport = true;
- szGroupDelimeter = XPathFmt(iqNode, "query[@xmlns='%s']/roster[@xmlns='%s']", JABBER_FEAT_PRIVATE_STORAGE, JABBER_FEAT_NESTED_ROSTER_GROUPS);
- if (szGroupDelimeter && !szGroupDelimeter[0])
- szGroupDelimeter = nullptr; // "" as roster delimeter is not supported :)
+ auto *xmlDelimiter = XmlGetChildByTag(XmlGetChildByTag(iqNode, "query", "xmlns", JABBER_FEAT_PRIVATE_STORAGE), "roster", "xmlns", JABBER_FEAT_NESTED_ROSTER_GROUPS);
+ if (xmlDelimiter)
+ szGroupDelimiter = xmlDelimiter->GetText();
}
// global fuckup
@@ -97,13 +97,13 @@ void CJabberProto::OnIqResultNestedRosterGroups(const TiXmlElement *iqNode, CJab
return;
// is our default delimiter?
- if ((!szGroupDelimeter && bPrivateStorageSupport) || (szGroupDelimeter && mir_strcmp(szGroupDelimeter, "\\")))
+ if ((!szGroupDelimiter && bPrivateStorageSupport) || (szGroupDelimiter && mir_strcmp(szGroupDelimiter, "\\")))
m_ThreadInfo->send(
XmlNodeIq("set", SerialNext()) << XQUERY(JABBER_FEAT_PRIVATE_STORAGE)
<< XCHILD("roster", "\\") << XATTR("xmlns", JABBER_FEAT_NESTED_ROSTER_GROUPS));
// roster request
- char *szUserData = mir_strdup(szGroupDelimeter ? szGroupDelimeter : "\\");
+ char *szUserData = mir_strdup(szGroupDelimiter ? szGroupDelimiter : "\\");
m_ThreadInfo->send(
XmlNodeIq(AddIQ(&CJabberProto::OnIqResultGetRoster, JABBER_IQ_TYPE_GET, nullptr, 0, -1, (void*)szUserData))
<< XCHILDNS("query", JABBER_FEAT_IQ_ROSTER));
@@ -293,7 +293,7 @@ void CJabberProto::OnIqResultBind(const TiXmlElement *iqNode, CJabberIqInfo *pIn
if (!m_ThreadInfo || !iqNode)
return;
if (pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT) {
- const char *szJid = XPath(iqNode, "bind[@xmlns='urn:ietf:params:xml:ns:xmpp-bind']/jid");
+ const char *szJid = XmlGetChildText(XmlGetChildByTag(iqNode, "bind", "xmlns", JABBER_FEAT_BIND), "jid");
if (szJid) {
if (!strncmp(m_ThreadInfo->fullJID, szJid, _countof(m_ThreadInfo->fullJID)))
debugLogA("Result Bind: %s confirmed ", m_ThreadInfo->fullJID);
@@ -351,7 +351,7 @@ void CJabberProto::GroupchatJoinByHContact(MCONTACT hContact, bool autojoin)
void CJabberProto::OnIqResultGetRoster(const TiXmlElement *iqNode, CJabberIqInfo *pInfo)
{
debugLogA("<iq/> iqIdGetRoster");
- ptrA szGroupDelimeter((char *)pInfo->GetUserData());
+ ptrA szGroupDelimiter((char *)pInfo->GetUserData());
if (pInfo->GetIqType() != JABBER_IQ_TYPE_RESULT)
return;
@@ -362,8 +362,8 @@ void CJabberProto::OnIqResultGetRoster(const TiXmlElement *iqNode, CJabberIqInfo
if (mir_strcmp(queryNode->Attribute("xmlns"), JABBER_FEAT_IQ_ROSTER))
return;
- if (!mir_strcmp(szGroupDelimeter, "\\"))
- szGroupDelimeter = nullptr;
+ if (!mir_strcmp(szGroupDelimiter, "\\"))
+ szGroupDelimiter = nullptr;
LIST<void> chatRooms(10);
OBJLIST<JABBER_HTTP_AVATARS> *httpavatars = new OBJLIST<JABBER_HTTP_AVATARS>(20, JABBER_HTTP_AVATARS::compare);
@@ -402,10 +402,10 @@ void CJabberProto::OnIqResultGetRoster(const TiXmlElement *iqNode, CJabberIqInfo
replaceStr(item->group, XmlGetChildText(itemNode, "group"));
// check group delimiters
- if (item->group && szGroupDelimeter) {
- while (char *szPos = strstr(item->group, szGroupDelimeter)) {
+ if (item->group && szGroupDelimiter) {
+ while (char *szPos = strstr(item->group, szGroupDelimiter)) {
*szPos = 0;
- szPos += mir_strlen(szGroupDelimeter);
+ szPos += mir_strlen(szGroupDelimiter);
CMStringA szNewGroup(FORMAT, "%s\\%s", item->group, szPos);
replaceStr(item->group, szNewGroup.Detach());
}
@@ -491,8 +491,8 @@ void CJabberProto::OnIqResultGetRoster(const TiXmlElement *iqNode, CJabberIqInfo
UI_SAFE_NOTIFY(m_pDlgServiceDiscovery, WM_JABBER_TRANSPORT_REFRESH);
- if (szGroupDelimeter)
- mir_free(szGroupDelimeter);
+ if (szGroupDelimiter)
+ mir_free(szGroupDelimiter);
OnProcessLoginRq(m_ThreadInfo, JABBER_LOGIN_ROSTER);
RebuildInfoFrame();
@@ -1424,8 +1424,8 @@ void CJabberProto::OnIqResultDiscoBookmarks(const TiXmlElement *iqNode, CJabberI
item->name = mir_utf8decodeW(itemNode->Attribute("name"));
item->type = mir_strdup("conference");
item->bUseResource = true;
- item->nick = mir_strdup(XPath(itemNode, "nick"));
- item->password = mir_strdup(XPath(itemNode, "password"));
+ item->nick = mir_strdup(XmlGetChildText(itemNode, "nick"));
+ item->password = mir_strdup(XmlGetChildText(itemNode, "password"));
const char *autoJ = itemNode->Attribute("autojoin");
if (autoJ != nullptr)
@@ -1515,7 +1515,7 @@ void CJabberProto::OnIqResultLastActivity(const TiXmlElement *iqNode, CJabberIqI
time_t lastActivity = -1;
if (pInfo->m_nIqType == JABBER_IQ_TYPE_RESULT) {
if (auto *xmlLast = XmlGetChildByTag(iqNode, "query", "xmlns", JABBER_FEAT_LAST_ACTIVITY)) {
- int nSeconds = XmlGetChildInt(xmlLast, "seconds");
+ int nSeconds = xmlLast->IntAttribute("seconds");
if (nSeconds > 0)
lastActivity = time(0) - nSeconds;
@@ -1536,24 +1536,27 @@ void CJabberProto::OnIqResultEntityTime(const TiXmlElement *pIqNode, CJabberIqIn
return;
if (pInfo->m_nIqType == JABBER_IQ_TYPE_RESULT) {
- const char *szTzo = XPathFmt(pIqNode, "time[@xmlns='%s']/tzo", JABBER_FEAT_ENTITY_TIME);
- if (szTzo && szTzo[0]) {
- const char *szMin = strchr(szTzo, ':');
- int nTz = atoi(szTzo) * -2;
- nTz += (nTz < 0 ? -1 : 1) * (szMin ? atoi(szMin + 1) / 30 : 0);
-
- TIME_ZONE_INFORMATION tzinfo;
- if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT)
- nTz -= tzinfo.DaylightBias / 30;
-
- setByte(pInfo->m_hContact, "Timezone", (signed char)nTz);
-
- const char *szTz = XPathFmt(pIqNode, "time[@xmlns='%s']/tz", JABBER_FEAT_ENTITY_TIME);
- if (szTz)
- setUString(pInfo->m_hContact, "TzName", szTz);
- else
- delSetting(pInfo->m_hContact, "TzName");
- return;
+ auto *xmlTime = XmlGetChildByTag(pIqNode, "time", "xmlns", JABBER_FEAT_ENTITY_TIME);
+ if (xmlTime) {
+ const char *szTzo = XmlGetChildText(xmlTime, "tzo");
+ if (szTzo && szTzo[0]) {
+ const char *szMin = strchr(szTzo, ':');
+ int nTz = atoi(szTzo) * -2;
+ nTz += (nTz < 0 ? -1 : 1) * (szMin ? atoi(szMin + 1) / 30 : 0);
+
+ TIME_ZONE_INFORMATION tzinfo;
+ if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT)
+ nTz -= tzinfo.DaylightBias / 30;
+
+ setByte(pInfo->m_hContact, "Timezone", (signed char)nTz);
+
+ const char *szTz = XmlGetChildText(xmlTime, "tz");
+ if (szTz)
+ setUString(pInfo->m_hContact, "TzName", szTz);
+ else
+ delSetting(pInfo->m_hContact, "TzName");
+ return;
+ }
}
}
else if (pInfo->m_nIqType == JABBER_IQ_TYPE_ERROR) {
diff --git a/protocols/JabberG/src/jabber_notes.cpp b/protocols/JabberG/src/jabber_notes.cpp
index 67678f107c..3b346ff64c 100644
--- a/protocols/JabberG/src/jabber_notes.cpp
+++ b/protocols/JabberG/src/jabber_notes.cpp
@@ -38,10 +38,10 @@ CNoteItem::CNoteItem()
CNoteItem::CNoteItem(const TiXmlElement *hXml, const char *szFrom)
{
SetData(
- XPath(hXml, "title"),
- szFrom ? szFrom : XPath(hXml, "@from"),
- Utf2T(XPath(hXml, "text")),
- XPath(hXml, "@tags"));
+ XmlGetChildText(hXml, "title"),
+ szFrom ? szFrom : hXml->Attribute("from"),
+ Utf2T(XmlGetChildText(hXml, "text")),
+ hXml->Attribute("tags"));
}
CNoteItem::~CNoteItem()
@@ -107,12 +107,6 @@ int CNoteItem::cmp(const CNoteItem *p1, const CNoteItem *p2)
return 0;
}
-void CNoteList::AddNote(TiXmlElement *hXml, const char *szFrom)
-{
- m_bIsModified = true;
- insert(new CNoteItem(hXml, szFrom));
-}
-
void CNoteList::LoadXml(const TiXmlElement *hXml)
{
destroy();
diff --git a/protocols/JabberG/src/jabber_notes.h b/protocols/JabberG/src/jabber_notes.h
index c2867970b3..3f0613a044 100644
--- a/protocols/JabberG/src/jabber_notes.h
+++ b/protocols/JabberG/src/jabber_notes.h
@@ -77,7 +77,6 @@ public:
OBJLIST<CNoteItem>::remove(p);
}
- void AddNote(TiXmlElement *hXml, const char *szFrom = nullptr);
void LoadXml(const TiXmlElement *hXml);
void SaveXml(TiXmlElement *hXmlParent);
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.cpp b/protocols/JabberG/src/jabber_strm_mgmt.cpp
index 9a61f66c63..b7682364aa 100755
--- a/protocols/JabberG/src/jabber_strm_mgmt.cpp
+++ b/protocols/JabberG/src/jabber_strm_mgmt.cpp
@@ -272,7 +272,7 @@ void strm_mgmt::FinishLoginProcess(ThreadData *info)
if (info->auth) { //We are already logged-in
info->send(
XmlNodeIq(proto->AddIQ(&CJabberProto::OnIqResultBind, JABBER_IQ_TYPE_SET))
- << XCHILDNS("bind", "urn:ietf:params:xml:ns:xmpp-bind")
+ << XCHILDNS("bind", JABBER_FEAT_BIND)
<< XCHILD("resource", info->resource));
if (proto->m_AuthMechs.isSessionAvailable)
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp
index 439ed33d69..fa9ea84c14 100755
--- a/protocols/JabberG/src/jabber_thread.cpp
+++ b/protocols/JabberG/src/jabber_thread.cpp
@@ -760,7 +760,7 @@ void CJabberProto::OnProcessFeatures(const TiXmlElement *node, ThreadData *info)
if (info->auth) { //We are already logged-in
info->send(
XmlNodeIq(AddIQ(&CJabberProto::OnIqResultBind, JABBER_IQ_TYPE_SET))
- << XCHILDNS("bind", "urn:ietf:params:xml:ns:xmpp-bind")
+ << XCHILDNS("bind", JABBER_FEAT_BIND)
<< XCHILD("resource", info->resource));
if (m_AuthMechs.isSessionAvailable)
@@ -989,10 +989,10 @@ void CJabberProto::OnProcessPubsubEvent(const TiXmlElement *node)
if (!tuneNode)
return;
- const char *szArtist = XPath(tuneNode, "artist");
- const char *szSource = XPath(tuneNode, "source");
- const char *szTitle = XPath(tuneNode, "title");
- const char *szTrack = XPath(tuneNode, "track");
+ const char *szArtist = XmlGetChildText(tuneNode, "artist");
+ const char *szSource = XmlGetChildText(tuneNode, "source");
+ const char *szTitle = XmlGetChildText(tuneNode, "title");
+ const char *szTrack = XmlGetChildText(tuneNode, "track");
wchar_t szLengthInTime[20];
int nLength = XmlGetChildInt(tuneNode, "length");
diff --git a/protocols/JabberG/src/jabber_xml.cpp b/protocols/JabberG/src/jabber_xml.cpp
index bd0fbe08eb..f2336123c7 100644
--- a/protocols/JabberG/src/jabber_xml.cpp
+++ b/protocols/JabberG/src/jabber_xml.cpp
@@ -199,191 +199,3 @@ int XmlGetChildCount(const TiXmlElement *hXml)
}
return iCount;
}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void XPath::ProcessPath(LookupInfo &info)
-{
- if (!info.nodeName) return;
-
- char *nodeName = (char *)alloca(sizeof(char) * (info.nodeName.length+1));
- mir_strncpy(nodeName, info.nodeName.p, info.nodeName.length+1);
-
- if (info.attrName && info.attrValue) {
- char *attrName = (char *)alloca(sizeof(char)* (info.attrName.length + 1));
- mir_strncpy(attrName, info.attrName.p, info.attrName.length + 1);
- char *attrValue = (char *)alloca(sizeof(char)* (info.attrValue.length + 1));
- mir_strncpy(attrValue, info.attrValue.p, info.attrValue.length + 1);
- m_hXml = XmlGetChildByTag(m_hXml, nodeName, attrName, attrValue);
- }
- else m_hXml = m_hXml->FirstChildElement(nodeName);
-
- info.Reset();
-}
-
-XPath::PathType XPath::LookupImpl()
-{
- LookupState state = S_START;
- LookupInfo info = {};
-
- for (const char *p = m_szPath; state < S_FINAL; ++p) {
- switch (state) {
- case S_START:
- ProcessPath(info);
- if (!m_hXml) {
- state = S_FINAL_ERROR;
- break;
- }
-
- switch (*p) {
- case 0:
- state = S_FINAL_ERROR;
- break;
- case '@':
- info.attrName.Begin(p + 1);
- state = S_ATTR_STEP;
- break;
- case '/':
- 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 '[':
- info.nodeName.End(p);
- state = S_NODE_OPENBRACKET;
- break;
- case '/':
- 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 '@':
- info.attrName.Begin(p + 1);
- state = S_NODE_ATTRNAME;
- break;
- default:
- state = S_FINAL_ERROR;
- break;
- };
- break;
-
- case S_NODE_ATTRNAME:
- switch (*p) {
- case 0:
- state = S_FINAL_ERROR;
- break;
- case '=':
- 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 '\'':
- 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 '\'':
- 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 ']':
- 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 '/':
- 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);
- return T_NODE;
- case S_FINAL_NODESET:
- m_szParam = info.nodeName.p;
- return T_NODESET;
- }
-
- return T_ERROR;
-}
diff --git a/protocols/JabberG/src/jabber_xml.h b/protocols/JabberG/src/jabber_xml.h
index 84be255ba5..098e8ae346 100644
--- a/protocols/JabberG/src/jabber_xml.h
+++ b/protocols/JabberG/src/jabber_xml.h
@@ -188,137 +188,4 @@ struct XQUERY
TiXmlElement* __fastcall operator<<(TiXmlElement *node, const XQUERY& child);
-/////////////////////////////////////////////////////////////////////////////////////////
-// Limited XPath support
-// path should look like: "node-spec/node-spec/.../result-spec"
-// where "node-spec" can be "node-name", "node-name[@attr-name='attr-value']" or "node-name[node-index]"
-// result may be either "node-spec", or "@attr-name"
-//
-// Samples:
-// const char *s = XPath(node, "child/subchild[@attr='value']"); // get node text
-// XPath(node, "child/subchild[@name='test']/@attr") = L"Hello"; // create path if needed and set attribute value
-//
-// XPath(node, "child/subchild[@name='test']") = L"Hello"; // TODO: create path if needed and set node text
-
-class XPath
-{
-public:
- __forceinline XPath(const TiXmlElement *hXml, char *path):
- m_type(T_UNKNOWN),
- m_szPath(path),
- m_hXml(hXml),
- m_szParam(nullptr)
- {}
-
- // Read data
- operator const TiXmlElement*()
- {
- switch (Lookup())
- {
- case T_NODE: return m_hXml;
- case T_NODESET: return m_hXml->FirstChildElement(m_szParam);
- }
- return nullptr;
- }
- operator LPCSTR()
- {
- switch (Lookup())
- {
- case T_ATTRIBUTE: return m_hXml->Attribute(m_szParam);
- case T_NODE: return m_hXml->GetText();
- case T_NODESET: return (m_hXml->FirstChildElement()) ? m_hXml->FirstChildElement()->GetText() : 0;
- }
- return nullptr;
- }
- __forceinline bool operator== (char *str)
- {
- return !mir_strcmp(*this, str);
- }
- __forceinline bool operator!= (char *str)
- {
- return mir_strcmp(*this, str) ? true : false;
- }
-
-private:
- enum PathType
- {
- T_UNKNOWN,
- T_ERROR,
- T_NODE,
- T_ATTRIBUTE,
- T_NODESET
- };
-
- __forceinline PathType Lookup()
- {
- return (m_type == T_UNKNOWN) ? LookupImpl() : m_type;
- }
-
- enum LookupState
- {
- S_START,
- S_ATTR_STEP,
- S_NODE_NAME,
- S_NODE_OPENBRACKET,
- S_NODE_ATTRNAME,
- S_NODE_ATTREQUALS,
- S_NODE_ATTRVALUE,
- S_NODE_ATTRCLOSEVALUE,
- S_NODE_CLOSEBRACKET,
-
- S_FINAL,
- S_FINAL_ERROR,
- S_FINAL_ATTR,
- S_FINAL_NODESET,
- S_FINAL_NODE
- };
-
- struct LookupString
- {
- void Begin(const char *p_) { p = p_; }
- void End(const char *p_) { length = p_ - p; }
- operator bool() { return p ? true : false; }
-
- const char *p;
- int length;
-
- };
-
- struct LookupInfo
- {
- void Reset() { memset(this, 0, sizeof(*this)); }
- LookupString nodeName;
- LookupString attrName;
- LookupString attrValue;
- };
-
- void ProcessPath(LookupInfo &info);
- PathType LookupImpl();
-
- PathType m_type;
- const TiXmlElement *m_hXml;
- const char *m_szPath;
- const char *m_szParam;
-};
-
-class XPathFmt: public XPath
-{
-public:
- enum { BUFSIZE = 512 };
- XPathFmt(const TiXmlElement *hXml, char *path, ...): XPath(hXml, m_buf)
- {
- *m_buf = 0;
- char buf[BUFSIZE];
-
- va_list args;
- va_start(args, path);
- mir_vsnprintf(buf, BUFSIZE, path, args);
- buf[BUFSIZE-1] = 0;
- va_end(args);
- }
-
-private:
- char m_buf[BUFSIZE];
-};
-
#endif
diff --git a/protocols/JabberG/src/jabber_xstatus.cpp b/protocols/JabberG/src/jabber_xstatus.cpp
index 70fad9c365..7909374f13 100644
--- a/protocols/JabberG/src/jabber_xstatus.cpp
+++ b/protocols/JabberG/src/jabber_xstatus.cpp
@@ -1003,7 +1003,7 @@ void CPepActivity::ProcessItems(const char *from, const TiXmlElement *itemsNode)
if (!actNode)
return;
- const char *szText = XPath(actNode, "text");
+ const char *szText = XmlGetChildText(actNode, "text");
const char *szFirstNode = nullptr, *szSecondNode = nullptr;
for (auto *n : TiXmlFilter(actNode, "text")) {