From 38ad322fbd50951a6a00b4576ac541b8bbc49c20 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Thu, 5 Jan 2012 21:08:04 +0100 Subject: [PATCH] Improved CSV parser. --- src/Config.h | 4 +- src/Model_FileList.cpp | 88 +++++++++++++++++++++++++++--------------- src/Model_FileList.h | 2 + 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/Config.h b/src/Config.h index 22ffc381..50396968 100644 --- a/src/Config.h +++ b/src/Config.h @@ -29,8 +29,8 @@ #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 4 #define VER_LAMEXP_TYPE Alpha -#define VER_LAMEXP_PATCH 13 -#define VER_LAMEXP_BUILD 870 +#define VER_LAMEXP_PATCH 14 +#define VER_LAMEXP_BUILD 872 /////////////////////////////////////////////////////////////////////////////// // Tool versions (minimum expected versions!) diff --git a/src/Model_FileList.cpp b/src/Model_FileList.cpp index f96790e8..c6c2eb48 100644 --- a/src/Model_FileList.cpp +++ b/src/Model_FileList.cpp @@ -370,24 +370,41 @@ int FileListModel::importFromCsv(QWidget *parent, const QString &inFile) stream.setAutoDetectUnicode(false); stream.setCodec(codec); - QStringList header = stream.readLine().simplified().split(";", QString::KeepEmptyParts); + QString headerLine = stream.readLine().simplified(); + + while(headerLine.isEmpty()) + { + if(stream.atEnd()) + { + qWarning("The file appears to be empty!"); + return CsvError_FileRead; + } + qWarning("Skipping a blank line at beginning of CSV file!"); + headerLine = stream.readLine().simplified(); + } + + QStringList header = headerLine.split(";", QString::KeepEmptyParts); const int nCols = header.count(); const int nFiles = m_fileList.count(); if(nCols < 1) { + qWarning("Header appears to be empty!"); return CsvError_FileRead; } - for(int i = 0; i < nCols; i++) - { - header[i] = header[i].trimmed(); - } - bool *ignore = new bool[nCols]; memset(ignore, 0, sizeof(bool) * nCols); + for(int i = 0; i < nCols; i++) + { + if((header[i] = header[i].trimmed()).isEmpty()) + { + ignore[i] = true; + } + } + //----------------------// for(int i = 0; i < nFiles; i++) @@ -398,9 +415,17 @@ int FileListModel::importFromCsv(QWidget *parent, const QString &inFile) return CsvError_Incomplete; } - QStringList line = stream.readLine().split(";", QString::KeepEmptyParts); + QString line = stream.readLine().simplified(); + + if(line.isEmpty()) + { + qWarning("Skipping a blank line in CSV file!"); + continue; + } + + QStringList data = line.split(";", QString::KeepEmptyParts); - if(line.count() < header.count()) + if(data.count() < header.count()) { qWarning("Skipping an incomplete line in CSV file!"); continue; @@ -415,63 +440,52 @@ int FileListModel::importFromCsv(QWidget *parent, const QString &inFile) else if(CHECK_HDR(header.at(j), "POSITION")) { bool ok = false; - unsigned int temp = line.at(j).trimmed().toUInt(&ok); + unsigned int temp = data.at(j).trimmed().toUInt(&ok); if(ok) m_fileList[i].setFilePosition(temp); } else if(CHECK_HDR(header.at(j), "TITLE")) { - QString temp = line.at(j).trimmed(); + QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileList[i].setFileName(temp); } else if(CHECK_HDR(header.at(j), "ARTIST")) { - QString temp = line.at(j).trimmed(); + QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileList[i].setFileArtist(temp); } else if(CHECK_HDR(header.at(j), "ALBUM")) { - QString temp = line.at(j).trimmed(); + QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileList[i].setFileAlbum(temp); } else if(CHECK_HDR(header.at(j), "GENRE")) { - QString temp = line.at(j).trimmed(); + QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileList[i].setFileGenre(temp); } else if(CHECK_HDR(header.at(j), "YEAR")) { bool ok = false; - unsigned int temp = line.at(j).trimmed().toUInt(&ok); + unsigned int temp = data.at(j).trimmed().toUInt(&ok); if(ok) m_fileList[i].setFileYear(temp); } else if(CHECK_HDR(header.at(j), "COMMENT")) { - QString temp = line.at(j).trimmed(); + QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileList[i].setFileComment(temp); } else { qWarning("Unkonw field '%s' will be ignored!", header.at(j).toUtf8().constData()); ignore[j] = true; + + if(!checkArray(ignore, false, nCols)) + { + qWarning("No known fields left, aborting!"); + return CsvError_NoTags; + } } } - - bool noFieldsLeft = true; - - for(int j = 0; j < nCols; j++) - { - if(!ignore[j]) - { - noFieldsLeft = false; - break; - } - } - - if(noFieldsLeft) - { - LAMEXP_DELETE_ARRAY(ignore); - return CsvError_NoTags; - } } //----------------------// @@ -479,3 +493,13 @@ int FileListModel::importFromCsv(QWidget *parent, const QString &inFile) LAMEXP_DELETE_ARRAY(ignore); return CsvError_OK; } + +bool FileListModel::checkArray(const bool *a, const bool val, size_t len) +{ + for(size_t i = 0; i < len; i++) + { + if(a[i] == val) return true; + } + + return false; +} diff --git a/src/Model_FileList.h b/src/Model_FileList.h index 3df1890b..24147f84 100644 --- a/src/Model_FileList.h +++ b/src/Model_FileList.h @@ -72,4 +72,6 @@ public slots: private: QList m_fileList; const QIcon m_fileIcon; + + static bool checkArray(const bool *a, const bool val, size_t len); };