diff options
Diffstat (limited to 'plugins/DbChecker')
-rw-r--r-- | plugins/DbChecker/res/resource.rc | 1 | ||||
-rw-r--r-- | plugins/DbChecker/src/options.cpp | 3 | ||||
-rw-r--r-- | plugins/DbChecker/src/resource.h | 1 | ||||
-rw-r--r-- | plugins/DbChecker/src/stdafx.h | 4 | ||||
-rw-r--r-- | plugins/DbChecker/src/worker.cpp | 54 |
5 files changed, 57 insertions, 6 deletions
diff --git a/plugins/DbChecker/res/resource.rc b/plugins/DbChecker/res/resource.rc index 46f1084e6a..1b3f792c1e 100644 --- a/plugins/DbChecker/res/resource.rc +++ b/plugins/DbChecker/res/resource.rc @@ -47,6 +47,7 @@ BEGIN EDITTEXT IDC_FILENAME,6,50,235,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_OPENFILE,243,49,15,13 CONTROL "Mark all events as read",IDC_MARKREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,69,248,10 + CONTROL "Fix utf-8 encoding in old events",IDC_FIX_UTF8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,83,248,10 END IDD_OPENERROR DIALOGEX 0, 0, 262, 143 diff --git a/plugins/DbChecker/src/options.cpp b/plugins/DbChecker/src/options.cpp index a06a39d1f3..4ac947df57 100644 --- a/plugins/DbChecker/src/options.cpp +++ b/plugins/DbChecker/src/options.cpp @@ -21,6 +21,7 @@ COptionsPageDlg::COptionsPageDlg() : CSuper(IDD_OPTPAGE), edtFile(this, IDC_FILENAME), btnFile(this, IDC_OPENFILE), + chkFixUtf(this, IDC_FIX_UTF8), chkMarkRead(this, IDC_MARKREAD) { } @@ -32,6 +33,7 @@ bool COptionsPageDlg::OnInitDialog() auto *opts = getOpts(); edtFile.SetText(opts->filename); + chkFixUtf.SetState(opts->bCheckUtf); chkMarkRead.SetState(opts->bMarkRead); if (opts->dbChecker != nullptr) { @@ -87,6 +89,7 @@ LBL_Error: opts->db = pDb; } + opts->bCheckUtf = chkFixUtf.GetState(); opts->bMarkRead = chkMarkRead.GetState(); changePage(new CProgressPageDlg()); } diff --git a/plugins/DbChecker/src/resource.h b/plugins/DbChecker/src/resource.h index bc00166ba9..fc35edc169 100644 --- a/plugins/DbChecker/src/resource.h +++ b/plugins/DbChecker/src/resource.h @@ -21,6 +21,7 @@ #define IDC_MARKREAD 1013 #define IDC_FILENAME 1014 #define IDC_OPENFILE 1015 +#define IDC_FIX_UTF8 1016 // Next default values for new objects // diff --git a/plugins/DbChecker/src/stdafx.h b/plugins/DbChecker/src/stdafx.h index b6cbb59ae2..9d2213a64c 100644 --- a/plugins/DbChecker/src/stdafx.h +++ b/plugins/DbChecker/src/stdafx.h @@ -64,7 +64,7 @@ struct DbToolOptions : public MZeroedObject MIDatabaseChecker *dbChecker; DWORD error; HANDLE hEventRun, hEventAbort; - bool bFinished, bAutoExit, bOwnsDb, bMarkRead; + bool bFinished, bAutoExit, bOwnsDb, bMarkRead, bCheckUtf; wchar_t filename[MAX_PATH]; }; @@ -113,7 +113,7 @@ class COptionsPageDlg : public CWizardPageDlg CCtrlEdit edtFile; CCtrlButton btnFile; - CCtrlCheck chkMarkRead; + CCtrlCheck chkMarkRead, chkFixUtf; public: COptionsPageDlg(); diff --git a/plugins/DbChecker/src/worker.cpp b/plugins/DbChecker/src/worker.cpp index a31d723eff..433f9ca386 100644 --- a/plugins/DbChecker/src/worker.cpp +++ b/plugins/DbChecker/src/worker.cpp @@ -21,6 +21,40 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void ProcessingDone(void); +static bool ConvertOldEvent(DBEVENTINFO &dbei) +{ + if (dbei.flags & DBEF_UTF) + return false; + + int msglen = (int)mir_strlen((char *)dbei.pBlob) + 1, msglenW = 0; + if (msglen != (int)dbei.cbBlob) { + int count = ((dbei.cbBlob - msglen) / sizeof(WCHAR)); + WCHAR *p = (WCHAR *)&dbei.pBlob[msglen]; + for (int i = 0; i < count; i++) { + if (p[i] == 0) { + msglenW = i; + break; + } + } + } + + char *utf8str; + if (msglenW > 0 && msglenW <= msglen) + utf8str = mir_utf8encodeW((WCHAR *)&dbei.pBlob[msglen]); + else + utf8str = mir_utf8encode((char *)dbei.pBlob); + + if (utf8str == nullptr) + return false; + + mir_free(dbei.pBlob); + + dbei.flags |= DBEF_UTF; + dbei.cbBlob = (DWORD)mir_strlen(utf8str); + dbei.pBlob = (PBYTE)utf8str; + return true; +} + void __cdecl WorkerThread(DbToolOptions *opts) { time_t ts = time(nullptr); @@ -29,25 +63,37 @@ void __cdecl WorkerThread(DbToolOptions *opts) DWORD sp = 0; - if (opts->bMarkRead) { - int nCount = 0; + if (opts->bMarkRead || opts->bCheckUtf) { + int nCount = 0, nUtfCount = 0; for (auto &cc : Contacts()) { DB::ECPTR pCursor(DB::Events(cc)); while (MEVENT hEvent = pCursor.FetchNext()) { - DBEVENTINFO dbei = {}; + DB::EventInfo dbei; + if (opts->bCheckUtf) // read also event's body + dbei.cbBlob = -1; if (db_event_get(hEvent, &dbei)) continue; - if (!dbei.markedRead()) { + if (opts->bMarkRead && !dbei.markedRead()) { db_event_markRead(cc, hEvent); nCount++; } + + if (opts->bCheckUtf && dbei.eventType == EVENTTYPE_MESSAGE) { + if (ConvertOldEvent(dbei)) { + db_event_edit(cc, hEvent, &dbei); + nUtfCount++; + } + } } } if (nCount) AddToStatus(STATUS_MESSAGE, TranslateT("%d events marked as read"), nCount); + + if (nUtfCount) + AddToStatus(STATUS_MESSAGE, TranslateT("Utf-8 encoding fixed in %d events"), nUtfCount); } DBCHeckCallback callback; |