1st attempt at an initial import.
[qwerkisync] / EventParsers / CSVSymbianEventLogParser.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 "CSVSymbianEventLogParser.h"
20
21 #include <QDebug>
22
23 #include <QFile>
24 #include <QString>
25 #include <QStringList>
26
27 using namespace EventParsers;
28
29 class SortByValueDesc
30 {
31 public:
32         inline bool operator()(const QPair<char, uint> &a, const QPair<char, uint> &b) const
33         {
34                 return b.second < a.second;
35         }
36 };
37
38 iEventParser *CSVSymbianEventLogParser::IsValid(QFile &eventFile)
39 {
40         qDebug() << "Checking if a CSV call log file...";
41
42         QByteArray firstLineContent(eventFile.readLine());
43         eventFile.seek(0);
44         if(firstLineContent.length() > 0)
45         {
46                 // Count the non-alphanumeric characters used
47                 QHash<char, uint> counts;
48                 foreach(char c, firstLineContent)
49                         ++counts[c];
50
51                 QList<QPair<char, uint> > orderedCounts;
52                 orderedCounts.reserve(counts.size());
53                 foreach(char c, counts.keys())
54                         if(!QChar(c).isLetterOrNumber())
55                                 orderedCounts.append(QPair<char, uint>(c, counts.value(c)));
56
57                 qSort(orderedCounts.begin(), orderedCounts.end(), SortByValueDesc());
58
59                 // Work around Q_FOREACH macro limitation when dealing with
60                 // multi-typed templates (comma issue)
61                 typedef QPair<char, uint> bodge;
62                 foreach(bodge count, orderedCounts)
63                         qDebug() << count.first << " = " << count.second;
64
65                 char delim;
66                 // No-one would be mad enough to use quotation marks or apostrophes
67                 // as their delimiter,but just in case, check the second most
68                 // frequent character is present thr right number of times for
69                 // the qutation marks to be present on every column heading (two
70                 // per heading, less one as they're seperators)
71                 if((orderedCounts.value(0).first == '"' || orderedCounts.value(0).first == '\'')
72                         && ((orderedCounts.value(0).second / 2) - 1 == orderedCounts.value(1).second ))
73                 {
74                         // We're good.
75                         delim = orderedCounts.value(1).first;
76                 }
77                 else
78                         delim = orderedCounts.value(0).first;
79
80                 // Check we have the essential fields we need, and grab their
81                 // column ordering
82                 QStringList requiredHeadings;
83                 requiredHeadings << "etype" << "etime" << "remote"
84                                                  << "direction" << "duration" << "number";
85
86                 EventParsers::CSVSymbianEventLogParser::ColumnIndicesHash headingPositions;
87                 headingPositions.reserve(requiredHeadings.count());
88
89                 QStringList headings(QString(firstLineContent).split(delim));
90                 for(QStringList::size_type i(0); i < headings.count(); ++i)
91                 {
92                         QRegExp content("^[\"\']?(\\w*)?[\"\']?$");
93                         content.indexIn(headings.value(i).trimmed());
94                         QString heading(content.cap(1));
95                         qDebug() << headings.value(i) << " : " << heading;
96
97                         // Check over the required headings
98                         foreach(QString requiredHeading, requiredHeadings)
99                         {
100                                 if(heading.toLower() == requiredHeading)
101                                 {
102                                         headingPositions[requiredHeading] = i;
103                                         requiredHeadings.removeOne(requiredHeading);
104                                 }
105                         }
106                 }
107
108                 // If we found all of the required headings, continue
109                 if(requiredHeadings.count() == 0)
110                 {
111                         return new EventParsers::CSVSymbianEventLogParser(eventFile.fileName(), headingPositions);
112                 }
113         }
114
115         return NULL;
116 }
117
118 CSVSymbianEventLogParser::CSVSymbianEventLogParser(const QString &filename, const ColumnIndicesHash &columns)
119 {
120 }
121
122 EventTypes::EventFromFileList CSVSymbianEventLogParser::ParseFile(QFile &eventFile, const QList<uint> &recordsToReturn)
123 {
124         qDebug() << "CSV Parsing NYI!";
125         return EventTypes::EventFromFileList();
126 }