summaryrefslogtreecommitdiffhomepage
path: root/csv
diff options
context:
space:
mode:
Diffstat (limited to 'csv')
-rw-r--r--csv/csv.cpp136
-rw-r--r--csv/csv.h25
-rw-r--r--csv/lang/de_DE.ts4
-rw-r--r--csv/lang/zh_CN.ts2
4 files changed, 53 insertions, 114 deletions
diff --git a/csv/csv.cpp b/csv/csv.cpp
index a1f62dc0..79841bea 100644
--- a/csv/csv.cpp
+++ b/csv/csv.cpp
@@ -11,84 +11,42 @@
#include "csv.h"
#include "compat/library-path.hpp"
-#include <QTextDecoder>
-#include <QFile>
+#include <utility>
+#include <cstdio>
+#include <QByteArray>
#include <QString>
+#include <QStringDecoder>
+#include <QFile>
+#include <QByteArrayView>
#include <QDebug>
-#include <utility>
-#include <algorithm>
-
-const QTextCodec* const CSV::m_codec = QTextCodec::codecForName("System");
-const QRegExp CSV::m_rx = QRegExp(QString("((?:(?:[^;\\n]*;?)|(?:\"[^\"]*\";?))*)?\\n?"));
-const QRegExp CSV::m_rx2 = QRegExp(QString("(?:\"([^\"]*)\";?)|(?:([^;]*);?)?"));
+namespace {
-CSV::CSV(QIODevice* device) :
- m_device(device),
- m_pos(0)
+void chomp(QString& str)
{
- if (m_device && m_device->isReadable())
+ if (!str.isEmpty() && str.back() == '\n')
{
- QTextDecoder dec(m_codec);
- m_string = dec.toUnicode(m_device->readAll());
+ str.chop(1);
+ if (!str.isEmpty() && str.back() == '\r')
+ str.chop(1);
}
}
-QString CSV::readLine()
+auto do_scanf(QLatin1StringView s, unsigned(&tmp)[8])
{
- QString line;
-
- if ((m_pos = m_rx.indexIn(m_string,m_pos)) != -1)
- {
- line = m_rx.cap(1);
- m_pos += m_rx.matchedLength();
- }
- else
- {
- const QChar lf(QChar::LineFeed);
-
- while (m_pos < m_string.length())
- if (m_string[m_pos++] == lf)
- break;
- }
- return line;
-}
-
-bool CSV::parseLine(QStringList& ret)
-{
- QString line(readLine());
-
- QStringList list;
- int pos2 = 0;
+ unsigned fuzz[3];
+ return std::sscanf(s.constData(),
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ fuzz + 2,
+ fuzz + 0,
+ tmp + 3, tmp + 2, tmp + 1, tmp + 0,
+ tmp + 7, tmp + 6, tmp + 5, tmp + 4,
+ fuzz + 1);
+};
- if (line.size() == 0)
- {
- ret = QStringList();
- return m_device->size() > m_pos;
- }
- else
- {
- while (line.size() > pos2 && (pos2 = m_rx2.indexIn(line, pos2)) != -1)
- {
- QString col;
- if (m_rx2.cap(1).size() > 0)
- col = m_rx2.cap(1);
- else if (m_rx2.cap(2).size() > 0)
- col = m_rx2.cap(2);
-
- list << col;
-
- if (col.size())
- pos2 += m_rx2.matchedLength();
- else
- pos2++;
- }
- }
- ret = std::move(list);
- return true;
}
-bool CSV::getGameData(int id, unsigned char* table, QString& gamename)
+bool getGameData(int id, unsigned char* table, QString& gamename)
{
for (int i = 0; i < 8; i++)
table[i] = 0;
@@ -96,28 +54,34 @@ bool CSV::getGameData(int id, unsigned char* table, QString& gamename)
if (id != 0)
qDebug() << "csv: lookup game id" << id;
- QString id_str(QString::number(id));
-
static const QString csv_path(OPENTRACK_BASE_PATH +
OPENTRACK_DOC_PATH "settings/facetracknoir supported games.csv");
+ auto id_str = QString::number(id);
QFile file(csv_path);
-
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ if (!file.open(QIODevice::ReadOnly))
{
qDebug() << "csv: can't open game list for freetrack protocol!";
return false;
}
+ QStringDecoder decoder{QStringConverter::Encoding::Utf8};
+ QStringList gameLine; gameLine.reserve(8);
+ unsigned lineno = 0;
+ // TODO QIODevice::readLineInto() is Qt 6.9 - sh 20250515
+ char buf[256];
- CSV csv(&file);
+ while (auto sz = file.readLine(buf, sizeof(buf)))
+ {
+ QString line = decoder.decode(QByteArrayView{buf, sz});
- unsigned tmp[8];
- unsigned fuzz[3];
+ if (line.isEmpty())
+ break;
+ chomp(line);
+ if (line.isEmpty())
+ continue;
- QStringList gameLine;
+ gameLine = line.split(';', Qt::SplitBehaviorFlags::KeepEmptyParts);
- for (int lineno = 0; csv.parseLine(gameLine); lineno++)
- {
//qDebug() << "Column 0: " << gameLine.at(0); // No.
//qDebug() << "Column 1: " << gameLine.at(1); // Game Name
//qDebug() << "Column 2: " << gameLine.at(2); // Game Protocol
@@ -127,28 +91,18 @@ bool CSV::getGameData(int id, unsigned char* table, QString& gamename)
//qDebug() << "Column 6: " << gameLine.at(6); // International ID
//qDebug() << "Column 7: " << gameLine.at(7); // FaceTrackNoIR ID
- if (gameLine.count() == 8)
+ if (gameLine.size() == 8)
{
- if (gameLine.at(6).compare(id_str, Qt::CaseInsensitive) == 0)
+ if (gameLine[6] == id_str)
{
const QString& proto = gameLine[3];
QString& name = gameLine[1];
-
const QByteArray id_cstr = gameLine[7].toLatin1();
-
- auto do_scanf = [&]() {
- return sscanf(id_cstr.constData(),
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- fuzz + 2,
- fuzz + 0,
- tmp + 3, tmp + 2, tmp + 1, tmp + 0,
- tmp + 7, tmp + 6, tmp + 5, tmp + 4,
- fuzz + 1);
- };
+ unsigned tmp[8] {};
if (proto == QStringLiteral("V160") || id_cstr.length() != 22)
(void)0;
- else if (id_cstr.length() != 22 || do_scanf() != 11)
+ else if (id_cstr.length() != 22 || do_scanf(QLatin1StringView(id_cstr), tmp) != 11)
qDebug() << "scanf failed" << lineno;
else
{
@@ -161,7 +115,9 @@ bool CSV::getGameData(int id, unsigned char* table, QString& gamename)
}
}
else
- qDebug() << "malformed csv line" << lineno;
+ qDebug() << "csv wrong column count" << gameLine.size();
+
+ lineno++;
}
if (id)
diff --git a/csv/csv.h b/csv/csv.h
index 9e72b2bb..15f279d6 100644
--- a/csv/csv.h
+++ b/csv/csv.h
@@ -1,26 +1,5 @@
#pragma once
-#include <QtGlobal>
-#include <QObject>
-#include <QStringList>
-#include <QIODevice>
-#include <QTextCodec>
-#include <QRegExp>
-#include <QtGlobal>
-class CSV
-{
-public:
- QString readLine();
- bool parseLine(QStringList& ret);
+#include <QString>
- static bool getGameData(int gameID, unsigned char* table, QString& gamename);
-private:
- CSV(QIODevice* device);
-
- QIODevice* m_device;
- QString m_string;
- int m_pos;
-
- static QTextCodec const* const m_codec;
- static const QRegExp m_rx, m_rx2;
-};
+bool getGameData(int gameID, unsigned char* table, QString& gamename);
diff --git a/csv/lang/de_DE.ts b/csv/lang/de_DE.ts
new file mode 100644
index 00000000..1552582e
--- /dev/null
+++ b/csv/lang/de_DE.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="de_DE">
+</TS>
diff --git a/csv/lang/zh_CN.ts b/csv/lang/zh_CN.ts
index 6401616d..e5ca8aa9 100644
--- a/csv/lang/zh_CN.ts
+++ b/csv/lang/zh_CN.ts
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
-<TS version="2.1">
+<TS version="2.1" language="zh_CN">
</TS>