Added CSV parsing and export of Symbian-format Event logs that have had their tables...
[qwerkisync] / EventParsers / VMGParser.cpp
1 /*
2  * Copyright (C) 2011, Jamie Thompson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 3 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18
19 #include "VMGParser.h"
20
21 #include "EventParsers/VMGEntities/Factory.h"
22 #include "EventParsers/VMGEntities/iReader.h"
23 #include "EventTypes/SMS.h"
24
25 #include <QDebug>
26
27 #include <QFile>
28 #include <QHash>
29 #include <QList>
30 #include <QString>
31 #include <QStringList>
32
33 #include <stdexcept>
34
35 using namespace EventParsers;
36
37 iEventParser *VMGParser::IsValid(const Settings &settings, QFile &eventFile)
38 {
39         qDebug() << "Checking if a VMG file...";
40
41         char fileIDBuf[0x16];
42         qint64 bytesRead(eventFile.read(fileIDBuf, sizeof(fileIDBuf) - 1));
43         eventFile.seek(0);
44         if(bytesRead == sizeof(fileIDBuf) - 1)
45         {
46                 // This is the string BEGIN:VMSG<LF> in little-endian UTF16.
47                 char signatureVMG[] = { 0x42, 0x00, 0x45, 0x00, 0x47, 0x00,
48                                                                 0x49, 0x00, 0x4E, 0x00, 0x3A, 0x00,
49                                                                 0x56, 0x00, 0x4D, 0x00, 0x53, 0x00,
50                                                                 0x47, 0x00, 0x0A, 0x00 };
51
52                 if(memcmp(fileIDBuf, signatureVMG, sizeof(fileIDBuf) - 1) == 0)
53                 {
54                         qDebug() << eventFile.fileName() << " is a VMG file.";
55                         return new VMGParser(settings, eventFile.fileName());
56                 }
57                 else
58                 {
59                         QString hexs;
60                         for(int i(0); i<0x16; ++i)
61                                 hexs.append(QString::number(fileIDBuf[i], 16).rightJustified(2, '0'));
62                         qDebug() << eventFile.fileName() << " has bad signature: " << hexs;
63                 }
64         }
65         else
66                 qDebug() << eventFile.fileName() << " has size mismatch.";
67
68         return false;
69 }
70
71 VMGParser::VMGParser(const Settings &settings, const QString &filename) : m_Settings(settings)
72 {
73 }
74
75 EventTypes::EventFromFileList VMGParser::ParseFile(QFile &eventFile, const QList<uint> &recordsToReturn)
76 {
77         EventTypes::EventFromFileList retList;
78
79         // VMGs only support single events per file
80         if(recordsToReturn.count() == 0 || recordsToReturn.contains(0))
81         {
82                 // VMG files are stored in Little-Endian UTF16, with no BOM.
83                 QTextStream eventStream(&eventFile);
84                 eventStream.setCodec("UTF-16LE");
85
86                 // Parse the event
87                 EventTypes::SMS *event(new EventTypes::SMS(CurrentSettings()));
88                 QString lineData = eventStream.readLine();
89                 EventParsers::VMGEntities::iReader* reader = EventParsers::VMGEntities::Factory::Instantiate(CurrentSettings(), lineData, NULL);
90                 bool valid(NULL != reader && reader->Read(QString(""), eventStream, *event));
91                 delete reader;
92                 if (!valid)
93                         throw std::runtime_error(QString("Unsupported format. Unable to open: %1").arg(eventFile.fileName()).toStdString());
94
95                 qDebug() << "\nParsed event:";
96                 qDebug() << event;
97
98                 retList.append(EventTypes::EventFromFile(QSharedPointer<EventTypes::iEvent>(event), 0));
99         }
100
101         return retList;
102 }