summaryrefslogtreecommitdiff
path: root/src/csvbuilder.h
blob: 70d712c4dbd3a6f9b0bd8a827aee35a73476e14e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifndef CSVBUILDER_H
#define CSVBUILDER_H

#include <QString>
#include <QTextStream>
#include <QVariant>
#include <vector>

class CSVException : public std::exception {

public:
    CSVException(const QString& text) : std::exception(), m_Message(text.toLocal8Bit()) {}

    virtual const char* what() const throw() { return m_Message.constData(); }

private:
    QByteArray m_Message;
};

class CSVBuilder {

public:
    enum EFieldType { TYPE_INTEGER, TYPE_STRING, TYPE_FLOAT };

    enum EQuoteMode { QUOTE_NEVER, QUOTE_ONDEMAND, QUOTE_ALWAYS };

    enum ELineBreak { BREAK_LF, BREAK_CRLF, BREAK_CR };

public:
    CSVBuilder(QIODevice* target);
    ~CSVBuilder();

    void setFieldSeparator(char sep);
    void setLineBreak(ELineBreak lineBreak);
    void setEscapeMode(EFieldType type, EQuoteMode mode);
    void setFields(const std::vector<std::pair<QString, EFieldType>>& fields);
    void setDefault(const QString& field, const QVariant& value);

    void writeHeader();

    void setRowField(const QString& field, const QVariant& value);
    void writeRow();

    void addRow(const std::map<QString, QVariant>& data);

private:
    const char* lineBreak();
    const char separator();

    void fieldValid();
    void checkFields(const std::vector<QString>& fields);
    void checkValue(const QString& field, const QVariant& value);
    void writeData(const std::map<QString, QVariant>& data, bool check);

    void quoteInsert(QTextStream& stream, int value);
    void quoteInsert(QTextStream& stream, float value);
    void quoteInsert(QTextStream& stream, const QString& value);

private:
    QTextStream m_Out;
    char m_Separator;
    ELineBreak m_LineBreak;
    std::map<EFieldType, EQuoteMode> m_QuoteMode;
    std::vector<QString> m_Fields;
    std::map<QString, EFieldType> m_FieldTypes;
    std::map<QString, QVariant> m_Defaults;
    std::map<QString, QVariant> m_RowBuffer;
};

#endif // CSVBUILDER_H