aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/string_utils/csv/csv.h
blob: 8cb96e6bb92651489350523af0a277d1b586c6ce (plain) (blame)
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
#pragma once

#include <util/generic/yexception.h>
#include <util/generic/strbuf.h>
#include <util/generic/vector.h>
#include <util/stream/input.h>

/*
    Split string by rfc4180
*/

namespace NCsvFormat {
    class TLinesSplitter {
    private:
        IInputStream& Input;
        const char Quote;
    public:
        TLinesSplitter(IInputStream& input, const char quote = '"')
            : Input(input)
            , Quote(quote) {
        }
        TString ConsumeLine();
    };

    class CsvSplitter {
    public:
        CsvSplitter(TString& data, const char delimeter = ',', const char quote = '"')
        // quote = '\0' ignores quoting in values and words like simple split
            : Delimeter(delimeter)
            , Quote(quote)
            , Begin(data.begin())
            , End(data.end())
        {
        }

        bool Step() {
            if (Begin == End) {
                return false;
            }
            ++Begin;
            return true;
        }

        TStringBuf Consume();
        explicit operator TVector<TString>() {
            TVector<TString> ret;

            do {
                TStringBuf buf = Consume();
                ret.push_back(TString{buf});
            } while (Step());

            return ret;
        }

    private:
        const char Delimeter;
        const char Quote;
        TString::iterator Begin;
        const TString::const_iterator End;
        TString CustomString;
        TVector<TStringBuf> CustomStringBufs;
    };
}