Coverage Report

Created: 2026-01-10 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp
Line
Count
Source
1
// Copyright 2013-2025 Daniel Parker
2
// Distributed under the Boost license, Version 1.0.
3
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
5
// See https://github.com/danielaparker/jsoncons for latest version
6
7
#ifndef JSONCONS_CSV_CSV_READER_HPP
8
#define JSONCONS_CSV_CSV_READER_HPP
9
10
#include <cstddef>
11
#include <functional>
12
#include <memory> // std::allocator
13
#include <system_error>
14
#include <utility> // std::move
15
16
#include <jsoncons/config/compiler_support.hpp>
17
#include <jsoncons/json_decoder.hpp>
18
#include <jsoncons/json_exception.hpp>
19
#include <jsoncons/json_reader.hpp>
20
#include <jsoncons/json_visitor.hpp>
21
#include <jsoncons/ser_util.hpp>
22
#include <jsoncons/source.hpp>
23
#include <jsoncons/source_adaptor.hpp>
24
25
#include <jsoncons_ext/csv/csv_error.hpp>
26
#include <jsoncons_ext/csv/csv_options.hpp>
27
#include <jsoncons_ext/csv/csv_parser.hpp>
28
29
namespace jsoncons { 
30
namespace csv {
31
32
    template <typename CharT,typename Source=jsoncons::stream_source<CharT>,typename Allocator=std::allocator<char>>
33
    class basic_csv_reader 
34
    {
35
        struct stack_item
36
        {
37
            stack_item() noexcept
38
               : array_begun_(false)
39
            {
40
            }
41
42
            bool array_begun_;
43
        };
44
        using char_type = CharT;
45
        using temp_allocator_type = Allocator;
46
        using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<CharT>;
47
48
        basic_csv_reader(const basic_csv_reader&) = delete; 
49
        basic_csv_reader& operator = (const basic_csv_reader&) = delete; 
50
51
        basic_default_json_visitor<CharT> default_visitor_;
52
        text_source_adaptor<Source> source_;
53
        basic_json_visitor<CharT>& visitor_;
54
        basic_csv_parser<CharT,Allocator> parser_;
55
56
    public:
57
        template <typename Sourceable>
58
        basic_csv_reader(Sourceable&& source,
59
            basic_json_visitor<CharT>& visitor,
60
            const basic_csv_decode_options<CharT>& options = basic_csv_decode_options<CharT>{},
61
            const Allocator& alloc = Allocator())
62
2.61k
           : source_(std::forward<Sourceable>(source)),
63
2.61k
             visitor_(visitor),
64
2.61k
             parser_(options, alloc)
65
66
2.61k
        {
67
2.61k
        }
68
69
        template <typename Sourceable>
70
        basic_csv_reader(Sourceable&& source,
71
            basic_json_visitor<CharT>& visitor,
72
            const Allocator& alloc = Allocator())
73
            : basic_csv_reader(std::forward<Sourceable>(source), 
74
                               visitor, 
75
                               basic_csv_decode_options<CharT>(), 
76
                               alloc)
77
        {
78
        }
79
80
#if !defined(JSONCONS_NO_DEPRECATED)
81
82
        template <typename Sourceable>
83
        basic_csv_reader(Sourceable&& source,
84
            basic_json_visitor<CharT>& visitor,
85
            const basic_csv_decode_options<CharT>& options,
86
            std::function<bool(csv_errc,const ser_context&)> err_handler, 
87
            const Allocator& alloc = Allocator())
88
           : source_(std::forward<Sourceable>(source)),
89
             visitor_(visitor),
90
             parser_(options, err_handler, alloc)
91
             
92
        {
93
        }
94
95
        template <typename Sourceable>
96
        basic_csv_reader(Sourceable&& source,
97
            basic_json_visitor<CharT>& visitor,
98
            std::function<bool(csv_errc,const ser_context&)> err_handler, 
99
            const Allocator& alloc = Allocator())
100
            : basic_csv_reader(std::forward<Sourceable>(source), 
101
                               visitor, 
102
                               basic_csv_decode_options<CharT>(), 
103
                               err_handler,
104
                               alloc)
105
        {
106
        }
107
#endif
108
109
2.61k
        ~basic_csv_reader() noexcept = default;
110
111
        void read()
112
2.61k
        {
113
2.61k
            std::error_code ec;
114
2.61k
            read(ec);
115
2.61k
            if (JSONCONS_UNLIKELY(ec))
116
93
            {
117
93
                JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column()));
118
93
            }
119
2.61k
        }
120
121
        void read(std::error_code& ec)
122
2.61k
        {
123
2.61k
            read_internal(ec);
124
2.61k
        }
125
126
        std::size_t line() const
127
        {
128
            return parser_.line();
129
        }
130
131
        std::size_t column() const
132
        {
133
            return parser_.column();
134
        }
135
136
        bool eof() const
137
        {
138
            return parser_.source_exhausted() && source_.eof();
139
        }
140
141
    private:
142
143
        void read_internal(std::error_code& ec)
144
2.61k
        {
145
2.61k
            if (source_.is_error())
146
0
            {
147
0
                ec = csv_errc::source_error;
148
0
                return;
149
0
            }   
150
19.5k
            while (!parser_.stopped())
151
17.0k
            {
152
17.0k
                if (parser_.source_exhausted())
153
17.0k
                {
154
17.0k
                    auto s = source_.read_buffer(ec);
155
17.0k
                    if (JSONCONS_UNLIKELY(ec)) return;
156
17.0k
                    if (s.size() > 0)
157
2.60k
                    {
158
2.60k
                        parser_.update(s.data(),s.size());
159
2.60k
                    }
160
17.0k
                }
161
17.0k
                parser_.parse_some(visitor_, ec);
162
17.0k
                if (JSONCONS_UNLIKELY(ec)) return;
163
17.0k
            }
164
2.61k
        }
165
    };
166
167
    using csv_string_reader = basic_csv_reader<char,string_source<char>>;
168
    using wcsv_string_reader = basic_csv_reader<wchar_t,string_source<wchar_t>>;
169
    using csv_stream_reader = basic_csv_reader<char,stream_source<char>>;
170
    using wcsv_stream_reader = basic_csv_reader<wchar_t,stream_source<wchar_t>>;
171
172
}}
173
174
#endif