1 /*
2  *  Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
3  *  Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 2 or (at your option)
8  *  version 3 of the License.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef KEEPASSX_CSVPARSER_H
20 #define KEEPASSX_CSVPARSER_H
21 
22 #include <QBuffer>
23 #include <QFile>
24 #include <QQueue>
25 #include <QTextStream>
26 
27 typedef QStringList CsvRow;
28 typedef QList<CsvRow> CsvTable;
29 
30 class CsvParser
31 {
32 
33 public:
34     CsvParser();
35     ~CsvParser();
36     // read data from device and parse it
37     bool parse(QFile* device);
38     bool isFileLoaded();
39     // reparse the same buffer (device is not opened again)
40     bool reparse();
41     void setCodec(const QString& s);
42     void setComment(const QChar& c);
43     void setFieldSeparator(const QChar& c);
44     void setTextQualifier(const QChar& c);
45     void setBackslashSyntax(bool set);
46     int getFileSize() const;
47     int getCsvRows() const;
48     int getCsvCols() const;
49     QString getStatus() const;
50     const CsvTable getCsvTable() const;
51 
52 protected:
53     CsvTable m_table;
54 
55 private:
56     QByteArray m_array;
57     QBuffer m_csv;
58     QChar m_ch;
59     QChar m_comment;
60     unsigned int m_currCol;
61     unsigned int m_currRow;
62     bool m_isBackslashSyntax;
63     bool m_isEof;
64     bool m_isFileLoaded;
65     bool m_isGood;
66     qint64 m_lastPos;
67     int m_maxCols;
68     QChar m_qualifier;
69     QChar m_separator;
70     QString m_statusMsg;
71     QTextStream m_ts;
72 
73     void getChar(QChar& c);
74     void ungetChar();
75     void peek(QChar& c);
76     void fillColumns();
77     bool isTerminator(const QChar& c) const;
78     bool isSeparator(const QChar& c) const;
79     bool isQualifier(const QChar& c) const;
80     bool processEscapeMark(QString& s, QChar c);
81     bool isText(QChar c) const;
82     bool isComment();
83     bool isCRLF(const QChar& c) const;
84     bool isSpace(const QChar& c) const;
85     bool isTab(const QChar& c) const;
86     bool isEmptyRow(const CsvRow& row) const;
87     bool parseFile();
88     void parseRecord();
89     void parseField(CsvRow& row);
90     void parseSimple(QString& s);
91     void parseQuoted(QString& s);
92     void parseEscaped(QString& s);
93     void parseEscapedText(QString& s);
94     bool readFile(QFile* device);
95     void reset();
96     void clear();
97     bool skipEndline();
98     void skipLine();
99     void appendStatusMsg(const QString& s, bool isCritical = false);
100 };
101 
102 #endif // CSVPARSER_H
103