diff options
Diffstat (limited to 'plugins/Dbx_mdb/src/dbevents.cpp')
-rw-r--r-- | plugins/Dbx_mdb/src/dbevents.cpp | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/plugins/Dbx_mdb/src/dbevents.cpp b/plugins/Dbx_mdb/src/dbevents.cpp new file mode 100644 index 0000000000..cd25e6e479 --- /dev/null +++ b/plugins/Dbx_mdb/src/dbevents.cpp @@ -0,0 +1,300 @@ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org)
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+
+#include "commonheaders.h"
+
+static HANDLE hEventDeletedEvent, hEventAddedEvent, hEventFilterAddedEvent;
+
+STDMETHODIMP_(LONG) CDbxMdb::GetEventCount(MCONTACT contactID)
+{
+ mir_cslock lck(m_csDbAccess);
+ return -1;
+}
+
+STDMETHODIMP_(HANDLE) CDbxMdb::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei)
+{
+ if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0;
+ if (dbei->timestamp == 0) return 0;
+
+ DBEvent dbe;
+ dbe.signature = DBEVENT_SIGNATURE;
+ dbe.contactID = contactID; // store native or subcontact's id
+ dbe.timestamp = dbei->timestamp;
+ dbe.flags = dbei->flags;
+ dbe.wEventType = dbei->eventType;
+ dbe.cbBlob = dbei->cbBlob;
+ BYTE *pBlob = dbei->pBlob;
+
+ MCONTACT contactNotifyID = contactID;
+ DBCachedContact *ccSub = NULL;
+ if (contactID != 0) {
+ DBCachedContact *cc = m_cache->GetCachedContact(contactID);
+ if (cc == NULL)
+ return NULL;
+
+ if (cc->IsSub()) {
+ ccSub = cc;
+ // set default sub to the event's source
+ if (!(dbei->flags & DBEF_SENT))
+ db_mc_setDefault(cc->parentID, contactID, false);
+ contactID = cc->parentID; // and add an event to a metahistory
+ if (db_mc_isEnabled())
+ contactNotifyID = contactID;
+ }
+ }
+
+ if (NotifyEventHooks(hEventFilterAddedEvent, contactNotifyID, (LPARAM)dbei))
+ return NULL;
+
+ mir_ptr<BYTE> pCryptBlob;
+ if (m_bEncrypted) {
+ size_t len;
+ BYTE *pResult = m_crypto->encodeBuffer(pBlob, dbe.cbBlob, &len);
+ if (pResult != NULL) {
+ pCryptBlob = pBlob = pResult;
+ dbe.cbBlob = (DWORD)len;
+ dbe.flags |= DBEF_ENCRYPTED;
+ }
+ }
+
+ mir_cslockfull lck(m_csDbAccess);
+
+ lck.unlock();
+
+ log1("add event @ %08x", ofsNew);
+
+ // Notify only in safe mode or on really new events
+ NotifyEventHooks(hEventAddedEvent, contactNotifyID, (LPARAM)-1);
+
+ return (HANDLE)0;
+}
+
+STDMETHODIMP_(BOOL) CDbxMdb::DeleteEvent(MCONTACT contactID, HANDLE hDbEvent)
+{
+ DBCachedContact *cc;
+ if (contactID) {
+ if ((cc = m_cache->GetCachedContact(contactID)) == NULL)
+ return 2;
+ if (cc->IsSub())
+ if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
+ return 3;
+ }
+ else cc = NULL;
+
+ mir_cslockfull lck(m_csDbAccess);
+ lck.unlock();
+
+ // call notifier while outside mutex
+ NotifyEventHooks(hEventDeletedEvent, contactID, (LPARAM)hDbEvent);
+
+ // get back in
+ lck.lock();
+ return 0;
+}
+
+STDMETHODIMP_(LONG) CDbxMdb::GetBlobSize(HANDLE hDbEvent)
+{
+ mir_cslock lck(m_csDbAccess);
+ return -1;
+}
+
+STDMETHODIMP_(BOOL) CDbxMdb::GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbei)
+{
+ if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 1;
+ if (dbei->cbBlob > 0 && dbei->pBlob == NULL) {
+ dbei->cbBlob = 0;
+ return 1;
+ }
+
+ mir_cslock lck(m_csDbAccess);
+ return 0;
+}
+
+STDMETHODIMP_(BOOL) CDbxMdb::MarkEventRead(MCONTACT contactID, HANDLE hDbEvent)
+{
+ DBCachedContact *cc;
+ if (contactID) {
+ if ((cc = m_cache->GetCachedContact(contactID)) == NULL)
+ return -1;
+ if (cc->IsSub())
+ if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
+ return -1;
+ }
+ else cc = NULL;
+
+ mir_cslockfull lck(m_csDbAccess);
+
+ lck.unlock();
+ NotifyEventHooks(hEventMarkedRead, contactID, (LPARAM)hDbEvent);
+ return -11;
+}
+
+STDMETHODIMP_(MCONTACT) CDbxMdb::GetEventContact(HANDLE hDbEvent)
+{
+ mir_cslock lck(m_csDbAccess);
+ DBEvent *dbe = AdaptEvent((DWORD)hDbEvent, INVALID_CONTACT_ID);
+ return (dbe->signature != DBEVENT_SIGNATURE) ? INVALID_CONTACT_ID : dbe->contactID;
+}
+
+STDMETHODIMP_(HANDLE) CDbxMdb::FindFirstEvent(MCONTACT contactID)
+{
+ DBCachedContact *cc;
+
+ mir_cslock lck(m_csDbAccess);
+ DBContact *dbc = NULL;
+ if (dbc->signature != DBCONTACT_SIGNATURE)
+ return NULL;
+ if (!cc || !cc->IsSub())
+ return HANDLE(dbc->ofsFirstEvent);
+
+ if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
+ return NULL;
+ dbc = NULL;
+ if (dbc->signature != DBCONTACT_SIGNATURE)
+ return NULL;
+
+ for (DWORD dwOffset = dbc->ofsFirstEvent; dwOffset != 0;) {
+ DBEvent *dbe = AdaptEvent(dwOffset, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (dbe->contactID == contactID)
+ return HANDLE(dwOffset);
+ dwOffset = dbe->ofsNext;
+ }
+ return NULL;
+}
+
+STDMETHODIMP_(HANDLE) CDbxMdb::FindFirstUnreadEvent(MCONTACT contactID)
+{
+ DBCachedContact *cc;
+
+ mir_cslock lck(m_csDbAccess);
+ DBContact *dbc = NULL;
+ if (dbc->signature != DBCONTACT_SIGNATURE)
+ return NULL;
+ if (!cc || !cc->IsSub())
+ return HANDLE(dbc->ofsFirstUnread);
+
+ if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
+ return NULL;
+ dbc = NULL;
+ if (dbc->signature != DBCONTACT_SIGNATURE)
+ return NULL;
+
+ for (DWORD dwOffset = dbc->ofsFirstUnread; dwOffset != 0;) {
+ DBEvent *dbe = AdaptEvent(dwOffset, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (dbe->contactID == contactID && !dbe->markedRead())
+ return HANDLE(dwOffset);
+ dwOffset = dbe->ofsNext;
+ }
+ return NULL;
+}
+
+STDMETHODIMP_(HANDLE) CDbxMdb::FindLastEvent(MCONTACT contactID)
+{
+ DBCachedContact *cc;
+
+ mir_cslock lck(m_csDbAccess);
+ DBContact *dbc = NULL;
+ if (dbc->signature != DBCONTACT_SIGNATURE)
+ return NULL;
+ if (!cc || !cc->IsSub())
+ return HANDLE(dbc->ofsLastEvent);
+
+ if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
+ return NULL;
+ dbc = NULL;
+ if (dbc->signature != DBCONTACT_SIGNATURE)
+ return NULL;
+
+ for (DWORD dwOffset = dbc->ofsLastEvent; dwOffset != 0;) {
+ DBEvent *dbe = AdaptEvent(dwOffset, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (dbe->contactID == contactID)
+ return HANDLE(dwOffset);
+ dwOffset = dbe->ofsPrev;
+ }
+ return NULL;
+}
+
+STDMETHODIMP_(HANDLE) CDbxMdb::FindNextEvent(MCONTACT contactID, HANDLE hDbEvent)
+{
+ DBCachedContact *cc = (contactID) ? m_cache->GetCachedContact(contactID) : NULL;
+
+ mir_cslock lck(m_csDbAccess);
+ DBEvent *dbe = AdaptEvent((DWORD)hDbEvent, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (!cc || !cc->IsSub())
+ return HANDLE(dbe->ofsNext);
+
+ for (DWORD dwOffset = dbe->ofsNext; dwOffset != 0;) {
+ dbe = AdaptEvent(dwOffset, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (dbe->contactID == contactID)
+ return HANDLE(dwOffset);
+ dwOffset = dbe->ofsNext;
+ }
+ return NULL;
+}
+
+STDMETHODIMP_(HANDLE) CDbxMdb::FindPrevEvent(MCONTACT contactID, HANDLE hDbEvent)
+{
+ DBCachedContact *cc = (contactID) ? m_cache->GetCachedContact(contactID) : NULL;
+
+ mir_cslock lck(m_csDbAccess);
+ DBEvent *dbe = AdaptEvent((DWORD)hDbEvent, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (!cc || !cc->IsSub())
+ return HANDLE(dbe->ofsPrev);
+
+ for (DWORD dwOffset = dbe->ofsPrev; dwOffset != 0;) {
+ dbe = AdaptEvent(dwOffset, contactID);
+ if (dbe->signature != DBEVENT_SIGNATURE)
+ return NULL;
+ if (dbe->contactID == contactID)
+ return HANDLE(dwOffset);
+ dwOffset = dbe->ofsPrev;
+ }
+ return NULL;
+}
+
+DBEvent* CDbxMdb::AdaptEvent(DWORD ofs, DWORD dwContactID)
+{
+ return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// low-level history cleaner
+
+int CDbxMdb::WipeContactHistory(DBContact *dbc)
+{
+ // drop subContact's history if any
+ dbc->eventCount = 0; dbc->ofsFirstEvent = dbc->ofsLastEvent = dbc->ofsFirstUnread = dbc->tsFirstUnread = 0;
+ return 0;
+}
|