summaryrefslogtreecommitdiff
path: root/plugins/BasicHistory/DatExport.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2012-06-05 19:31:43 +0000
committerGeorge Hazan <george.hazan@gmail.com>2012-06-05 19:31:43 +0000
commit528949c71a12f54dc7b71133a32d9ee91cb53298 (patch)
treea2b57251631adf14f00a4d775b6894da06f670fc /plugins/BasicHistory/DatExport.cpp
parenta6fb825ecbf5313b010fd8cf37754f494cabddc5 (diff)
BasicHistory - the alternative for history++
git-svn-id: http://svn.miranda-ng.org/main/trunk@317 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/BasicHistory/DatExport.cpp')
-rw-r--r--plugins/BasicHistory/DatExport.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/plugins/BasicHistory/DatExport.cpp b/plugins/BasicHistory/DatExport.cpp
new file mode 100644
index 0000000000..bd74546393
--- /dev/null
+++ b/plugins/BasicHistory/DatExport.cpp
@@ -0,0 +1,214 @@
+/*
+Basic History plugin
+Copyright (C) 2011-2012 Krzysztof Kral
+
+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 version 2
+of the License.
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "StdAfx.h"
+#include "DatExport.h"
+#include "EventList.h"
+
+#define EXP_FILE (*((std::ofstream*)IExport::stream))
+#define IMP_FILE (*((std::ifstream*)IImport::stream))
+
+std::wstring GetProtocolName(HANDLE hContact);
+std::wstring GetContactId(HANDLE hContact);
+
+#pragma pack(push, 1)
+
+struct MCHeader
+{
+ unsigned char signature[2];
+ unsigned int version;
+ unsigned int dataSize;
+};
+
+#pragma pack(pop)
+
+typedef struct {
+ int cbSize; //size of the structure in bytes
+ DWORD szModule; //pointer to name of the module that 'owns' this
+ //event, ie the one that is in control of the data format
+ DWORD timestamp; //seconds since 00:00, 01/01/1970. Gives us times until
+ //2106 unless you use the standard C library which is
+ //signed and can only do until 2038. In GMT.
+ DWORD flags; //the omnipresent flags
+ WORD eventType; //module-defined event type field
+ DWORD cbBlob; //size of pBlob in bytes
+ DWORD pBlob; //pointer to buffer containing module-defined event data
+} DBEVENTINFO86;
+
+
+DatExport::~DatExport()
+{
+}
+
+
+int DatExport::WriteString(const std::wstring &str)
+{
+ int conv = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length() + 1, NULL, 0, NULL, NULL);
+ if(conv > (int)memBuf.size())
+ {
+ memBuf.resize(conv);
+ }
+
+ conv = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length() + 1, (char*)memBuf.c_str(), conv, NULL, NULL);
+ return conv;
+}
+
+void DatExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding)
+{
+ MCHeader header;
+ memset(&header, 0, sizeof(MCHeader));
+ memcpy(header.signature, "HB", 2);
+ header.version = -1;
+ header.dataSize = 0;
+ dataSize = 0;
+ EXP_FILE.write((char*)&header, sizeof(MCHeader));
+}
+
+void DatExport::WriteFooter()
+{
+ size_t pos = EXP_FILE.tellp();
+ EXP_FILE.seekp(offsetof(MCHeader, dataSize), std::ios_base::beg);
+ EXP_FILE.write((char*)&dataSize, sizeof(dataSize));
+ EXP_FILE.seekp(pos, std::ios_base::beg);
+ memBuf.resize(0);
+#ifdef _WIN64
+ memBuf.shrink_to_fit();
+#endif
+}
+
+void DatExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText)
+{
+}
+
+void DatExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei)
+{
+ DBEVENTINFO86 header;
+ header.cbSize = sizeof(DBEVENTINFO86);
+ header.eventType = dbei.eventType;
+ header.flags = dbei.flags & (~(0x800));
+ header.timestamp = dbei.timestamp;
+ header.szModule = 0;
+ header.pBlob = 0;
+ if(dbei.flags & 0x800)
+ {
+ //Imported
+ header.flags |= DBEF_UTF;
+ header.cbBlob = WriteString(message);
+ EXP_FILE.write((char*)&header, header.cbSize);
+ EXP_FILE.write(memBuf.c_str(), header.cbBlob);
+ }
+ else
+ {
+ //Internal
+ header.cbBlob = dbei.cbBlob;
+ EXP_FILE.write((char*)&header, header.cbSize);
+ EXP_FILE.write((char*)dbei.pBlob, header.cbBlob);
+ }
+
+ dataSize += header.cbSize + header.cbBlob;
+}
+
+bool ReadHeader(MCHeader& header, std::istream* stream)
+{
+ stream->read((char*)&header, sizeof(MCHeader));
+ if(!stream->good())
+ return false;
+ if(memcmp(header.signature, "HB", 2) != 0)
+ return false;
+
+ return true;
+}
+
+int DatExport::IsContactInFile(const std::vector<HANDLE>& contacts)
+{
+ MCHeader header;
+ if(!ReadHeader(header, IImport::stream))
+ return -2;
+
+ if(contacts.size() == 1)
+ {
+ hContact = contacts[0];
+ }
+
+ IMP_FILE.seekg(0, std::ios_base::beg);
+ return -3;
+}
+
+bool DatExport::GetEventList(std::vector<IImport::ExternalMessage>& eventList)
+{
+ MCHeader header;
+ if(!ReadHeader(header, IImport::stream))
+ return false;
+ dataSize = header.dataSize;
+ DBEVENTINFO86 messageHeader;
+ DBEVENTINFO info = {0};
+ info.cbSize = sizeof(DBEVENTINFO);
+ info.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ TCHAR _str[MAXSELECTSTR + 8]; // for safety reason
+ std::multimap<DWORD, IImport::ExternalMessage> sortedEvents;
+ while(dataSize > 0)
+ {
+ messageHeader.cbSize = 0;
+ IMP_FILE.read((char*)&messageHeader, sizeof(DBEVENTINFO86));
+ if(!IMP_FILE.good())
+ return false;
+
+ if(messageHeader.cbSize < sizeof(DBEVENTINFO86))
+ return false;
+
+ if(messageHeader.cbSize > sizeof(DBEVENTINFO86))
+ {
+ IMP_FILE.seekg(messageHeader.cbSize - sizeof(DBEVENTINFO86), std::ios_base::cur);
+ }
+
+ IImport::ExternalMessage exMsg;
+ exMsg.eventType = messageHeader.eventType;
+ exMsg.flags = messageHeader.flags;
+ exMsg.timestamp = messageHeader.timestamp;
+ if(messageHeader.cbBlob > memBuf.size())
+ {
+ memBuf.resize(messageHeader.cbBlob);
+ }
+
+ IMP_FILE.read((char*)memBuf.c_str(), messageHeader.cbBlob);
+ if(!IMP_FILE.good())
+ return false;
+
+ info.eventType = messageHeader.eventType;
+ info.flags = messageHeader.flags;
+ info.timestamp = messageHeader.timestamp;
+ info.cbBlob = messageHeader.cbBlob;
+ info.pBlob = (PBYTE)memBuf.c_str();
+ EventList::GetObjectDescription(&info, _str, MAXSELECTSTR);
+ exMsg.message = _str;
+ sortedEvents.insert(std::pair<DWORD, IImport::ExternalMessage>(messageHeader.timestamp, exMsg));
+ dataSize -= messageHeader.cbSize + messageHeader.cbBlob;
+ }
+
+ memBuf.resize(0);
+#ifdef _WIN64
+ memBuf.shrink_to_fit();
+#endif
+
+ for(std::multimap<DWORD, IImport::ExternalMessage>::iterator it = sortedEvents.begin(); it != sortedEvents.end(); ++it)
+ {
+ eventList.push_back(it->second);
+ }
+
+ return true;
+}