summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2017-11-23 21:08:39 +0300
committerGeorge Hazan <ghazan@miranda.im>2017-11-23 21:08:39 +0300
commit01b51542b22ea4c36001324b6014e3f7667c0981 (patch)
tree7cbd3d36be89dec75649529e441a23d1e3ebe8c1
parentf37c4afa26480bddde72d97c96ae9c8f3ef0ccea (diff)
common database code to be concentrated in mir_app
-rw-r--r--include/m_db_int.h24
-rw-r--r--libs/win32/mir_app.libbin120660 -> 127416 bytes
-rw-r--r--libs/win64/mir_app.libbin115930 -> 122916 bytes
-rw-r--r--plugins/Db3x_mmap/src/dbintf.cpp9
-rw-r--r--plugins/Db3x_mmap/src/dbintf.h13
-rw-r--r--plugins/Db3x_mmap/src/dbsettings.cpp163
-rw-r--r--plugins/Dbx_mdb/src/dbintf.cpp3
-rw-r--r--plugins/Dbx_mdb/src/dbintf.h16
-rw-r--r--plugins/Dbx_mdb/src/dbsettings.cpp134
-rw-r--r--src/mir_app/src/MDatabaseCommon.cpp187
-rw-r--r--src/mir_app/src/mir_app.def22
-rw-r--r--src/mir_app/src/mir_app64.def22
12 files changed, 260 insertions, 333 deletions
diff --git a/include/m_db_int.h b/include/m_db_int.h
index f989e91344..7ab866f884 100644
--- a/include/m_db_int.h
+++ b/include/m_db_int.h
@@ -80,7 +80,7 @@ interface MIDatabaseCache : public MZeroedObject
STDMETHOD_(DBVARIANT*, GetCachedValuePtr)(MCONTACT contactID, char *szSetting, int bAllocate) PURE;
};
-interface MIDatabase
+interface MIR_APP_EXPORT MIDatabase
{
MIDatabaseCache* m_cache;
@@ -128,6 +128,28 @@ interface MIDatabase
STDMETHOD_(BOOL, MetaSplitHistory)(DBCachedContact *ccMeta, DBCachedContact *ccSub) PURE;
};
+class MIR_APP_EXPORT MDatabaseCommon : public MIDatabase
+{
+
+protected:
+ int m_codePage;
+
+ mir_cs m_csDbAccess;
+ LIST<char> m_lResidentSettings;
+
+protected:
+ MDatabaseCommon();
+
+ STDMETHOD_(BOOL, GetContactSettingWorker)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic) PURE;
+
+public:
+ STDMETHODIMP_(BOOL) GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName);
+};
+
///////////////////////////////////////////////////////////////////////////////
// basic database checker interface
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 2ea92d7e51..e6769d1692 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index 15f2c8f7a6..d50aca166c 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/plugins/Db3x_mmap/src/dbintf.cpp b/plugins/Db3x_mmap/src/dbintf.cpp
index 109dfb99da..d43ff7b99c 100644
--- a/plugins/Db3x_mmap/src/dbintf.cpp
+++ b/plugins/Db3x_mmap/src/dbintf.cpp
@@ -39,11 +39,6 @@ static int OfsCompare(const ModuleName *mn1, const ModuleName *mn2)
return (mn1->ofs - mn2->ofs);
}
-static int stringCompare2(const char *p1, const char *p2)
-{
- return mir_strcmp(p1, p2);
-}
-
CDb3Mmap::CDb3Mmap(const wchar_t *tszFileName, int iMode) :
m_hDbFile(INVALID_HANDLE_VALUE),
m_safetyMode(true),
@@ -51,8 +46,7 @@ CDb3Mmap::CDb3Mmap(const wchar_t *tszFileName, int iMode) :
m_bShared((iMode & DBMODE_SHARED) != 0),
m_dwMaxContactId(1),
m_lMods(50, ModCompare),
- m_lOfs(50, OfsCompare),
- m_lResidentSettings(50, stringCompare2)
+ m_lOfs(50, OfsCompare)
{
m_tszProfileName = mir_wstrdup(tszFileName);
InitDbInstance(this);
@@ -61,7 +55,6 @@ CDb3Mmap::CDb3Mmap(const wchar_t *tszFileName, int iMode) :
GetSystemInfo(&sinf);
m_ChunkSize = sinf.dwAllocationGranularity;
- m_codePage = Langpack_GetDefaultCodePage();
m_hModHeap = HeapCreate(0, 0, 0);
}
diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h
index d5ada71747..8155a1758f 100644
--- a/plugins/Db3x_mmap/src/dbintf.h
+++ b/plugins/Db3x_mmap/src/dbintf.h
@@ -181,7 +181,7 @@ struct DBCachedContact : public DBCachedContactBase
DWORD dwOfsContact;
};
-struct CDb3Mmap : public MIDatabase, public MIDatabaseChecker, public MZeroedObject
+struct CDb3Mmap : public MDatabaseCommon, public MIDatabaseChecker, public MZeroedObject
{
CDb3Mmap(const wchar_t *tszFileName, int mode);
~CDb3Mmap();
@@ -234,14 +234,10 @@ public:
STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, const void *pParam);
- STDMETHODIMP_(BOOL) GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic);
STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws);
STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting);
STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, const void *param);
- STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName);
STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, const void *pParam);
STDMETHODIMP_(BOOL) IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting);
@@ -302,8 +298,6 @@ protected:
DWORD m_dwFileSize, m_dwMaxContactId;
HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent, hEventMarkedRead;
- mir_cs m_csDbAccess;
-
int CheckProto(DBCachedContact *cc, const char *proto);
DWORD CreateNewSpace(int bytes);
void DeleteSpace(DWORD ofs, int bytes);
@@ -312,7 +306,6 @@ protected:
////////////////////////////////////////////////////////////////////////////
// settings
- int m_codePage;
HANDLE hService, hHook;
////////////////////////////////////////////////////////////////////////////
@@ -333,7 +326,6 @@ protected:
HANDLE m_hModHeap;
LIST<ModuleName> m_lMods, m_lOfs;
- LIST<char> m_lResidentSettings;
HANDLE hEventAddedEvent, hEventDeletedEvent, hEventFilterAddedEvent;
MCONTACT m_hLastCachedContact;
ModuleName *m_lastmn;
@@ -356,7 +348,6 @@ protected:
DWORD ConvertModuleNameOfs(DWORD ofsOld);
void ConvertOldEvent(DBEvent*& dbei);
- int GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic);
int WorkSettingsChain(DBContact *dbc, int firstTime);
int WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime);
diff --git a/plugins/Db3x_mmap/src/dbsettings.cpp b/plugins/Db3x_mmap/src/dbsettings.cpp
index 8fd9a1dde3..3f22540b21 100644
--- a/plugins/Db3x_mmap/src/dbsettings.cpp
+++ b/plugins/Db3x_mmap/src/dbsettings.cpp
@@ -63,18 +63,8 @@ int CDb3Mmap::GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCST
// the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name
int settingNameLen = (int)mir_strlen(szSetting);
int moduleNameLen = (int)mir_strlen(szModule);
- if (settingNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("GetContactSettingWorker() got a > 255 setting name length. \n");
-#endif
- return 1;
- }
- if (moduleNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("GetContactSettingWorker() got a > 255 module name length. \n");
-#endif
+ if (settingNameLen > 0xFE || moduleNameLen > 0xFE)
return 1;
- }
mir_cslock lck(m_csDbAccess);
@@ -246,157 +236,6 @@ LBL_Seek:
return 1;
}
-STDMETHODIMP_(BOOL) CDb3Mmap::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- dbv->type = 0;
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
- return 1;
-
- if (dbv->type == DBVT_UTF8) {
- WCHAR *tmp = nullptr;
- char *p = NEWSTR_ALLOCA(dbv->pszVal);
- if (mir_utf8decode(p, &tmp) != nullptr) {
- BOOL bUsed = FALSE;
- int result = WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, nullptr, 0, nullptr, &bUsed);
-
- mir_free(dbv->pszVal);
-
- if (bUsed || result == 0) {
- dbv->type = DBVT_WCHAR;
- dbv->pwszVal = tmp;
- }
- else {
- dbv->type = DBVT_ASCIIZ;
- dbv->pszVal = (char *)mir_alloc(result);
- WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dbv->pszVal, result, nullptr, nullptr);
- mir_free(tmp);
- }
- }
- else {
- dbv->type = DBVT_ASCIIZ;
- mir_free(tmp);
- }
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDb3Mmap::GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- int iSaveType = dbv->type;
-
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
- return 1;
-
- if (iSaveType == 0 || iSaveType == dbv->type)
- return 0;
-
- if (dbv->type != DBVT_ASCIIZ && dbv->type != DBVT_UTF8)
- return 1;
-
- if (iSaveType == DBVT_WCHAR) {
- if (dbv->type != DBVT_UTF8) {
- int len = MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, nullptr, 0);
- wchar_t* wszResult = (wchar_t*)mir_alloc((len + 1)*sizeof(wchar_t));
- if (wszResult == nullptr)
- return 1;
-
- MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, wszResult, len);
- wszResult[len] = 0;
- mir_free(dbv->pszVal);
- dbv->pwszVal = wszResult;
- }
- else {
- char* savePtr = NEWSTR_ALLOCA(dbv->pszVal);
- mir_free(dbv->pszVal);
- if (!mir_utf8decode(savePtr, &dbv->pwszVal))
- return 1;
- }
- }
- else if (iSaveType == DBVT_UTF8) {
- char* tmpBuf = mir_utf8encode(dbv->pszVal);
- if (tmpBuf == nullptr)
- return 1;
-
- mir_free(dbv->pszVal);
- dbv->pszVal = tmpBuf;
- }
- else if (iSaveType == DBVT_ASCIIZ)
- mir_utf8decode(dbv->pszVal, nullptr);
-
- dbv->type = iSaveType;
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDb3Mmap::GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- bool bNeedsWchars;
- size_t cbSaved;
-
- if (dbv->type == DBVT_WCHAR) { // there's no wchar_t strings in a database, we need conversion
- cbSaved = dbv->cchVal-1;
- dbv->cchVal *= sizeof(wchar_t); // extend a room for the utf8 string
- dbv->type = DBVT_UTF8;
- bNeedsWchars = true;
- }
- else bNeedsWchars = false;
-
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 1))
- return 1;
-
- if (bNeedsWchars) {
- char *pBuf = NEWSTR_ALLOCA(dbv->pszVal);
- int cbLen = Utf8toUcs2(pBuf, dbv->cchVal, dbv->pwszVal, cbSaved);
- if (cbLen < 0)
- return 1;
-
- dbv->pwszVal[cbLen] = 0;
- }
- else if (dbv->type == DBVT_UTF8) {
- mir_utf8decode(dbv->pszVal, nullptr);
- dbv->type = DBVT_ASCIIZ;
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDb3Mmap::FreeVariant(DBVARIANT *dbv)
-{
- if (dbv == nullptr) return 1;
-
- switch (dbv->type) {
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- case DBVT_WCHAR:
- if (dbv->pszVal) mir_free(dbv->pszVal);
- dbv->pszVal = nullptr;
- break;
- case DBVT_BLOB:
- if (dbv->pbVal) mir_free(dbv->pbVal);
- dbv->pbVal = nullptr;
- break;
- }
- dbv->type = 0;
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDb3Mmap::SetSettingResident(BOOL bIsResident, const char *pszSettingName)
-{
- char *szSetting = m_cache->GetCachedSetting(nullptr, pszSettingName, 0, (int)mir_strlen(pszSettingName));
- szSetting[-1] = (char)bIsResident;
-
- mir_cslock lck(m_csDbAccess);
- int idx = m_lResidentSettings.getIndex(szSetting);
- if (idx == -1) {
- if (bIsResident)
- m_lResidentSettings.insert(szSetting);
- }
- else if (!bIsResident)
- m_lResidentSettings.remove(idx);
-
- return 0;
-}
-
STDMETHODIMP_(BOOL) CDb3Mmap::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws)
{
if (dbcws == nullptr || dbcws->szSetting == nullptr || dbcws->szModule == nullptr || m_bReadOnly)
diff --git a/plugins/Dbx_mdb/src/dbintf.cpp b/plugins/Dbx_mdb/src/dbintf.cpp
index 2d2d01d7cd..4b5ea4045c 100644
--- a/plugins/Dbx_mdb/src/dbintf.cpp
+++ b/plugins/Dbx_mdb/src/dbintf.cpp
@@ -27,7 +27,6 @@ CDbxMdb::CDbxMdb(const TCHAR *tszFileName, int iMode) :
m_safetyMode(true),
m_bReadOnly((iMode & DBMODE_READONLY) != 0),
m_bShared((iMode & DBMODE_SHARED) != 0),
- m_lResidentSettings(50, strcmp),
m_maxContactId(1)
{
m_tszProfileName = mir_wstrdup(tszFileName);
@@ -37,8 +36,6 @@ CDbxMdb::CDbxMdb(const TCHAR *tszFileName, int iMode) :
mdbx_env_set_maxdbs(m_pMdbEnv, 10);
mdbx_env_set_userctx(m_pMdbEnv, this);
// mdbx_env_set_assert(m_pMdbEnv, LMDBX_FailAssert);
-
- m_codePage = Langpack_GetDefaultCodePage();
}
CDbxMdb::~CDbxMdb()
diff --git a/plugins/Dbx_mdb/src/dbintf.h b/plugins/Dbx_mdb/src/dbintf.h
index d97f11855c..8c93379094 100644
--- a/plugins/Dbx_mdb/src/dbintf.h
+++ b/plugins/Dbx_mdb/src/dbintf.h
@@ -125,7 +125,7 @@ struct EventItem
MEVENT eventId;
};
-struct CDbxMdb : public MIDatabase, public MIDatabaseChecker, public MZeroedObject
+struct CDbxMdb : public MDatabaseCommon, public MIDatabaseChecker, public MZeroedObject
{
friend class LMDBEventCursor;
@@ -176,14 +176,10 @@ public:
STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, const void *pParam);
- STDMETHODIMP_(BOOL) GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic);
STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws);
STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting);
STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, const void *param);
- STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName);
STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, const void *pParam);
STDMETHODIMP_(BOOL) IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting);
@@ -230,11 +226,8 @@ protected:
MDBX_dbi m_dbSettings;
MDBX_cursor *m_curSettings;
- int m_codePage;
HANDLE hService, hHook;
- LIST<char> m_lResidentSettings;
-
////////////////////////////////////////////////////////////////////////////
// contacts
@@ -270,10 +263,6 @@ protected:
uint32_t GetModuleID(const char *szName);
char* GetModuleName(uint32_t dwId);
-
- int GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic);
-
-
DBCHeckCallback *cb;
////////////////////////////////////////////////////////////////////////////
@@ -283,7 +272,6 @@ protected:
int InitCrypt(void);
CRYPTO_PROVIDER* SelectProvider();
- void GenerateNewKey();
void InitDialogs();
}; \ No newline at end of file
diff --git a/plugins/Dbx_mdb/src/dbsettings.cpp b/plugins/Dbx_mdb/src/dbsettings.cpp
index 711b0b45a3..14f6f7d3c5 100644
--- a/plugins/Dbx_mdb/src/dbsettings.cpp
+++ b/plugins/Dbx_mdb/src/dbsettings.cpp
@@ -222,140 +222,6 @@ LBL_Seek:
return 0;
}
-STDMETHODIMP_(BOOL) CDbxMdb::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- dbv->type = 0;
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
- return 1;
-
- if (dbv->type == DBVT_UTF8)
- {
- WCHAR *tmp = NULL;
- char *p = NEWSTR_ALLOCA(dbv->pszVal);
- if (mir_utf8decode(p, &tmp) != NULL)
- {
- BOOL bUsed = FALSE;
- int result = WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed);
-
- mir_free(dbv->pszVal);
-
- if (bUsed || result == 0) {
- dbv->type = DBVT_WCHAR;
- dbv->pwszVal = tmp;
- }
- else {
- dbv->type = DBVT_ASCIIZ;
- dbv->pszVal = (char *)mir_alloc(result);
- WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dbv->pszVal, result, NULL, NULL);
- mir_free(tmp);
- }
- }
- else
- {
- dbv->type = DBVT_ASCIIZ;
- mir_free(tmp);
- }
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxMdb::GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- int iSaveType = dbv->type;
-
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
- return 1;
-
- if (iSaveType == 0 || iSaveType == dbv->type)
- return 0;
-
- if (dbv->type != DBVT_ASCIIZ && dbv->type != DBVT_UTF8)
- return 1;
-
- if (iSaveType == DBVT_WCHAR) {
- if (dbv->type != DBVT_UTF8) {
- int len = MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, NULL, 0);
- wchar_t *wszResult = (wchar_t*)mir_alloc((len + 1)*sizeof(wchar_t));
- if (wszResult == NULL)
- return 1;
-
- MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, wszResult, len);
- wszResult[len] = 0;
- mir_free(dbv->pszVal);
- dbv->pwszVal = wszResult;
- }
- else {
- char* savePtr = NEWSTR_ALLOCA(dbv->pszVal);
- mir_free(dbv->pszVal);
- if (!mir_utf8decode(savePtr, &dbv->pwszVal))
- return 1;
- }
- }
- else if (iSaveType == DBVT_UTF8) {
- char* tmpBuf = mir_utf8encode(dbv->pszVal);
- if (tmpBuf == NULL)
- return 1;
-
- mir_free(dbv->pszVal);
- dbv->pszVal = tmpBuf;
- }
- else if (iSaveType == DBVT_ASCIIZ)
- mir_utf8decode(dbv->pszVal, NULL);
-
- dbv->type = iSaveType;
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxMdb::GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 1))
- return 1;
-
- if (dbv->type == DBVT_UTF8) {
- mir_utf8decode(dbv->pszVal, NULL);
- dbv->type = DBVT_ASCIIZ;
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxMdb::FreeVariant(DBVARIANT *dbv)
-{
- if (dbv == 0) return 1;
-
- switch (dbv->type) {
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- case DBVT_WCHAR:
- if (dbv->pszVal) mir_free(dbv->pszVal);
- dbv->pszVal = 0;
- break;
- case DBVT_BLOB:
- if (dbv->pbVal) mir_free(dbv->pbVal);
- dbv->pbVal = 0;
- break;
- }
- dbv->type = 0;
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxMdb::SetSettingResident(BOOL bIsResident, const char *pszSettingName)
-{
- char *szSetting = m_cache->GetCachedSetting(NULL, pszSettingName, 0, (int)strlen(pszSettingName));
- szSetting[-1] = (char)bIsResident;
-
- int idx = m_lResidentSettings.getIndex(szSetting);
- if (idx == -1) {
- if (bIsResident)
- m_lResidentSettings.insert(szSetting);
- }
- else if (!bIsResident)
- m_lResidentSettings.remove(idx);
-
- return 0;
-}
-
STDMETHODIMP_(BOOL) CDbxMdb::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws)
{
if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL || m_bReadOnly)
diff --git a/src/mir_app/src/MDatabaseCommon.cpp b/src/mir_app/src/MDatabaseCommon.cpp
new file mode 100644
index 0000000000..66e16968c4
--- /dev/null
+++ b/src/mir_app/src/MDatabaseCommon.cpp
@@ -0,0 +1,187 @@
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-17 Miranda NG project,
+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 "stdafx.h"
+#include "database.h"
+
+static int stringCompare2(const char *p1, const char *p2)
+{
+ return mir_strcmp(p1, p2);
+}
+
+MDatabaseCommon::MDatabaseCommon() :
+ m_lResidentSettings(50, stringCompare2)
+{
+ m_codePage = Langpack_GetDefaultCodePage();
+}
+
+STDMETHODIMP_(BOOL) MDatabaseCommon::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
+{
+ dbv->type = 0;
+ if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
+ return 1;
+
+ if (dbv->type == DBVT_UTF8) {
+ WCHAR *tmp = nullptr;
+ char *p = NEWSTR_ALLOCA(dbv->pszVal);
+ if (mir_utf8decode(p, &tmp) != nullptr) {
+ BOOL bUsed = FALSE;
+ int result = WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, nullptr, 0, nullptr, &bUsed);
+
+ mir_free(dbv->pszVal);
+
+ if (bUsed || result == 0) {
+ dbv->type = DBVT_WCHAR;
+ dbv->pwszVal = tmp;
+ }
+ else {
+ dbv->type = DBVT_ASCIIZ;
+ dbv->pszVal = (char *)mir_alloc(result);
+ WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dbv->pszVal, result, nullptr, nullptr);
+ mir_free(tmp);
+ }
+ }
+ else {
+ dbv->type = DBVT_ASCIIZ;
+ mir_free(tmp);
+ }
+ }
+
+ return 0;
+}
+
+STDMETHODIMP_(BOOL) MDatabaseCommon::GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
+{
+ int iSaveType = dbv->type;
+
+ if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
+ return 1;
+
+ if (iSaveType == 0 || iSaveType == dbv->type)
+ return 0;
+
+ if (dbv->type != DBVT_ASCIIZ && dbv->type != DBVT_UTF8)
+ return 1;
+
+ if (iSaveType == DBVT_WCHAR) {
+ if (dbv->type != DBVT_UTF8) {
+ int len = MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, nullptr, 0);
+ wchar_t* wszResult = (wchar_t*)mir_alloc((len + 1) * sizeof(wchar_t));
+ if (wszResult == nullptr)
+ return 1;
+
+ MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, wszResult, len);
+ wszResult[len] = 0;
+ mir_free(dbv->pszVal);
+ dbv->pwszVal = wszResult;
+ }
+ else {
+ char* savePtr = NEWSTR_ALLOCA(dbv->pszVal);
+ mir_free(dbv->pszVal);
+ if (!mir_utf8decode(savePtr, &dbv->pwszVal))
+ return 1;
+ }
+ }
+ else if (iSaveType == DBVT_UTF8) {
+ char* tmpBuf = mir_utf8encode(dbv->pszVal);
+ if (tmpBuf == nullptr)
+ return 1;
+
+ mir_free(dbv->pszVal);
+ dbv->pszVal = tmpBuf;
+ }
+ else if (iSaveType == DBVT_ASCIIZ)
+ mir_utf8decode(dbv->pszVal, nullptr);
+
+ dbv->type = iSaveType;
+ return 0;
+}
+
+STDMETHODIMP_(BOOL) MDatabaseCommon::GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
+{
+ bool bNeedsWchars;
+ size_t cbSaved;
+
+ if (dbv->type == DBVT_WCHAR) { // there's no wchar_t strings in a database, we need conversion
+ cbSaved = dbv->cchVal - 1;
+ dbv->cchVal *= sizeof(wchar_t); // extend a room for the utf8 string
+ dbv->type = DBVT_UTF8;
+ bNeedsWchars = true;
+ }
+ else bNeedsWchars = false;
+
+ if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 1))
+ return 1;
+
+ if (bNeedsWchars) {
+ char *pBuf = NEWSTR_ALLOCA(dbv->pszVal);
+ int cbLen = Utf8toUcs2(pBuf, dbv->cchVal, dbv->pwszVal, cbSaved);
+ if (cbLen < 0)
+ return 1;
+
+ dbv->pwszVal[cbLen] = 0;
+ }
+ else if (dbv->type == DBVT_UTF8) {
+ mir_utf8decode(dbv->pszVal, nullptr);
+ dbv->type = DBVT_ASCIIZ;
+ }
+
+ return 0;
+}
+
+STDMETHODIMP_(BOOL) MDatabaseCommon::FreeVariant(DBVARIANT *dbv)
+{
+ if (dbv == nullptr) return 1;
+
+ switch (dbv->type) {
+ case DBVT_ASCIIZ:
+ case DBVT_UTF8:
+ case DBVT_WCHAR:
+ if (dbv->pszVal) mir_free(dbv->pszVal);
+ dbv->pszVal = nullptr;
+ break;
+ case DBVT_BLOB:
+ if (dbv->pbVal) mir_free(dbv->pbVal);
+ dbv->pbVal = nullptr;
+ break;
+ }
+ dbv->type = 0;
+ return 0;
+}
+
+STDMETHODIMP_(BOOL) MDatabaseCommon::SetSettingResident(BOOL bIsResident, const char *pszSettingName)
+{
+ char *szSetting = m_cache->GetCachedSetting(nullptr, pszSettingName, 0, (int)mir_strlen(pszSettingName));
+ szSetting[-1] = (char)bIsResident;
+
+ mir_cslock lck(m_csDbAccess);
+ int idx = m_lResidentSettings.getIndex(szSetting);
+ if (idx == -1) {
+ if (bIsResident)
+ m_lResidentSettings.insert(szSetting);
+ }
+ else if (!bIsResident)
+ m_lResidentSettings.remove(idx);
+
+ return 0;
+}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index 4e00ffee6a..90a77bfe25 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -457,3 +457,25 @@ Skin_AddSound @461
Skin_PlaySound @462
Skin_PlaySoundFile @463
Clist_SetStatusMode @464
+??0CProtoIntDlgBase@@QAE@$$QAV0@@Z @465 NONAME
+??0MDatabaseCommon@@IAE@XZ @466 NONAME
+??0MDatabaseCommon@@QAE@$$QAV0@@Z @467 NONAME
+??0MDatabaseCommon@@QAE@ABV0@@Z @468 NONAME
+??0MIDatabase@@QAE@$$QAU0@@Z @469 NONAME
+??0MIDatabase@@QAE@ABU0@@Z @470 NONAME
+??0MIDatabase@@QAE@XZ @471 NONAME
+??0PROTO_INTERFACE@@QAE@$$QAU0@@Z @472 NONAME
+??1MDatabaseCommon@@QAE@XZ @473 NONAME
+??4CProtoIntDlgBase@@QAEAAV0@$$QAV0@@Z @474 NONAME
+??4MDatabaseCommon@@QAEAAV0@$$QAV0@@Z @475 NONAME
+??4MDatabaseCommon@@QAEAAV0@ABV0@@Z @476 NONAME
+??4MIDatabase@@QAEAAU0@$$QAU0@@Z @477 NONAME
+??4MIDatabase@@QAEAAU0@ABU0@@Z @478 NONAME
+??4PROTO_INTERFACE@@QAEAAU0@$$QAU0@@Z @479 NONAME
+??_7MDatabaseCommon@@6B@ @480 NONAME
+??_7MIDatabase@@6B@ @481 NONAME
+?FreeVariant@MDatabaseCommon@@UAGHPAUDBVARIANT@@@Z @482 NONAME
+?GetContactSetting@MDatabaseCommon@@UAGHIPBD0PAUDBVARIANT@@@Z @483 NONAME
+?GetContactSettingStatic@MDatabaseCommon@@UAGHIPBD0PAUDBVARIANT@@@Z @484 NONAME
+?GetContactSettingStr@MDatabaseCommon@@UAGHIPBD0PAUDBVARIANT@@@Z @485 NONAME
+?SetSettingResident@MDatabaseCommon@@UAGHHPBD@Z @486 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index fc4fd13ffe..2bb0247a06 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -457,3 +457,25 @@ Skin_AddSound @461
Skin_PlaySound @462
Skin_PlaySoundFile @463
Clist_SetStatusMode @464
+??0CProtoIntDlgBase@@QEAA@$$QEAV0@@Z @465 NONAME
+??0MDatabaseCommon@@IEAA@XZ @466 NONAME
+??0MDatabaseCommon@@QEAA@$$QEAV0@@Z @467 NONAME
+??0MDatabaseCommon@@QEAA@AEBV0@@Z @468 NONAME
+??0MIDatabase@@QEAA@$$QEAU0@@Z @469 NONAME
+??0MIDatabase@@QEAA@AEBU0@@Z @470 NONAME
+??0MIDatabase@@QEAA@XZ @471 NONAME
+??0PROTO_INTERFACE@@QEAA@$$QEAU0@@Z @472 NONAME
+??1MDatabaseCommon@@QEAA@XZ @473 NONAME
+??4CProtoIntDlgBase@@QEAAAEAV0@$$QEAV0@@Z @474 NONAME
+??4MDatabaseCommon@@QEAAAEAV0@$$QEAV0@@Z @475 NONAME
+??4MDatabaseCommon@@QEAAAEAV0@AEBV0@@Z @476 NONAME
+??4MIDatabase@@QEAAAEAU0@$$QEAU0@@Z @477 NONAME
+??4MIDatabase@@QEAAAEAU0@AEBU0@@Z @478 NONAME
+??4PROTO_INTERFACE@@QEAAAEAU0@$$QEAU0@@Z @479 NONAME
+??_7MDatabaseCommon@@6B@ @480 NONAME
+??_7MIDatabase@@6B@ @481 NONAME
+?FreeVariant@MDatabaseCommon@@UEAAHPEAUDBVARIANT@@@Z @482 NONAME
+?GetContactSetting@MDatabaseCommon@@UEAAHIPEBD0PEAUDBVARIANT@@@Z @483 NONAME
+?GetContactSettingStatic@MDatabaseCommon@@UEAAHIPEBD0PEAUDBVARIANT@@@Z @484 NONAME
+?GetContactSettingStr@MDatabaseCommon@@UEAAHIPEBD0PEAUDBVARIANT@@@Z @485 NONAME
+?SetSettingResident@MDatabaseCommon@@UEAAHHPEBD@Z @486 NONAME