summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-05-23 21:43:02 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-05-23 21:43:02 +0300
commit039d185a5aeb5c65d5ba44af5e7ecb5150a16b75 (patch)
treee976e6d7a953d9a8bb82acd28a34a67a40410ec5
parent0f831226bf437da1eeb42acdb46f4fb3e17fa2bd (diff)
fixes #1906 (Import: h++ pattern doesn't work)
-rw-r--r--plugins/Import/ini/historypp.ini1
-rw-r--r--plugins/Import/src/patterns.cpp69
-rw-r--r--plugins/Import/src/stdafx.h3
3 files changed, 69 insertions, 4 deletions
diff --git a/plugins/Import/ini/historypp.ini b/plugins/Import/ini/historypp.ini
new file mode 100644
index 0000000000..7d5e353e48
--- /dev/null
+++ b/plugins/Import/ini/historypp.ini
@@ -0,0 +1 @@
+[General] Name=History++ pattern Type=1 Charset=UCS2 UseHeader=3 UsePreMsg=1 [Message] Pattern=^\[(\d\d?)\.(\d\d?)\.(\d\d\d?\d?)\s(\d\d?):(\d\d?):(\d\d?)\]\s([^\r\n]+?):$ Direction=7 Day=1 Month=2 Year=3 Hours=4 Minutes=5 Seconds=6 [Header] Pattern=^###\r\n###\s[^\r\n]+?\r\n###\s([^\r\n]+?)\s\([^\r\n]+?:\s([^\r\n]+?)\)\s-\s([^\r\n]+?)\s\([^\r\n]+?:\s([^\r\n]+?)\)\r\n###\s[^\r\n]+?\r\n###\r\n In=3 Out=1 InNick=3 OutNick=1 InUID=4 OutUID=2 [PreMessage] PreRN=1 AfterRN=2 \ No newline at end of file
diff --git a/plugins/Import/src/patterns.cpp b/plugins/Import/src/patterns.cpp
index 7f40a6eafc..511426b675 100644
--- a/plugins/Import/src/patterns.cpp
+++ b/plugins/Import/src/patterns.cpp
@@ -99,6 +99,22 @@ void CMPlugin::LoadPattern(const wchar_t *pwszFileName)
pNew->iSeconds = GetPrivateProfileIntW(L"Message", L"Seconds", 0, pwszFileName);
}
+ if (pNew->iUseHeader) {
+ if (GetPrivateProfileStringW(L"Header", L"Pattern", L"", buf, _countof(buf), pwszFileName)) {
+ if ((pNew->regHeader.pattern = pcre16_compile(buf, PCRE_MULTILINE, &err, &erroffset, nullptr)) == nullptr)
+ return;
+ pNew->regHeader.extra = pcre16_study(pNew->regMessage.pattern, 0, &err);
+ }
+ else return;
+
+ pNew->iHdrIncoming = GetPrivateProfileIntW(L"Header", L"In", 0, pwszFileName);
+ pNew->iHdrOutgoing = GetPrivateProfileIntW(L"Header", L"Out", 0, pwszFileName);
+ pNew->iHdrInNick = GetPrivateProfileIntW(L"Header", L"InNick", 0, pwszFileName);
+ pNew->iHdrOutNick = GetPrivateProfileIntW(L"Header", L"OutNick", 0, pwszFileName);
+ pNew->iHdrInUID = GetPrivateProfileIntW(L"Header", L"InUID", 0, pwszFileName);
+ pNew->iHdrOutUID = GetPrivateProfileIntW(L"Header", L"OutUID", 0, pwszFileName);
+ }
+
if (pNew->iUsePreMsg) {
pNew->preRN = GetPrivateProfileIntW(L"PreMessage", L"PreRN", -1, pwszFileName);
pNew->preSP = GetPrivateProfileIntW(L"PreMessage", L"PreSP", 0, pwszFileName);
@@ -153,8 +169,10 @@ class CDbxPattern : public MDatabaseReadonly, public MZeroedObject
bool LoadBinaryFile(const uint8_t *pFile, uint32_t iSize)
{
- if (memicmp(pFile, "QHF", 3))
+ if (memicmp(pFile, "QHF", 3)) {
+ AddMessage(LPGENW("Invalid file header"));
return false;
+ }
m_iFileVersion = pFile[3];
@@ -219,11 +237,52 @@ class CDbxPattern : public MDatabaseReadonly, public MZeroedObject
break;
}
+
// smth went wrong or empty file
if (m_buf.IsEmpty())
return false;
int iOffset = 0;
+ if (m_buf[0] == 0xFEFF)
+ m_buf.Delete(0);
+
+ if (pPattern->iUseHeader) {
+ int offsets[99];
+ int nMatch = pcre16_exec(pPattern->regHeader.pattern, pPattern->regHeader.extra, m_buf, m_buf.GetLength(), iOffset, PCRE_NEWLINE_ANYCRLF, offsets, _countof(offsets));
+ if (nMatch <= 0) {
+ AddMessage(LPGENW("Cannot parse file header, skipping file"));
+ return false;
+ }
+
+ const wchar_t **substrings;
+ if (pcre16_get_substring_list(m_buf, offsets, nMatch, &substrings) >= 0) {
+ if (pPattern->iUseHeader & 1) {
+ pPattern->wszIncoming = substrings[pPattern->iHdrIncoming];
+ pPattern->wszOutgoing = substrings[pPattern->iHdrOutgoing];
+ }
+
+ if (pPattern->iUseHeader & 2) {
+ DBCONTACTWRITESETTING dbcws = {};
+ dbcws.szModule = "Pattern";
+ dbcws.value.type = DBVT_WCHAR;
+
+ if (pPattern->iInUID && substrings[pPattern->iHdrInUID]) {
+ dbcws.szSetting = "ID";
+ dbcws.value.pwszVal = (wchar_t *)substrings[pPattern->iHdrInUID];
+ WriteContactSetting(m_hCurrContact, &dbcws);
+ }
+
+ if (pPattern->iInNick && substrings[pPattern->iHdrInNick]) {
+ dbcws.szSetting = "Nick";
+ dbcws.value.pwszVal = (wchar_t *)substrings[pPattern->iHdrInNick];
+ WriteContactSetting(m_hCurrContact, &dbcws);
+ }
+ }
+ }
+
+ iOffset = offsets[1];
+ }
+
while (true) {
int offsets[99];
int nMatch = pcre16_exec(pPattern->regMessage.pattern, pPattern->regMessage.extra, m_buf, m_buf.GetLength(), iOffset, PCRE_NEWLINE_ANYCRLF, offsets, _countof(offsets));
@@ -263,22 +322,24 @@ public:
m_events.clear();
Close();
+ AddMessage(LPGENW("Loading file '%s'..."), pwszFileName);
+
m_hFile = ::CreateFileW(pwszFileName, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, 0);
if (m_hFile == INVALID_HANDLE_VALUE) {
- Netlib_Logf(0, "failed to open file <%S> for import: %d", pwszFileName, GetLastError());
+ AddMessage(LPGENW("Failed to open file <%s> for import: %d"), pwszFileName, GetLastError());
return false;
}
uint32_t cbLen = ::GetFileSize(m_hFile, 0);
m_hMap = ::CreateFileMappingW(m_hFile, nullptr, PAGE_READONLY, 0, 0, L"ImportMapfile");
if (m_hMap == nullptr) {
- Netlib_Logf(0, "failed to mmap file <%S> for import: %d", pwszFileName, GetLastError());
+ AddMessage(LPGENW("Failed to mmap file <%s> for import: %d"), pwszFileName, GetLastError());
return false;
}
m_pFile = (const uint8_t*)::MapViewOfFile(m_hMap, FILE_MAP_READ, 0, 0, 0);
if (m_pFile == nullptr) {
- Netlib_Logf(0, "failed to map view of file <%S> for import: %d", pwszFileName, GetLastError());
+ AddMessage(LPGENW("Failed to map view of file <%s> for import: %d"), pwszFileName, GetLastError());
return false;
}
diff --git a/plugins/Import/src/stdafx.h b/plugins/Import/src/stdafx.h
index 43bac7697d..aa53aae8fb 100644
--- a/plugins/Import/src/stdafx.h
+++ b/plugins/Import/src/stdafx.h
@@ -82,6 +82,9 @@ struct CImportPattern : public MZeroedObject
CRegexp regFilename;
int iInNick, iInUID, iOutNick, iOutUID;
+ CRegexp regHeader;
+ int iHdrIncoming, iHdrOutgoing, iHdrInNick, iHdrOutNick, iHdrInUID, iHdrOutUID;
+
// symbols pre & after a messages
int preRN, afterRN, preSP, afterSP;
};