Fixed Symbian CSV parsing to handle UTF16-encoded files correctly.
authorJamie Thompson <jamie@.(none)>
Thu, 25 Aug 2011 00:50:56 +0000 (01:50 +0100)
committerJamie Thompson <jamie@.(none)>
Thu, 25 Aug 2011 00:50:56 +0000 (01:50 +0100)
EventParsers/CSVSymbianEventLogParser.cpp
EventParsers/CSVSymbianEventLogParser.h

index 926a247..b73d7df 100644 (file)
@@ -33,7 +33,7 @@ using namespace EventParsers;
 class SortByValueDesc
 {
 public:
-       inline bool operator()(const QPair<char, uint> &a, const QPair<char, uint> &b) const
+       inline bool operator()(const QPair<QChar, uint> &a, const QPair<QChar, uint> &b) const
        {
                return b.second < a.second;
        }
@@ -50,30 +50,32 @@ iEventParser *CSVSymbianEventLogParser::IsValid(const Settings &currentSettings,
 {
        qDebug() << "Checking if a CSV call log file...";
 
-       QByteArray firstLineContent(eventFile.readLine());
+       QTextStream stream(&eventFile);
+
+       QString firstLineContent(stream.readLine());
        eventFile.seek(0);
        if(firstLineContent.length() > 0)
        {
                // Count the non-alphanumeric characters used
-               QHash<char, uint> counts;
-               foreach(char c, firstLineContent)
+               QHash<QChar, uint> counts;
+               foreach(const QChar c, firstLineContent)
                        ++counts[c];
 
-               QList<QPair<char, uint> > orderedCounts;
+               QList<QPair<QChar, uint> > orderedCounts;
                orderedCounts.reserve(counts.size());
-               foreach(char c, counts.keys())
+               foreach(const QChar c, counts.keys())
                        if(!QChar(c).isLetterOrNumber())
-                               orderedCounts.append(QPair<char, uint>(c, counts.value(c)));
+                               orderedCounts.append(QPair<QChar, uint>(c, counts.value(c)));
 
                qSort(orderedCounts.begin(), orderedCounts.end(), SortByValueDesc());
 
                // Work around Q_FOREACH macro limitation when dealing with
                // multi-typed templates (comma issue)
-               typedef QPair<char, uint> bodge;
+               typedef QPair<QChar, uint> bodge;
                foreach(bodge count, orderedCounts)
                        qDebug() << count.first << " = " << count.second;
 
-               char delim;
+               QChar delim;
                // No-one would be mad enough to use quotation marks or apostrophes
                // as their delimiter,but just in case, check the second most
                // frequent character is present thr right number of times for
@@ -123,7 +125,7 @@ iEventParser *CSVSymbianEventLogParser::IsValid(const Settings &currentSettings,
        return NULL;
 }
 
-CSVSymbianEventLogParser::CSVSymbianEventLogParser(const Settings &settings, const QString &filename, const char delimiter, const int numColumnsPerRecord, const ColumnIndicesHash &headingIndices)
+CSVSymbianEventLogParser::CSVSymbianEventLogParser(const Settings &settings, const QString &filename, const QChar delimiter, const int numColumnsPerRecord, const ColumnIndicesHash &headingIndices)
        : m_Settings(settings), m_Delimiter(delimiter), m_NumColumnsPerRecord(numColumnsPerRecord), m_HeadingIndices(headingIndices)
 {
 }
@@ -141,25 +143,26 @@ EventTypes::EventFromFileList CSVSymbianEventLogParser::ParseFile(QFile &eventFi
        eventFile.seek(0);
 
        // Read the first line
-       QByteArray firstLineContent(eventFile.readLine());
+       QTextStream stream(&eventFile);
+       QString firstLineContent(stream.readLine());
        QStringList firstLineValues(QString(firstLineContent).split(m_Delimiter));
        if(firstLineValues.count() != m_NumColumnsPerRecord)
                throw new std::runtime_error(QString("Unexpected number of columns (%1, expected %2) on line %3 of %4")
                        .arg(firstLineValues.count())
-                        .arg(m_NumColumnsPerRecord)
-                        .arg(lineNumber)
-                        .arg(eventFile.fileName()).toStdString());
+                       .arg(m_NumColumnsPerRecord)
+                       .arg(lineNumber)
+                       .arg(eventFile.fileName()).toStdString());
        ++lineNumber;
 
        // Read the main body of the file
-       while(!eventFile.atEnd())
+       while(!stream.atEnd())
        {
-               QStringList lineValues(QString(eventFile.readLine()).split(m_Delimiter));
+               QStringList lineValues(QString(stream.readLine()).split(m_Delimiter));
                ++lineNumber;
                // Make sure we have enough columns (i.e. handle newlines in values)
                while(lineValues.count() < m_NumColumnsPerRecord)
                {
-                       lineValues.append(QString(eventFile.readLine()).split(m_Delimiter));
+                       lineValues.append(QString(stream.readLine()).split(m_Delimiter));
                        ++lineNumber;
                }
 
index 5441647..102d210 100644 (file)
@@ -23,6 +23,7 @@
 class Settings;
 
 #include <QHash>
+class QChar;
 class QFile;
 class QString;
 
@@ -35,7 +36,7 @@ namespace EventParsers
 
                static iEventParser *IsValid(const Settings &currentSettings, QFile &eventFile);
 
-               CSVSymbianEventLogParser(const Settings &currentSettings, const QString &filename, const char delimiter, const int numColumnsPerRecord, const ColumnIndicesHash &columns);
+               CSVSymbianEventLogParser(const Settings &currentSettings, const QString &filename, const QChar delimiter, const int numColumnsPerRecord, const ColumnIndicesHash &columns);
 
                virtual EventTypes::EventFromFileList ParseFile(QFile &eventFile, const QList<unsigned int> &recordsToReturn);
 
@@ -44,7 +45,7 @@ namespace EventParsers
 
        private:
                const Settings &m_Settings;
-               const char m_Delimiter;
+               const QChar m_Delimiter;
                const int m_NumColumnsPerRecord;
                const ColumnIndicesHash m_HeadingIndices;
        };