diff options
Diffstat (limited to 'protocols/JabberG/src/jabber_message_manager.cpp')
-rw-r--r-- | protocols/JabberG/src/jabber_message_manager.cpp | 130 |
1 files changed, 104 insertions, 26 deletions
diff --git a/protocols/JabberG/src/jabber_message_manager.cpp b/protocols/JabberG/src/jabber_message_manager.cpp index 910c76a0be..ed33c1ccf3 100644 --- a/protocols/JabberG/src/jabber_message_manager.cpp +++ b/protocols/JabberG/src/jabber_message_manager.cpp @@ -26,27 +26,44 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "jabber.h"
#include "jabber_message_manager.h"
-BOOL CJabberMessageManager::FillPermanentHandlers()
+CJabberMessageManager::CJabberMessageManager(CJabberProto *proto)
+{
+ InitializeCriticalSection(&m_cs);
+ m_pPermanentHandlers = NULL;
+ ppro = proto;
+}
+CJabberMessageManager::~CJabberMessageManager()
+{
+ CJabberMessagePermanentInfo *pInfo = m_pPermanentHandlers;
+ while (pInfo) {
+ CJabberMessagePermanentInfo *pTmp = pInfo->m_pNext;
+ delete pInfo;
+ pInfo = pTmp;
+ }
+ m_pPermanentHandlers = NULL;
+
+ DeleteCriticalSection(&m_cs);
+}
+
+void CJabberMessageManager::FillPermanentHandlers()
{
AddPermanentHandler(&CJabberProto::OnMessageError, JABBER_MESSAGE_TYPE_ERROR, JABBER_MESSAGE_PARSE_FROM | JABBER_MESSAGE_PARSE_HCONTACT, NULL, FALSE, _T("error"));
AddPermanentHandler(&CJabberProto::OnMessageIbb, 0, 0, JABBER_FEAT_IBB, FALSE, _T("data"));
AddPermanentHandler(&CJabberProto::OnMessagePubsubEvent, 0, 0, JABBER_FEAT_PUBSUB_EVENT, FALSE, _T("event"));
AddPermanentHandler(&CJabberProto::OnMessageGroupchat, JABBER_MESSAGE_TYPE_GROUPCHAT, JABBER_MESSAGE_PARSE_FROM, NULL, FALSE, NULL);
- return TRUE;
}
-BOOL CJabberMessageManager::HandleMessagePermanent(HXML node, ThreadData *pThreadData)
+bool CJabberMessageManager::HandleMessagePermanent(HXML node, ThreadData *pThreadData)
{
- BOOL bStopHandling = FALSE;
- Lock();
+ mir_cslock lck(m_cs);
+
CJabberMessagePermanentInfo *pInfo = m_pPermanentHandlers;
- while (pInfo && !bStopHandling) {
- // have to get all data here, in the loop, because there's always possibility that previous handler modified it
+ while (pInfo) {
+ // have to get all data here, in the loop, because there's always possibility that previous handler modified it
CJabberMessageInfo messageInfo;
LPCTSTR szType = xmlGetAttrValue(node, _T("type"));
- if (szType)
- {
+ if (szType) {
if ( !_tcsicmp(szType, _T("normal")))
messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL;
else if ( !_tcsicmp(szType, _T("error")))
@@ -58,24 +75,20 @@ BOOL CJabberMessageManager::HandleMessagePermanent(HXML node, ThreadData *pThrea else if ( !_tcsicmp(szType, _T("headline")))
messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_HEADLINE;
else
- break; // m_nMessageType = JABBER_MESSAGE_TYPE_FAIL;
- }
- else {
- messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL;
+ return FALSE;
}
+ else messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL;
- if ((pInfo->m_nMessageTypes & messageInfo.m_nMessageType)) {
- int i;
- for (i = xmlGetChildCount(node) - 1; i >= 0; i--) {
- // enumerate all children and see whether this node suits handler criteria
+ if (pInfo->m_nMessageTypes & messageInfo.m_nMessageType) {
+ for (int i = xmlGetChildCount(node) - 1; i >= 0; i--) {
+ // enumerate all children and see whether this node suits handler criteria
HXML child = xmlGetChild(node, i);
LPCTSTR szTagName = xmlGetName(child);
LPCTSTR szXmlns = xmlGetAttrValue(child, _T("xmlns"));
- if ((!pInfo->m_szXmlns || (szXmlns && !_tcscmp(pInfo->m_szXmlns, szXmlns))) &&
- (!pInfo->m_szTag || !_tcscmp(pInfo->m_szTag, szTagName))) {
- // node suits handler criteria, call the handler
+ if ((!pInfo->m_szXmlns || (szXmlns && !_tcscmp(pInfo->m_szXmlns, szXmlns))) && (!pInfo->m_szTag || !_tcscmp(pInfo->m_szTag, szTagName))) {
+ // node suits handler criteria, call the handler
messageInfo.m_hChildNode = child;
messageInfo.m_szChildTagName = szTagName;
messageInfo.m_szChildTagXmlns = szXmlns;
@@ -93,16 +106,81 @@ BOOL CJabberMessageManager::HandleMessagePermanent(HXML node, ThreadData *pThrea if (messageInfo.m_szFrom)
ppro->Log("Handling message from %S", messageInfo.m_szFrom);
- if ((ppro->*(pInfo->m_pHandler))(node, pThreadData, &messageInfo)) {
- bStopHandling = TRUE;
- break;
- }
+ if ((ppro->*(pInfo->m_pHandler))(node, pThreadData, &messageInfo))
+ return TRUE;
}
}
}
pInfo = pInfo->m_pNext;
}
- Unlock();
- return bStopHandling;
+ return FALSE;
+}
+
+CJabberMessagePermanentInfo* CJabberMessageManager::AddPermanentHandler(
+ JABBER_PERMANENT_MESSAGE_HANDLER pHandler,
+ int nMessageTypes,
+ DWORD dwParamsToParse,
+ const TCHAR *szXmlns,
+ BOOL bAllowPartialNs,
+ const TCHAR *szTag,
+ void *pUserData,
+ MESSAGE_USER_DATA_FREE_FUNC pUserDataFree,
+ int iPriority)
+{
+ CJabberMessagePermanentInfo* pInfo = new CJabberMessagePermanentInfo();
+ if (pInfo == NULL)
+ return NULL;
+
+ pInfo->m_pHandler = pHandler;
+ pInfo->m_nMessageTypes = nMessageTypes ? nMessageTypes : JABBER_MESSAGE_TYPE_ANY;
+ replaceStrT(pInfo->m_szXmlns, szXmlns);
+ pInfo->m_bAllowPartialNs = bAllowPartialNs;
+ replaceStrT(pInfo->m_szTag, szTag);
+ pInfo->m_dwParamsToParse = dwParamsToParse;
+ pInfo->m_pUserData = pUserData;
+ pInfo->m_pUserDataFree = pUserDataFree;
+ pInfo->m_iPriority = iPriority;
+
+ mir_cslock lck(m_cs);
+ if ( !m_pPermanentHandlers)
+ m_pPermanentHandlers = pInfo;
+ else {
+ if (m_pPermanentHandlers->m_iPriority > pInfo->m_iPriority) {
+ pInfo->m_pNext = m_pPermanentHandlers;
+ m_pPermanentHandlers = pInfo;
+ }
+ else {
+ CJabberMessagePermanentInfo *pTmp = m_pPermanentHandlers;
+ while (pTmp->m_pNext && pTmp->m_pNext->m_iPriority <= pInfo->m_iPriority)
+ pTmp = pTmp->m_pNext;
+ pInfo->m_pNext = pTmp->m_pNext;
+ pTmp->m_pNext = pInfo;
+ }
+ }
+ return pInfo;
+}
+
+bool CJabberMessageManager::DeletePermanentHandler(CJabberMessagePermanentInfo *pInfo)
+{
+ mir_cslock lck(m_cs);
+ if ( !m_pPermanentHandlers)
+ return FALSE;
+
+ if (m_pPermanentHandlers == pInfo) { // check first item
+ m_pPermanentHandlers = m_pPermanentHandlers->m_pNext;
+ delete pInfo;
+ return TRUE;
+ }
+
+ CJabberMessagePermanentInfo *pTmp = m_pPermanentHandlers;
+ while (pTmp->m_pNext) {
+ if (pTmp->m_pNext == pInfo) {
+ pTmp->m_pNext = pTmp->m_pNext->m_pNext;
+ delete pInfo;
+ return TRUE;
+ }
+ pTmp = pTmp->m_pNext;
+ }
+ return FALSE;
}
|