Coverage Report

Created: 2026-08-31 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp
Line
Count
Source
1
// Copyright 2013-2026 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_PARSER_HPP
8
#define JSONCONS_CSV_CSV_PARSER_HPP
9
10
#include <cctype>
11
#include <cstddef>
12
#include <cstdint>
13
#include <functional>
14
#include <memory> // std::allocator
15
#include <sstream>
16
#include <string>
17
#include <system_error>
18
#include <vector>
19
20
#include <jsoncons/config/compiler_support.hpp>
21
#include <jsoncons/config/jsoncons_config.hpp>
22
#include <jsoncons/utility/read_number.hpp>
23
#include <jsoncons/json_exception.hpp>
24
#include <jsoncons/json_filter.hpp>
25
#include <jsoncons/json_reader.hpp>
26
#include <jsoncons/json_type.hpp>
27
#include <jsoncons/json_visitor.hpp>
28
#include <jsoncons/semantic_tag.hpp>
29
#include <jsoncons/ser_utils.hpp>
30
#include <jsoncons/staj_event.hpp>
31
32
#include <jsoncons_ext/csv/csv_error.hpp>
33
#include <jsoncons_ext/csv/csv_options.hpp>
34
35
namespace jsoncons { 
36
namespace csv {
37
38
enum class csv_mode 
39
{
40
    initial,
41
    header,
42
    data,
43
    subfields
44
};
45
46
enum class csv_parse_state 
47
{
48
    start,
49
    cr, 
50
    expect_comment_or_record,
51
    expect_record,
52
    end_record,
53
    no_more_records,
54
    comment,
55
    between_values,
56
    quoted_string,
57
    unquoted_string,
58
    before_unquoted_string,
59
    escaped_value,
60
    minus, 
61
    zero,  
62
    integer,
63
    fraction,
64
    exp1,
65
    exp2,
66
    exp3,
67
    accept,
68
    before_unquoted_field,
69
    before_unquoted_field_tail, 
70
    before_unquoted_field_tail1,
71
    before_last_unquoted_field,
72
    before_last_unquoted_field_tail,
73
    before_unquoted_subfield,
74
    before_unquoted_subfield_tail,
75
    before_quoted_subfield,
76
    before_quoted_subfield_tail,
77
    before_quoted_field,
78
    before_quoted_field_tail,
79
    before_last_quoted_field,
80
    before_last_quoted_field_tail,
81
    done
82
};
83
84
enum class cached_state
85
{
86
    begin_object,
87
    end_object,
88
    begin_array,
89
    end_array,
90
    name,
91
    item,
92
    done
93
};
94
95
struct default_csv_parsing
96
{
97
    bool operator()(csv_errc, const ser_context&) noexcept
98
0
    {
99
0
        return false;
100
0
    }
101
};
102
103
namespace detail {
104
105
    template <typename CharT,typename TempAlloc >
106
    class parse_event
107
    {
108
        using temp_allocator_type = TempAlloc;
109
        using string_view_type = typename basic_json_visitor<CharT>::string_view_type;
110
        using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<CharT>;
111
        using byte_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<uint8_t>;                  
112
        using string_type = std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type>;
113
        using byte_string_type = basic_byte_string<byte_allocator_type>;
114
115
        staj_events event_type;
116
        string_type string_value;
117
        byte_string_type byte_string_value;
118
        union
119
        {
120
            bool bool_value;
121
            int64_t int64_value;
122
            uint64_t uint64_value;
123
            double double_value;
124
        };
125
        semantic_tag tag;
126
    public:
127
        parse_event(staj_events event_type, semantic_tag tag, const TempAlloc& alloc)
128
0
            : event_type(event_type), 
129
0
              string_value(alloc),
130
0
              byte_string_value(alloc),
131
0
              tag(tag)
132
0
        {
133
0
        }
134
135
        parse_event(const string_view_type& value, semantic_tag tag, const TempAlloc& alloc)
136
0
            : event_type(staj_events::string_value), 
137
0
              string_value(value.data(),value.length(),alloc), 
138
0
              byte_string_value(alloc),
139
0
              tag(tag)
140
0
        {
141
0
        }
142
143
        parse_event(const byte_string_view& value, semantic_tag tag, const TempAlloc& alloc)
144
0
            : event_type(staj_events::byte_string_value), 
145
0
              string_value(alloc),
146
0
              byte_string_value(value.data(),value.size(),alloc), 
147
0
              tag(tag)
148
0
        {
149
0
        }
150
151
        parse_event(bool value, semantic_tag tag, const TempAlloc& alloc)
152
0
            : event_type(staj_events::bool_value), 
153
0
              string_value(alloc),
154
0
              byte_string_value(alloc),
155
0
              bool_value(value), 
156
0
              tag(tag)
157
0
        {
158
0
        }
159
160
        parse_event(int64_t value, semantic_tag tag, const TempAlloc& alloc)
161
0
            : event_type(staj_events::int64_value), 
162
0
              string_value(alloc),
163
0
              byte_string_value(alloc),
164
0
              int64_value(value), 
165
0
              tag(tag)
166
0
        {
167
0
        }
168
169
        parse_event(uint64_t value, semantic_tag tag, const TempAlloc& alloc)
170
0
            : event_type(staj_events::uint64_value), 
171
0
              string_value(alloc),
172
0
              byte_string_value(alloc),
173
0
              uint64_value(value), 
174
0
              tag(tag)
175
0
        {
176
0
        }
177
178
        parse_event(double value, semantic_tag tag, const TempAlloc& alloc)
179
0
            : event_type(staj_events::double_value), 
180
0
              string_value(alloc),
181
0
              byte_string_value(alloc),
182
0
              double_value(value), 
183
0
              tag(tag)
184
0
        {
185
0
        }
186
187
        parse_event(const parse_event&) = default;
188
0
        parse_event(parse_event&&) = default;
189
        parse_event& operator=(const parse_event&) = default;
190
        parse_event& operator=(parse_event&&) = default;
191
192
        void replay(basic_json_visitor<CharT>& visitor) const
193
0
        {
194
0
            switch (event_type)
195
0
            {
196
0
                case staj_events::begin_array:
197
0
                    visitor.begin_array(tag, ser_context());
198
0
                    break;
199
0
                case staj_events::end_array:
200
0
                    visitor.end_array(ser_context());
201
0
                    break;
202
0
                case staj_events::string_value:
203
0
                    visitor.string_value(string_value, tag, ser_context());
204
0
                    break;
205
0
                case staj_events::byte_string_value:
206
0
                    visitor.byte_string_value(byte_string_value, tag, ser_context());
207
0
                    break;
208
0
                case staj_events::null_value:
209
0
                    visitor.null_value(tag, ser_context());
210
0
                    break;
211
0
                case staj_events::bool_value:
212
0
                    visitor.bool_value(bool_value, tag, ser_context());
213
0
                    break;
214
0
                case staj_events::int64_value:
215
0
                    visitor.int64_value(int64_value, tag, ser_context());
216
0
                    break;
217
0
                case staj_events::uint64_value:
218
0
                    visitor.uint64_value(uint64_value, tag, ser_context());
219
0
                    break;
220
0
                case staj_events::double_value:
221
0
                    visitor.double_value(double_value, tag, ser_context());
222
0
                    break;
223
0
                default:
224
0
                    break;
225
0
            }
226
0
        }
227
    };
228
229
    template <typename CharT,typename TempAlloc >
230
    class m_columns_filter : public basic_json_visitor<CharT>
231
    {
232
    public:
233
        using string_view_type = typename basic_json_visitor<CharT>::string_view_type;
234
        using char_type = CharT;
235
        using temp_allocator_type = TempAlloc;
236
237
        using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<CharT>;
238
        using string_type = std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type>;
239
240
        using string_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<string_type>;
241
        using parse_event_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_event<CharT,TempAlloc>>;
242
        using parse_event_vector_type = std::vector<parse_event<CharT,TempAlloc>, parse_event_allocator_type>;
243
        using parse_event_vector_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_event_vector_type>;
244
    private:
245
        TempAlloc alloc_;
246
        std::size_t name_index_{0};
247
        int level_{0};
248
        int level2_{0};
249
        cached_state state_{cached_state::begin_object};
250
        std::size_t column_index_{0};
251
        std::size_t row_index_{0};
252
253
        std::vector<string_type, string_allocator_type> column_names_;
254
        std::vector<parse_event_vector_type,parse_event_vector_allocator_type> cached_events_;
255
    public:
256
257
        m_columns_filter(const TempAlloc& alloc)
258
2.74k
            : alloc_(alloc),
259
2.74k
              column_names_(alloc),
260
2.74k
              cached_events_(alloc)
261
2.74k
        {
262
2.74k
        }
263
264
        void reset()
265
        {
266
            name_index_ = 0;
267
            level_ = 0;
268
            level2_ = 0;
269
            state_ = cached_state::begin_object;
270
            column_index_ = 0;
271
            row_index_ = 0;
272
            column_names_.clear();
273
            cached_events_.clear();
274
        }
275
276
        bool done() const
277
0
        {
278
0
            return state_ == cached_state::done;
279
0
        }
280
281
        void initialize(const std::vector<string_type, string_allocator_type>& column_names)
282
0
        {
283
0
            for (const auto& name : column_names)
284
0
            {
285
0
                column_names_.push_back(name);
286
0
                cached_events_.emplace_back(alloc_);
287
0
            }
288
0
            name_index_ = 0;
289
0
            level_ = 0;
290
0
            level2_ = 0;
291
0
            column_index_ = 0;
292
0
            row_index_ = 0;
293
0
            state_ = cached_state::begin_object;
294
0
        }
295
296
        void skip_column()
297
0
        {
298
0
            ++name_index_;
299
0
        }
300
        
301
        int level() const
302
        {
303
            return static_cast<int>(level_);
304
        }
305
306
        bool replay_parse_events(basic_json_visitor<CharT>& visitor, bool cursor_mode, int mark_level)
307
0
        {
308
0
            bool more = true;
309
0
            while (more)
310
0
            {
311
0
                switch (state_)
312
0
                {
313
0
                    case cached_state::begin_object:
314
0
                        visitor.begin_object(semantic_tag::none, ser_context());
315
0
                        ++level_;
316
0
                        more = !cursor_mode;
317
0
                        column_index_ = 0;
318
0
                        state_ = cached_state::name;
319
0
                        break;
320
0
                    case cached_state::end_object:
321
0
                        visitor.end_object(ser_context());
322
0
                        more = !cursor_mode;
323
0
                        if (level_ == mark_level)
324
0
                        {
325
0
                            more = false;
326
0
                        }
327
0
                        --level_;
328
0
                        state_ = cached_state::done;
329
0
                        break;
330
0
                    case cached_state::name:
331
0
                        if (column_index_ < column_names_.size())
332
0
                        {
333
0
                            visitor.key(column_names_[column_index_], ser_context());
334
0
                            more = !cursor_mode;
335
0
                            state_ = cached_state::begin_array;
336
0
                        }
337
0
                        else
338
0
                        {
339
0
                            state_ = cached_state::end_object;
340
0
                        }
341
0
                        break;
342
0
                    case cached_state::begin_array:
343
0
                        visitor.begin_array(semantic_tag::none, ser_context());
344
0
                        ++level_;
345
0
                        more = !cursor_mode;
346
0
                        row_index_ = 0;
347
0
                        state_ = cached_state::item;
348
0
                        break;
349
0
                    case cached_state::end_array:
350
0
                        visitor.end_array(ser_context());
351
0
                        more = !cursor_mode;
352
0
                        if (level_ == mark_level)
353
0
                        {
354
0
                            more = false;
355
0
                        }
356
0
                        --level_;
357
0
                        ++column_index_;
358
0
                        state_ = cached_state::name;
359
0
                        break;
360
0
                    case cached_state::item:
361
0
                        if (row_index_ < cached_events_[column_index_].size())
362
0
                        {
363
0
                            cached_events_[column_index_][row_index_].replay(visitor);
364
0
                            more = !cursor_mode;
365
0
                            ++row_index_;
366
0
                        }
367
0
                        else
368
0
                        {
369
0
                            state_ = cached_state::end_array;
370
0
                        }
371
0
                        break;
372
0
                    default:
373
0
                        more = false;
374
0
                        break;
375
0
                }
376
0
            }
377
0
            return more;
378
0
        }
379
380
        void visit_flush() final
381
0
        {
382
0
        }
383
384
        JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) final
385
0
        {
386
0
            ec = csv_errc::invalid_parse_state;
387
0
            JSONCONS_VISITOR_RETURN;
388
0
        }
389
390
        JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code& ec) final
391
0
        {
392
0
            ec = csv_errc::invalid_parse_state;
393
0
            JSONCONS_VISITOR_RETURN;
394
0
        }
395
396
        JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context&, std::error_code&) final
397
0
        {
398
0
            if (name_index_ < column_names_.size())
399
0
            {
400
0
                cached_events_[name_index_].emplace_back(staj_events::begin_array, tag, alloc_);
401
                
402
0
                ++level2_;
403
0
            }
404
0
            JSONCONS_VISITOR_RETURN;
405
0
        }
406
407
        JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) final
408
0
        {
409
0
            if (level2_ > 0)
410
0
            {
411
0
                cached_events_[name_index_].emplace_back(staj_events::end_array, semantic_tag::none, alloc_);
412
0
                ++name_index_;
413
0
                --level2_;
414
0
            }
415
0
            else
416
0
            {
417
0
                name_index_ = 0;
418
0
            }
419
0
            JSONCONS_VISITOR_RETURN;
420
0
        }
421
422
        JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type&, const ser_context&, std::error_code& ec) final
423
0
        {
424
0
            ec = csv_errc::invalid_parse_state;
425
0
            JSONCONS_VISITOR_RETURN;
426
0
        }
427
428
        JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code&) final
429
0
        {
430
0
            if (name_index_ < column_names_.size())
431
0
            {
432
0
                cached_events_[name_index_].emplace_back(staj_events::null_value, tag, alloc_);
433
0
                if (level2_ == 0)
434
0
                {
435
0
                    ++name_index_;
436
0
                }
437
0
            }
438
0
            JSONCONS_VISITOR_RETURN;
439
0
        }
440
441
        JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context&, std::error_code&) final
442
0
        {
443
0
            if (name_index_ < column_names_.size())
444
0
            {
445
0
                cached_events_[name_index_].emplace_back(value, tag, alloc_);
446
447
0
                if (level2_ == 0)
448
0
                {
449
0
                    ++name_index_;
450
0
                }
451
0
            }
452
0
            JSONCONS_VISITOR_RETURN;
453
0
        }
454
455
        JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value,
456
                                  semantic_tag tag,
457
                                  const ser_context&,
458
                                  std::error_code&) final
459
0
        {
460
0
            if (name_index_ < column_names_.size())
461
0
            {
462
0
                cached_events_[name_index_].emplace_back(value, tag, alloc_);
463
0
                if (level2_ == 0)
464
0
                {
465
0
                    ++name_index_;
466
0
                }
467
0
            }
468
0
            JSONCONS_VISITOR_RETURN;
469
0
        }
470
471
        JSONCONS_VISITOR_RETURN_TYPE visit_double(double value,
472
                             semantic_tag tag, 
473
                             const ser_context&,
474
                             std::error_code&) final
475
0
        {
476
0
            if (name_index_ < column_names_.size())
477
0
            {
478
0
                cached_events_[name_index_].emplace_back(value, tag, alloc_);
479
0
                if (level2_ == 0)
480
0
                {
481
0
                    ++name_index_;
482
0
                }
483
0
            }
484
0
            JSONCONS_VISITOR_RETURN;
485
0
        }
486
487
        JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value,
488
                            semantic_tag tag,
489
                            const ser_context&,
490
                            std::error_code&) final
491
0
        {
492
0
            if (name_index_ < column_names_.size())
493
0
            {
494
0
                cached_events_[name_index_].emplace_back(value, tag, alloc_);
495
0
                if (level2_ == 0)
496
0
                {
497
0
                    ++name_index_;
498
0
                }
499
0
            }
500
0
            JSONCONS_VISITOR_RETURN;
501
0
        }
502
503
        JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value,
504
                             semantic_tag tag,
505
                             const ser_context&,
506
                             std::error_code&) final
507
0
        {
508
0
            if (name_index_ < column_names_.size())
509
0
            {
510
0
                cached_events_[name_index_].emplace_back(value, tag, alloc_);
511
0
                if (level2_ == 0)
512
0
                {
513
0
                    ++name_index_;
514
0
                }
515
0
            }
516
0
            JSONCONS_VISITOR_RETURN;
517
0
        }
518
519
        JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context&, std::error_code&) final
520
0
        {
521
0
            if (name_index_ < column_names_.size())
522
0
            {
523
0
                cached_events_[name_index_].emplace_back(value, tag, alloc_);
524
0
                if (level2_ == 0)
525
0
                {
526
0
                    ++name_index_;
527
0
                }
528
0
            }
529
0
            JSONCONS_VISITOR_RETURN;
530
0
        }
531
    };
532
533
} // namespace detail
534
535
template <typename CharT,typename TempAlloc =std::allocator<char>>
536
class basic_csv_parser : public ser_context
537
{
538
public:
539
    using string_view_type = jsoncons::basic_string_view<CharT>;
540
    using char_type = CharT;
541
private:
542
    struct string_maps_to_double
543
    {
544
        string_view_type s;
545
546
        bool operator()(const std::pair<string_view_type,double>& val) const
547
        {
548
            return val.first == s;
549
        }
550
    };
551
552
    using temp_allocator_type = TempAlloc;
553
    typedef typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<CharT> char_allocator_type;
554
    using string_type = std::basic_string<CharT,std::char_traits<CharT>,char_allocator_type>;
555
    typedef typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<string_type> string_allocator_type;
556
    typedef typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<csv_mode> csv_mode_allocator_type;
557
    typedef typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<csv_type_info> csv_type_info_allocator_type;
558
    typedef typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<std::vector<string_type,string_allocator_type>> string_vector_allocator_type;
559
    typedef typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<csv_parse_state> csv_parse_state_allocator_type;
560
561
    static constexpr int default_depth = 3;
562
563
    temp_allocator_type alloc_;
564
    csv_parse_state state_;
565
    std::function<bool(csv_errc,const ser_context&)> err_handler_;
566
    std::size_t column_{1};
567
    std::size_t line_{1};
568
    int nesting_depth_{default_depth};
569
    bool assume_header_;
570
    char_type comment_starter_;
571
    char_type field_delimiter_;
572
    std::size_t header_lines_;
573
    bool ignore_empty_values_;
574
    bool ignore_empty_lines_;
575
    bool infer_types_;
576
    bool lossless_number_; 
577
    csv_mapping_kind mapping_kind_;
578
    std::size_t max_lines_;
579
    char_type quote_char_;
580
    char_type quote_escape_char_;
581
    char_type subfield_delimiter_;
582
    bool trim_leading_;
583
    bool trim_leading_inside_quotes_;
584
    bool trim_trailing_;
585
    bool trim_trailing_inside_quotes_;
586
    bool unquoted_empty_value_is_null_;
587
    bool enable_str_to_inf_;   
588
    bool enable_str_to_neginf_;   
589
    bool enable_str_to_nan_;   
590
    std::basic_string<char_type> inf_to_str_;
591
    std::basic_string<char_type> neginf_to_str_;
592
    std::basic_string<char_type> nan_to_str_;
593
    std::size_t min_column_names_{0};
594
    std::size_t column_index_{0};
595
    int level_{0};
596
    std::size_t depth_{0};
597
    std::size_t offset_{0};
598
    const CharT* begin_input_{nullptr};
599
    const CharT* input_end_{nullptr};
600
    const CharT* input_ptr_{nullptr};
601
    bool more_{true};
602
    std::size_t header_line_{1};
603
    bool cursor_mode_{false};
604
    bool actual_cursor_mode_{false};
605
    int mark_level_{0};
606
    std::size_t header_line_offset_{0};
607
608
    detail::m_columns_filter<CharT,TempAlloc> m_columns_filter_;
609
    std::vector<csv_mode,csv_mode_allocator_type> stack_;
610
    std::vector<string_type,string_allocator_type> column_names_;
611
    std::vector<csv_type_info,csv_type_info_allocator_type> column_types_;
612
    std::vector<string_type,string_allocator_type> column_defaults_;
613
    std::vector<csv_parse_state,csv_parse_state_allocator_type> state_stack_;
614
    string_type buffer_;
615
616
public:
617
    basic_csv_parser()
618
       : basic_csv_parser(basic_csv_decode_options<CharT>())
619
    {
620
    }
621
622
    explicit basic_csv_parser(const TempAlloc& alloc)
623
       : basic_csv_parser(basic_csv_decode_options<CharT>(), 
624
                          default_csv_parsing(),
625
                          alloc)
626
    {
627
    }
628
629
    explicit basic_csv_parser(const basic_csv_decode_options<CharT>& options)
630
        : basic_csv_parser(options, TempAlloc{})
631
    {
632
    }
633
634
    basic_csv_parser(const basic_csv_decode_options<CharT>& options,
635
        const TempAlloc& alloc)
636
2.74k
       : alloc_(alloc),
637
2.74k
         state_(csv_parse_state::start),
638
2.74k
         err_handler_(default_csv_parsing()),
639
2.74k
         assume_header_(options.assume_header()),                  
640
2.74k
         comment_starter_(options.comment_starter()),
641
2.74k
         field_delimiter_(options.field_delimiter()),
642
2.74k
         header_lines_(options.header_lines()),
643
2.74k
         ignore_empty_values_(options.ignore_empty_values()),
644
2.74k
         ignore_empty_lines_(options.ignore_empty_lines()),
645
2.74k
         infer_types_(options.infer_types()),
646
2.74k
         lossless_number_(options.lossless_number()), 
647
2.74k
         mapping_kind_(options.mapping_kind()),
648
2.74k
         max_lines_(options.max_lines()),
649
2.74k
         quote_char_(options.quote_char()),
650
2.74k
         quote_escape_char_(options.quote_escape_char()),
651
2.74k
         subfield_delimiter_(options.subfield_delimiter()),
652
2.74k
         trim_leading_(options.trim_leading()),
653
2.74k
         trim_leading_inside_quotes_(options.trim_leading_inside_quotes()),
654
2.74k
         trim_trailing_(options.trim_trailing()),
655
2.74k
         trim_trailing_inside_quotes_(options.trim_trailing_inside_quotes()),
656
2.74k
         unquoted_empty_value_is_null_(options.unquoted_empty_value_is_null()),
657
2.74k
         enable_str_to_inf_(options.enable_str_to_inf()),
658
2.74k
         enable_str_to_neginf_(options.enable_str_to_neginf()),
659
2.74k
         enable_str_to_nan_(options.enable_str_to_nan()),
660
2.74k
         inf_to_str_(options.inf_to_str()),
661
2.74k
         neginf_to_str_(options.neginf_to_str()),
662
2.74k
         nan_to_str_(options.nan_to_str()),
663
2.74k
         m_columns_filter_(alloc),
664
2.74k
         stack_(alloc),
665
2.74k
         column_names_(alloc),
666
2.74k
         column_types_(alloc),
667
2.74k
         column_defaults_(alloc),
668
2.74k
         state_stack_(alloc),
669
2.74k
         buffer_(alloc)
670
2.74k
    {
671
2.74k
        jsoncons::csv::detail::parse_column_types(options.column_types(), column_types_);
672
2.74k
        jsoncons::csv::detail::parse_column_names(options.column_defaults(), column_defaults_);
673
2.74k
        jsoncons::csv::detail::parse_column_names(options.column_names(), column_names_);
674
2.74k
        min_column_names_ = column_names_.size();
675
2.74k
        initialize();
676
2.74k
    }
677
678
#if !defined(JSONCONS_NO_DEPRECATED)
679
    basic_csv_parser(std::function<bool(csv_errc,const ser_context&)> err_handler,
680
                     const TempAlloc& alloc = TempAlloc())
681
        : basic_csv_parser(basic_csv_decode_options<CharT>(), 
682
                           err_handler,
683
                           alloc)
684
    {
685
    }
686
687
    basic_csv_parser(const basic_csv_decode_options<CharT>& options,
688
                     std::function<bool(csv_errc,const ser_context&)> err_handler,
689
                     const TempAlloc& alloc = TempAlloc())
690
       : alloc_(alloc),
691
         state_(csv_parse_state::start),
692
         err_handler_(err_handler),
693
         assume_header_(options.assume_header()),                  
694
         comment_starter_(options.comment_starter()),
695
         field_delimiter_(options.field_delimiter()),
696
         header_lines_(options.header_lines()),
697
         ignore_empty_values_(options.ignore_empty_values()),
698
         ignore_empty_lines_(options.ignore_empty_lines()),
699
         infer_types_(options.infer_types()),
700
         lossless_number_(options.lossless_number()), 
701
         mapping_kind_(options.mapping_kind()),
702
         max_lines_(options.max_lines()),
703
         quote_char_(options.quote_char()),
704
         quote_escape_char_(options.quote_escape_char()),
705
         subfield_delimiter_(options.subfield_delimiter()),
706
         trim_leading_(options.trim_leading()),
707
         trim_leading_inside_quotes_(options.trim_leading_inside_quotes()),
708
         trim_trailing_(options.trim_trailing()),
709
         trim_trailing_inside_quotes_(options.trim_trailing_inside_quotes()),
710
         unquoted_empty_value_is_null_(options.unquoted_empty_value_is_null()),
711
         enable_str_to_inf_(options.enable_str_to_inf()),
712
         enable_str_to_neginf_(options.enable_str_to_neginf()),
713
         enable_str_to_nan_(options.enable_str_to_nan()),
714
         inf_to_str_(options.inf_to_str()),
715
         neginf_to_str_(options.neginf_to_str()),
716
         nan_to_str_(options.nan_to_str()),
717
         m_columns_filter_(alloc),
718
         stack_(alloc),
719
         column_names_(alloc),
720
         column_types_(alloc),
721
         column_defaults_(alloc),
722
         state_stack_(alloc),
723
         buffer_(alloc)
724
    {
725
        jsoncons::csv::detail::parse_column_types(options.column_types(), column_types_);
726
        jsoncons::csv::detail::parse_column_names(options.column_defaults(), column_defaults_);
727
        jsoncons::csv::detail::parse_column_names(options.column_names(), column_names_);
728
        min_column_names_ = column_names_.size();
729
        initialize();
730
    }
731
#endif
732
733
    ~basic_csv_parser() noexcept
734
2.74k
    {
735
2.74k
    }
736
737
    void cursor_mode(bool value)
738
    {
739
        actual_cursor_mode_ = value;
740
        cursor_mode_ = (mapping_kind_ == csv_mapping_kind::m_columns) ? false : value;
741
    }
742
743
    int level() const
744
3.39k
    {
745
3.39k
        return level_;
746
3.39k
    }
747
748
    int mark_level() const 
749
    {
750
        return mark_level_;
751
    }
752
753
    void mark_level(int value)
754
    {
755
        mark_level_ = value;
756
    }
757
758
    bool done() const
759
    {
760
        return state_ == csv_parse_state::done;
761
    }
762
763
    bool accept() const
764
    {
765
        return state_ == csv_parse_state::accept || state_ == csv_parse_state::done;
766
    }
767
768
    bool stopped() const
769
20.5k
    {
770
20.5k
        return !more_;
771
20.5k
    }
772
773
    bool source_exhausted() const
774
17.8k
    {
775
17.8k
        return input_ptr_ == input_end_;
776
17.8k
    }
777
778
    const std::vector<string_type,string_allocator_type>& column_labels() const
779
    {
780
        return column_names_;
781
    }
782
783
    void reinitialize()
784
    {
785
        state_ = csv_parse_state::start;
786
        column_ = 1;
787
        line_ = 1;
788
        nesting_depth_ = default_depth;
789
        column_index_ = 0;
790
        level_ = 0;
791
        depth_ = 0;
792
        offset_ = 0;
793
        begin_input_ = nullptr;
794
        input_end_ = nullptr;
795
        input_ptr_ = nullptr;
796
        more_ = true;
797
        header_line_ = 1;
798
        m_columns_filter_.reset();
799
        stack_.clear();
800
        column_names_.erase(column_names_.begin() + min_column_names_, column_names_.end());
801
        state_stack_.clear();
802
        buffer_.clear();
803
804
        initialize();
805
    }
806
807
    void restart()
808
    {
809
        more_ = true;
810
    }
811
812
    void parse_some(basic_json_visitor<CharT>& visitor)
813
    {
814
        std::error_code ec;
815
        parse_some(visitor, ec);
816
        if (JSONCONS_UNLIKELY(ec))
817
        {
818
            JSONCONS_THROW(ser_error(ec,line_,column_));
819
        }
820
    }
821
822
    void parse_some(basic_json_visitor<CharT>& visitor, std::error_code& ec)
823
17.8k
    {
824
17.8k
        basic_json_visitor<CharT>& local_visitor = (mapping_kind_ == csv_mapping_kind::m_columns) 
825
17.8k
            ? m_columns_filter_ : visitor;
826
827
17.8k
        switch (mapping_kind_)
828
17.8k
        {
829
0
            case csv_mapping_kind::m_columns:
830
0
                cursor_mode_ = false;
831
0
                break;
832
17.8k
            default:
833
17.8k
                break;
834
17.8k
        } 
835
836
17.8k
        const CharT* local_input_end = input_end_;
837
838
17.8k
        if (input_ptr_ == local_input_end && more_)
839
15.1k
        {
840
15.1k
            switch (state_)
841
15.1k
            {
842
1
                case csv_parse_state::start:
843
1
                    ec = csv_errc::source_error;
844
1
                    more_ = false;
845
1
                    return;
846
2.27k
                case csv_parse_state::before_unquoted_field:
847
2.27k
                case csv_parse_state::before_last_unquoted_field:
848
2.27k
                    end_unquoted_string_value(local_visitor, ec);
849
2.27k
                    state_ = csv_parse_state::before_last_unquoted_field_tail;
850
2.27k
                    break;
851
2.26k
                case csv_parse_state::before_last_unquoted_field_tail:
852
2.26k
                    if (stack_.back() == csv_mode::subfields)
853
0
                    {
854
0
                        stack_.pop_back();
855
0
                        local_visitor.end_array(*this, ec);
856
0
                        more_ = !cursor_mode_;
857
0
                        if (mapping_kind_ != csv_mapping_kind::m_columns)
858
0
                        {
859
0
                            if (level() == mark_level_)
860
0
                            {
861
0
                                more_ = false;
862
0
                            }
863
0
                        }
864
0
                        --level_;
865
0
                    }
866
2.26k
                    ++column_index_;
867
2.26k
                    state_ = csv_parse_state::end_record;
868
2.26k
                    break;
869
234
                case csv_parse_state::before_unquoted_string: 
870
234
                    buffer_.clear();
871
234
                    JSONCONS_FALLTHROUGH;
872
2.27k
                case csv_parse_state::unquoted_string: 
873
2.27k
                    if (trim_leading_ || trim_trailing_)
874
0
                    {
875
0
                        trim_string_buffer(trim_leading_,trim_trailing_);
876
0
                    }
877
2.27k
                    if (ignore_empty_values_ && buffer_.empty())
878
0
                    {
879
0
                        state_ = csv_parse_state::end_record;
880
0
                    }
881
2.27k
                    else
882
2.27k
                    {
883
2.27k
                        before_value(local_visitor, ec);
884
2.27k
                        state_ = csv_parse_state::before_unquoted_field;
885
2.27k
                    }
886
2.27k
                    break;
887
34
                case csv_parse_state::before_last_quoted_field:
888
34
                    end_quoted_string_value(local_visitor, ec);
889
34
                    ++column_index_;
890
34
                    state_ = csv_parse_state::end_record;
891
34
                    break;
892
34
                case csv_parse_state::escaped_value:
893
34
                    if (quote_escape_char_ == quote_char_)
894
34
                    {
895
34
                        if (!(ignore_empty_values_ && buffer_.empty()))
896
34
                        {
897
34
                            before_value(local_visitor, ec);
898
34
                            ++column_;
899
34
                            state_ = csv_parse_state::before_last_quoted_field;
900
34
                        }
901
0
                        else
902
0
                        {
903
0
                            state_ = csv_parse_state::end_record;
904
0
                        }
905
34
                    }
906
0
                    else
907
0
                    {
908
0
                        ec = csv_errc::invalid_escaped_char;
909
0
                        more_ = false;
910
0
                        return;
911
0
                    }
912
34
                    break;
913
2.63k
                case csv_parse_state::end_record:
914
2.63k
                    if (column_index_ > 0)
915
2.31k
                    {
916
2.31k
                        end_record(local_visitor, ec);
917
2.31k
                    }
918
2.63k
                    state_ = csv_parse_state::no_more_records;
919
2.63k
                    break;
920
2.63k
                case csv_parse_state::no_more_records: 
921
2.63k
                    switch (stack_.back()) 
922
2.63k
                    {
923
118
                        case csv_mode::header:
924
118
                            stack_.pop_back();
925
118
                            break;
926
2.52k
                        case csv_mode::data:
927
2.52k
                            stack_.pop_back();
928
2.52k
                            break;
929
0
                        default:
930
0
                            break;
931
2.63k
                    }
932
2.63k
                    local_visitor.end_array(*this, ec);
933
2.63k
                    more_ = !cursor_mode_;
934
2.63k
                    if (mapping_kind_ != csv_mapping_kind::m_columns)
935
2.63k
                    {
936
2.63k
                        if (level() == mark_level_)
937
0
                        {
938
0
                            more_ = false;
939
0
                        }
940
2.63k
                    }
941
2.63k
                    --level_;
942
                    
943
2.63k
                    if (mapping_kind_ == csv_mapping_kind::m_columns)
944
0
                    {
945
0
                        if (!m_columns_filter_.done())
946
0
                        {
947
0
                            more_ = m_columns_filter_.replay_parse_events(visitor, actual_cursor_mode_, mark_level_);
948
0
                        }
949
0
                        else
950
0
                        {
951
0
                            state_ = csv_parse_state::accept;
952
0
                        }
953
0
                    }
954
2.63k
                    else
955
2.63k
                    {
956
2.63k
                        state_ = csv_parse_state::accept;
957
2.63k
                    }
958
2.63k
                    break;
959
2.63k
                case csv_parse_state::accept:
960
2.63k
                    if (!(stack_.size() == 1 && stack_.back() == csv_mode::initial))
961
0
                    {
962
0
                        err_handler_(csv_errc::unexpected_eof, *this);
963
0
                        ec = csv_errc::unexpected_eof;
964
0
                        more_ = false;
965
0
                        return;
966
0
                    }
967
2.63k
                    stack_.pop_back();
968
2.63k
                    local_visitor.flush();
969
2.63k
                    state_ = csv_parse_state::done;
970
2.63k
                    more_ = false;
971
2.63k
                    return;
972
336
                default:
973
336
                    state_ = csv_parse_state::end_record;
974
336
                    break;
975
15.1k
            }
976
15.1k
        }
977
978
174M
        for (; (input_ptr_ < local_input_end) && more_;)
979
174M
        {
980
174M
            CharT curr_char = *input_ptr_;
981
982
174M
            switch (state_) 
983
174M
            {
984
5.08M
                case csv_parse_state::cr:
985
5.08M
                    ++line_;
986
5.08M
                    column_ = 1;
987
5.08M
                    switch (*input_ptr_)
988
5.08M
                    {
989
9.48k
                        case '\n':
990
9.48k
                            ++input_ptr_;
991
9.48k
                            state_ = pop_state();
992
9.48k
                            break;
993
5.07M
                        default:
994
5.07M
                            state_ = pop_state();
995
5.07M
                            break;
996
5.08M
                    }
997
5.08M
                    break;
998
5.08M
                case csv_parse_state::start:
999
2.73k
                    if (mapping_kind_ != csv_mapping_kind::m_columns)
1000
2.73k
                    {
1001
2.73k
                        local_visitor.begin_array(semantic_tag::none, *this, ec);
1002
2.73k
                        more_ = !cursor_mode_;
1003
2.73k
                        ++level_;
1004
2.73k
                    }
1005
2.73k
                    if (assume_header_ && mapping_kind_ == csv_mapping_kind::n_rows && !column_names_.empty())
1006
0
                    {
1007
0
                        column_index_ = 0; 
1008
0
                        local_visitor.begin_array(semantic_tag::none, *this, ec);
1009
0
                        ++level_;
1010
0
                        more_ = !cursor_mode_;
1011
0
                        state_ = csv_parse_state::expect_comment_or_record;
1012
0
                    }
1013
2.73k
                    else
1014
2.73k
                    {
1015
2.73k
                        state_ = csv_parse_state::expect_comment_or_record;
1016
2.73k
                    }
1017
2.73k
                    break;
1018
7.26M
                case csv_parse_state::comment: 
1019
7.26M
                    switch (curr_char)
1020
7.26M
                    {
1021
1.75M
                        case '\n':
1022
1.75M
                        {
1023
1.75M
                            ++line_;
1024
1.75M
                            if (stack_.back() == csv_mode::header)
1025
1.50M
                            {
1026
1.50M
                                ++header_line_offset_;
1027
1.50M
                            }
1028
1.75M
                            column_ = 1;
1029
1.75M
                            state_ = csv_parse_state::expect_comment_or_record;
1030
1.75M
                            break;
1031
0
                        }
1032
14.5k
                        case '\r':
1033
14.5k
                            ++line_;
1034
14.5k
                            if (stack_.back() == csv_mode::header)
1035
1.77k
                            {
1036
1.77k
                                ++header_line_offset_;
1037
1.77k
                            }
1038
14.5k
                            column_ = 1;
1039
14.5k
                            state_ = csv_parse_state::expect_comment_or_record;
1040
14.5k
                            push_state(state_);
1041
14.5k
                            state_ = csv_parse_state::cr;
1042
14.5k
                            break;
1043
5.49M
                        default:
1044
5.49M
                            ++column_;
1045
5.49M
                            break;
1046
7.26M
                    }
1047
7.26M
                    ++input_ptr_;
1048
7.26M
                    break;
1049
                
1050
10.0M
                case csv_parse_state::expect_comment_or_record:
1051
10.0M
                    buffer_.clear();
1052
10.0M
                    if (curr_char == comment_starter_)
1053
1.77M
                    {
1054
1.77M
                        state_ = csv_parse_state::comment;
1055
1.77M
                        ++column_;
1056
1.77M
                        ++input_ptr_;
1057
1.77M
                    }
1058
8.28M
                    else
1059
8.28M
                    {
1060
8.28M
                        state_ = csv_parse_state::expect_record;
1061
8.28M
                    }
1062
10.0M
                    break;
1063
3.16M
                case csv_parse_state::quoted_string: 
1064
3.16M
                    {
1065
3.16M
                        if (curr_char == quote_escape_char_)
1066
5.81k
                        {
1067
5.81k
                            state_ = csv_parse_state::escaped_value;
1068
5.81k
                        }
1069
3.15M
                        else if (curr_char == quote_char_)
1070
0
                        {
1071
0
                            state_ = csv_parse_state::between_values;
1072
0
                        }
1073
3.15M
                        else
1074
3.15M
                        {
1075
3.15M
                            buffer_.push_back(static_cast<CharT>(curr_char));
1076
3.15M
                        }
1077
3.16M
                    }
1078
3.16M
                    ++column_;
1079
3.16M
                    ++input_ptr_;
1080
3.16M
                    break;
1081
5.78k
                case csv_parse_state::escaped_value: 
1082
5.78k
                    {
1083
5.78k
                        if (curr_char == quote_char_)
1084
2.75k
                        {
1085
2.75k
                            buffer_.push_back(static_cast<CharT>(curr_char));
1086
2.75k
                            state_ = csv_parse_state::quoted_string;
1087
2.75k
                            ++column_;
1088
2.75k
                            ++input_ptr_;
1089
2.75k
                        }
1090
3.02k
                        else if (quote_escape_char_ == quote_char_)
1091
3.02k
                        {
1092
3.02k
                            state_ = csv_parse_state::between_values;
1093
3.02k
                        }
1094
0
                        else
1095
0
                        {
1096
0
                            ec = csv_errc::invalid_escaped_char;
1097
0
                            more_ = false;
1098
0
                            return;
1099
0
                        }
1100
5.78k
                    }
1101
5.78k
                    break;
1102
5.78k
                case csv_parse_state::between_values:
1103
3.51k
                    switch (curr_char)
1104
3.51k
                    {
1105
332
                        case '\r':
1106
1.19k
                        case '\n':
1107
1.19k
                        {
1108
1.19k
                            if (trim_leading_ || trim_trailing_)
1109
0
                            {
1110
0
                                trim_string_buffer(trim_leading_,trim_trailing_);
1111
0
                            }
1112
1.19k
                            if (!(ignore_empty_values_ && buffer_.empty()))
1113
1.19k
                            {
1114
1.19k
                                before_value(local_visitor, ec);
1115
1.19k
                                state_ = csv_parse_state::before_last_quoted_field;
1116
1.19k
                            }
1117
0
                            else
1118
0
                            {
1119
0
                                state_ = csv_parse_state::end_record;
1120
0
                            }
1121
1.19k
                            break;
1122
332
                        }
1123
2.32k
                        default:
1124
2.32k
                            if (curr_char == field_delimiter_)
1125
1.72k
                            {
1126
1.72k
                                if (trim_leading_ || trim_trailing_)
1127
0
                                {
1128
0
                                    trim_string_buffer(trim_leading_,trim_trailing_);
1129
0
                                }
1130
1.72k
                                before_value(local_visitor, ec);
1131
1.72k
                                state_ = csv_parse_state::before_quoted_field;
1132
1.72k
                            }
1133
599
                            else if (subfield_delimiter_ != char_type() && curr_char == subfield_delimiter_)
1134
0
                            {
1135
0
                                if (trim_leading_ || trim_trailing_)
1136
0
                                {
1137
0
                                    trim_string_buffer(trim_leading_,trim_trailing_);
1138
0
                                }
1139
0
                                before_value(local_visitor, ec);
1140
0
                                state_ = csv_parse_state::before_quoted_subfield;
1141
0
                            }
1142
599
                            else if (curr_char == ' ' || curr_char == '\t')
1143
505
                            {
1144
505
                                ++column_;
1145
505
                                ++input_ptr_;
1146
505
                            }
1147
94
                            else
1148
94
                            {
1149
94
                                ec = csv_errc::unexpected_char_between_fields;
1150
94
                                more_ = false;
1151
94
                                return;
1152
94
                            }
1153
2.22k
                            break;
1154
3.51k
                    }
1155
3.42k
                    break;
1156
20.1M
                case csv_parse_state::before_unquoted_string: 
1157
20.1M
                {
1158
20.1M
                    buffer_.clear();
1159
20.1M
                    state_ = csv_parse_state::unquoted_string;
1160
20.1M
                    break;
1161
3.51k
                }
1162
20.1M
                case csv_parse_state::before_unquoted_field:
1163
20.1M
                    end_unquoted_string_value(local_visitor, ec);
1164
20.1M
                    state_ = csv_parse_state::before_unquoted_field_tail;
1165
20.1M
                    break;
1166
20.1M
                case csv_parse_state::before_unquoted_field_tail:
1167
20.1M
                {
1168
20.1M
                    if (stack_.back() == csv_mode::subfields)
1169
0
                    {
1170
0
                        stack_.pop_back();
1171
0
                        local_visitor.end_array(*this, ec);
1172
0
                        more_ = !cursor_mode_;
1173
0
                        if (mapping_kind_ != csv_mapping_kind::m_columns)
1174
0
                        {
1175
0
                            if (level() == mark_level_)
1176
0
                            {
1177
0
                                more_ = false;
1178
0
                            }
1179
0
                        }
1180
0
                        --level_;
1181
0
                    }
1182
20.1M
                    ++column_index_;
1183
20.1M
                    state_ = csv_parse_state::before_unquoted_string;
1184
20.1M
                    ++column_;
1185
20.1M
                    ++input_ptr_;
1186
20.1M
                    break;
1187
3.51k
                }
1188
0
                case csv_parse_state::before_unquoted_field_tail1:
1189
0
                {
1190
0
                    if (stack_.back() == csv_mode::subfields)
1191
0
                    {
1192
0
                        stack_.pop_back();
1193
0
                        local_visitor.end_array(*this, ec);
1194
0
                        more_ = !cursor_mode_;
1195
0
                        if (mapping_kind_ != csv_mapping_kind::m_columns)
1196
0
                        {
1197
0
                            if (level() == mark_level_)
1198
0
                            {
1199
0
                                more_ = false;
1200
0
                            }
1201
0
                        }
1202
0
                        --level_;
1203
0
                    }
1204
0
                    state_ = csv_parse_state::end_record;
1205
0
                    ++column_;
1206
0
                    ++input_ptr_;
1207
0
                    break;
1208
3.51k
                }
1209
1210
3.93M
                case csv_parse_state::before_last_unquoted_field:
1211
3.93M
                    end_unquoted_string_value(local_visitor, ec);
1212
3.93M
                    state_ = csv_parse_state::before_last_unquoted_field_tail;
1213
3.93M
                    break;
1214
1215
3.93M
                case csv_parse_state::before_last_unquoted_field_tail:
1216
3.93M
                    if (stack_.back() == csv_mode::subfields)
1217
0
                    {
1218
0
                        stack_.pop_back();
1219
0
                        local_visitor.end_array(*this, ec);
1220
0
                        more_ = !cursor_mode_;
1221
0
                        if (mapping_kind_ != csv_mapping_kind::m_columns)
1222
0
                        {
1223
0
                            if (level() == mark_level_)
1224
0
                            {
1225
0
                                more_ = false;
1226
0
                            }
1227
0
                        }
1228
0
                        --level_;
1229
0
                    }
1230
3.93M
                    ++column_index_;
1231
3.93M
                    state_ = csv_parse_state::end_record;
1232
3.93M
                    break;
1233
1234
0
                case csv_parse_state::before_unquoted_subfield:
1235
0
                    if (stack_.back() == csv_mode::data)
1236
0
                    {
1237
0
                        stack_.push_back(csv_mode::subfields);
1238
0
                        local_visitor.begin_array(semantic_tag::none, *this, ec);
1239
0
                        more_ = !cursor_mode_;
1240
0
                        ++level_;
1241
0
                    }
1242
0
                    state_ = csv_parse_state::before_unquoted_subfield_tail;
1243
0
                    break; 
1244
0
                case csv_parse_state::before_unquoted_subfield_tail:
1245
0
                    end_unquoted_string_value(local_visitor, ec);
1246
0
                    state_ = csv_parse_state::before_unquoted_string;
1247
0
                    ++column_;
1248
0
                    ++input_ptr_;
1249
0
                    break;
1250
1.72k
                case csv_parse_state::before_quoted_field:
1251
1.72k
                    end_quoted_string_value(local_visitor, ec);
1252
1.72k
                    state_ = csv_parse_state::before_unquoted_field_tail; // return to unquoted
1253
1.72k
                    break;
1254
0
                case csv_parse_state::before_quoted_subfield:
1255
0
                    if (stack_.back() == csv_mode::data)
1256
0
                    {
1257
0
                        stack_.push_back(csv_mode::subfields);
1258
0
                        local_visitor.begin_array(semantic_tag::none, *this, ec);
1259
0
                        more_ = !cursor_mode_;
1260
0
                        ++level_;
1261
0
                    }
1262
0
                    state_ = csv_parse_state::before_quoted_subfield_tail;
1263
0
                    break; 
1264
0
                case csv_parse_state::before_quoted_subfield_tail:
1265
0
                    end_quoted_string_value(local_visitor, ec);
1266
0
                    state_ = csv_parse_state::before_unquoted_string;
1267
0
                    ++column_;
1268
0
                    ++input_ptr_;
1269
0
                    break;
1270
1.19k
                case csv_parse_state::before_last_quoted_field:
1271
1.19k
                    end_quoted_string_value(local_visitor, ec);
1272
1.19k
                    state_ = csv_parse_state::before_last_quoted_field_tail;
1273
1.19k
                    break;
1274
1.19k
                case csv_parse_state::before_last_quoted_field_tail:
1275
1.19k
                    if (stack_.back() == csv_mode::subfields)
1276
0
                    {
1277
0
                        stack_.pop_back();
1278
0
                        local_visitor.end_array(*this, ec);
1279
0
                        more_ = !cursor_mode_;
1280
0
                        if (mapping_kind_ != csv_mapping_kind::m_columns)
1281
0
                        {
1282
0
                            if (level() == mark_level_)
1283
0
                            {
1284
0
                                more_ = false;
1285
0
                            }
1286
0
                        }
1287
0
                        --level_;
1288
0
                    }
1289
1.19k
                    ++column_index_;
1290
1.19k
                    state_ = csv_parse_state::end_record;
1291
1.19k
                    break;
1292
65.8M
                case csv_parse_state::unquoted_string: 
1293
65.8M
                {
1294
65.8M
                    switch (curr_char)
1295
65.8M
                    {
1296
1.32M
                        case '\n':
1297
3.93M
                        case '\r':
1298
3.93M
                        {
1299
3.93M
                            if (trim_leading_ || trim_trailing_)
1300
0
                            {
1301
0
                                trim_string_buffer(trim_leading_,trim_trailing_);
1302
0
                            }
1303
3.93M
                            if (!(ignore_empty_values_ && buffer_.empty()))
1304
3.93M
                            {
1305
3.93M
                                before_value(local_visitor, ec);
1306
3.93M
                                state_ = csv_parse_state::before_last_unquoted_field;
1307
3.93M
                            }
1308
0
                            else
1309
0
                            {
1310
0
                                state_ = csv_parse_state::end_record;
1311
0
                            }
1312
3.93M
                            break;
1313
1.32M
                        }
1314
61.9M
                        default:
1315
61.9M
                            if (curr_char == field_delimiter_)
1316
20.1M
                            {
1317
20.1M
                                if (trim_leading_ || trim_trailing_)
1318
0
                                {
1319
0
                                    trim_string_buffer(trim_leading_,trim_trailing_);
1320
0
                                }
1321
20.1M
                                before_value(local_visitor, ec);
1322
20.1M
                                state_ = csv_parse_state::before_unquoted_field;
1323
20.1M
                            }
1324
41.7M
                            else if (subfield_delimiter_ != char_type() && curr_char == subfield_delimiter_)
1325
0
                            {
1326
0
                                if (trim_leading_ || trim_trailing_)
1327
0
                                {
1328
0
                                    trim_string_buffer(trim_leading_,trim_trailing_);
1329
0
                                }
1330
0
                                before_value(local_visitor, ec);
1331
0
                                state_ = csv_parse_state::before_unquoted_subfield;
1332
0
                            }
1333
41.7M
                            else if (curr_char == quote_char_)
1334
1.47k
                            {
1335
1.47k
                                buffer_.clear();
1336
1.47k
                                state_ = csv_parse_state::quoted_string;
1337
1.47k
                                ++column_;
1338
1.47k
                                ++input_ptr_;
1339
1.47k
                            }
1340
41.7M
                            else
1341
41.7M
                            {
1342
41.7M
                                buffer_.push_back(static_cast<CharT>(curr_char));
1343
41.7M
                                ++column_;
1344
41.7M
                                ++input_ptr_;
1345
41.7M
                            }
1346
61.9M
                            break;
1347
65.8M
                    }
1348
65.8M
                    break;
1349
65.8M
                }
1350
65.8M
                case csv_parse_state::expect_record: 
1351
10.7M
                {
1352
10.7M
                    switch (curr_char)
1353
10.7M
                    {
1354
4.35M
                        case '\n':
1355
4.35M
                        {
1356
4.35M
                            if (!ignore_empty_lines_)
1357
0
                            {
1358
0
                                begin_record(local_visitor, ec);
1359
0
                                state_ = csv_parse_state::end_record;
1360
0
                            }
1361
4.35M
                            else
1362
4.35M
                            {
1363
4.35M
                                ++line_;
1364
4.35M
                                column_ = 1;
1365
4.35M
                                state_ = csv_parse_state::expect_comment_or_record;
1366
4.35M
                                ++input_ptr_;
1367
4.35M
                            }
1368
4.35M
                            break;
1369
0
                        }
1370
2.45M
                        case '\r':
1371
2.45M
                            if (!ignore_empty_lines_)
1372
0
                            {
1373
0
                                begin_record(local_visitor, ec);
1374
0
                                state_ = csv_parse_state::end_record;
1375
0
                            }
1376
2.45M
                            else
1377
2.45M
                            {
1378
2.45M
                                ++input_ptr_;
1379
2.45M
                                push_state(state_);
1380
2.45M
                                state_ = csv_parse_state::cr;
1381
2.45M
                            }
1382
2.45M
                            break;
1383
6.88k
                        case ' ':
1384
64.9k
                        case '\t':
1385
64.9k
                            if (!trim_leading_)
1386
64.9k
                            {
1387
64.9k
                                buffer_.push_back(static_cast<CharT>(curr_char));
1388
64.9k
                                begin_record(local_visitor, ec);
1389
64.9k
                                state_ = csv_parse_state::unquoted_string;
1390
64.9k
                            }
1391
64.9k
                            ++column_;
1392
64.9k
                            ++input_ptr_;
1393
64.9k
                            break;
1394
3.87M
                        default:
1395
3.87M
                            begin_record(local_visitor, ec);
1396
3.87M
                            if (curr_char == quote_char_)
1397
1.68k
                            {
1398
1.68k
                                buffer_.clear();
1399
1.68k
                                state_ = csv_parse_state::quoted_string;
1400
1.68k
                                ++column_;
1401
1.68k
                                ++input_ptr_;
1402
1.68k
                            }
1403
3.86M
                            else
1404
3.86M
                            {
1405
3.86M
                                state_ = csv_parse_state::unquoted_string;
1406
3.86M
                            }
1407
3.87M
                            break;
1408
10.7M
                        }
1409
10.7M
                    break;
1410
10.7M
                    }
1411
10.7M
                case csv_parse_state::end_record: 
1412
3.93M
                {
1413
3.93M
                    switch (curr_char)
1414
3.93M
                    {
1415
1.32M
                        case '\n':
1416
1.32M
                        {
1417
1.32M
                            ++line_;
1418
1.32M
                            column_ = 1;
1419
1.32M
                            state_ = csv_parse_state::expect_comment_or_record;
1420
1.32M
                            end_record(local_visitor, ec);
1421
1.32M
                            ++input_ptr_;
1422
1.32M
                            break;
1423
0
                        }
1424
2.61M
                        case '\r':
1425
2.61M
                            ++line_;
1426
2.61M
                            column_ = 1;
1427
2.61M
                            state_ = csv_parse_state::expect_comment_or_record;
1428
2.61M
                            end_record(local_visitor, ec);
1429
2.61M
                            push_state(state_);
1430
2.61M
                            state_ = csv_parse_state::cr;
1431
2.61M
                            ++input_ptr_;
1432
2.61M
                            break;
1433
0
                        case ' ':
1434
0
                        case '\t':
1435
0
                            ++column_;
1436
0
                            ++input_ptr_;
1437
0
                            break;
1438
0
                        default:
1439
0
                            err_handler_(csv_errc::syntax_error, *this);
1440
0
                            ec = csv_errc::syntax_error;
1441
0
                            more_ = false;
1442
0
                            return;
1443
3.93M
                        }
1444
3.93M
                    break;
1445
3.93M
                }
1446
3.93M
                default:
1447
0
                    err_handler_(csv_errc::invalid_parse_state, *this);
1448
0
                    ec = csv_errc::invalid_parse_state;
1449
0
                    more_ = false;
1450
0
                    return;
1451
174M
            }
1452
174M
            if (line_ > max_lines_)
1453
0
            {
1454
0
                state_ = csv_parse_state::done;
1455
0
                more_ = false;
1456
0
            }
1457
174M
        }
1458
15.2k
    }
1459
1460
    void finish_parse()
1461
    {
1462
        std::error_code ec;
1463
        finish_parse(ec);
1464
        if (JSONCONS_UNLIKELY(ec))
1465
        {
1466
            JSONCONS_THROW(ser_error(ec,line_,column_));
1467
        }
1468
    }
1469
1470
    void finish_parse(std::error_code& ec)
1471
    {
1472
        while (more_)
1473
        {
1474
            parse_some(ec);
1475
        }
1476
    }
1477
1478
    csv_parse_state state() const
1479
    {
1480
        return state_;
1481
    }
1482
1483
    void update(const string_view_type sv)
1484
    {
1485
        update(sv.data(),sv.length());
1486
    }
1487
1488
    void update(const CharT* data, std::size_t length)
1489
2.73k
    {
1490
2.73k
        begin_input_ = data;
1491
2.73k
        input_end_ = data + length;
1492
2.73k
        input_ptr_ = begin_input_;
1493
2.73k
    }
1494
1495
    std::size_t line() const final
1496
111
    {
1497
111
        return line_;
1498
111
    }
1499
1500
    std::size_t column() const final
1501
111
    {
1502
111
        return column_;
1503
111
    }
1504
1505
private:
1506
    void initialize()
1507
2.74k
    {
1508
2.74k
        stack_.reserve(default_depth);
1509
2.74k
        stack_.push_back(csv_mode::initial);
1510
2.74k
        stack_.push_back((header_lines_ > 0) ? csv_mode::header : csv_mode::data);
1511
2.74k
    }
1512
1513
    // name
1514
    void before_value(basic_json_visitor<CharT>& visitor, 
1515
        std::error_code& ec)
1516
24.0M
    {
1517
24.0M
        switch (stack_.back())
1518
24.0M
        {
1519
12.5M
            case csv_mode::header:
1520
12.5M
                if (trim_leading_inside_quotes_ || trim_trailing_inside_quotes_)
1521
0
                {
1522
0
                    trim_string_buffer(trim_leading_inside_quotes_,trim_trailing_inside_quotes_);
1523
0
                }
1524
12.5M
                if (line_ == (header_line_+header_line_offset_) && column_index_ >= min_column_names_)
1525
12.5M
                {
1526
12.5M
                    column_names_.push_back(buffer_);
1527
12.5M
                    if (assume_header_ && mapping_kind_ == csv_mapping_kind::n_rows)
1528
12.5M
                    {
1529
12.5M
                        visitor.string_value(buffer_, semantic_tag::none, *this, ec);
1530
12.5M
                        more_ = !cursor_mode_;
1531
12.5M
                    }
1532
12.5M
                }
1533
12.5M
                break;
1534
11.4M
            case csv_mode::data:
1535
11.4M
                if (mapping_kind_ == csv_mapping_kind::n_objects)
1536
0
                {
1537
0
                    if (!(ignore_empty_values_ && buffer_.empty()))
1538
0
                    {
1539
0
                        if (column_index_ < column_names_.size() + offset_)
1540
0
                        {
1541
0
                            visitor.key(column_names_[column_index_ - offset_], *this, ec);
1542
0
                            more_ = !cursor_mode_;
1543
0
                        }
1544
0
                    }
1545
0
                }
1546
11.4M
                break;
1547
0
            default:
1548
0
                break;
1549
24.0M
        }
1550
24.0M
    }
1551
1552
    // begin_array or begin_record
1553
    void begin_record(basic_json_visitor<CharT>& visitor, std::error_code& ec)
1554
3.93M
    {
1555
3.93M
        offset_ = 0;
1556
1557
3.93M
        if (stack_.back() == csv_mode::header && line_ > (header_lines_+header_line_offset_))
1558
1.79k
        {
1559
1.79k
            stack_.back() = csv_mode::data;
1560
1.79k
        }
1561
3.93M
        switch (stack_.back())
1562
3.93M
        {
1563
871
            case csv_mode::header:
1564
871
                switch (mapping_kind_)
1565
871
                {
1566
871
                    case csv_mapping_kind::n_rows:
1567
871
                        if (assume_header_ && line_ == (header_line_+header_line_offset_))
1568
871
                        {
1569
871
                            visitor.begin_array(semantic_tag::none, *this, ec);
1570
871
                            more_ = !cursor_mode_;
1571
871
                            ++level_;
1572
871
                        }
1573
871
                        break;
1574
0
                    default:
1575
0
                        break;
1576
871
                }
1577
871
                break;
1578
3.93M
            case csv_mode::data:
1579
3.93M
                switch (mapping_kind_)
1580
3.93M
                {
1581
3.93M
                    case csv_mapping_kind::n_rows:
1582
3.93M
                        visitor.begin_array(semantic_tag::none, *this, ec);
1583
3.93M
                        more_ = !cursor_mode_;
1584
3.93M
                        ++level_;
1585
3.93M
                        break;
1586
0
                    case csv_mapping_kind::n_objects:
1587
0
                        visitor.begin_object(semantic_tag::none, *this, ec);
1588
0
                        more_ = !cursor_mode_;
1589
0
                        ++level_;
1590
0
                        break;
1591
0
                    case csv_mapping_kind::m_columns:
1592
0
                        break;
1593
0
                    default:
1594
0
                        break;
1595
3.93M
                }
1596
3.93M
                break;
1597
3.93M
            default:
1598
0
                break;
1599
3.93M
        }
1600
3.93M
    }
1601
1602
    // end_array, begin_array, string_value (headers)
1603
    void end_record(basic_json_visitor<CharT>& visitor, std::error_code& ec)
1604
3.93M
    {
1605
3.93M
        if (!column_types_.empty())
1606
0
        {
1607
0
            switch (mapping_kind_)
1608
0
            {
1609
0
                case csv_mapping_kind::n_rows:
1610
0
                case csv_mapping_kind::n_objects:
1611
0
                    if (depth_ > 0)
1612
0
                    {
1613
0
                        visitor.end_array(*this, ec);
1614
0
                        more_ = !cursor_mode_;
1615
0
                        if (level_ == mark_level_)
1616
0
                        {
1617
0
                            more_ = false;
1618
0
                        }
1619
0
                        --level_;
1620
0
                        depth_ = 0;
1621
0
                    }
1622
0
                    break;
1623
0
                case csv_mapping_kind::m_columns:
1624
0
                    if (depth_ > 0)
1625
0
                    {
1626
0
                        visitor.end_array(*this, ec);
1627
0
                        more_ = !cursor_mode_;
1628
0
                        --level_;
1629
0
                        depth_ = 0;
1630
0
                    }
1631
0
                    break;
1632
0
                default:
1633
0
                    break;
1634
0
            }
1635
0
        }
1636
3.93M
        switch (stack_.back())
1637
3.93M
        {
1638
760
            case csv_mode::header:
1639
760
                if (line_ >= header_lines_)
1640
760
                {
1641
760
                    stack_.back() = csv_mode::data;
1642
760
                }
1643
760
                switch (mapping_kind_)
1644
760
                {
1645
760
                    case csv_mapping_kind::n_rows:
1646
760
                        if (assume_header_)
1647
760
                        {
1648
760
                            visitor.end_array(*this, ec);
1649
760
                            more_ = !cursor_mode_;
1650
760
                            if (level() == mark_level_)
1651
0
                            {
1652
0
                                more_ = false;
1653
0
                            }
1654
760
                            --level_;
1655
760
                        }
1656
760
                        break;
1657
0
                    case csv_mapping_kind::m_columns:
1658
0
                        m_columns_filter_.initialize(column_names_);
1659
0
                        break;
1660
0
                    default:
1661
0
                        break;
1662
760
                }
1663
760
                break;
1664
3.93M
            case csv_mode::data:
1665
3.93M
            case csv_mode::subfields:
1666
3.93M
            {
1667
3.93M
                switch (mapping_kind_)
1668
3.93M
                {
1669
3.93M
                    case csv_mapping_kind::n_rows:
1670
3.93M
                        visitor.end_array(*this, ec);
1671
3.93M
                        more_ = !cursor_mode_;
1672
3.93M
                        if (level_ == mark_level_)
1673
0
                        {
1674
0
                            more_ = false;
1675
0
                        }
1676
3.93M
                        --level_;
1677
3.93M
                        break;
1678
0
                    case csv_mapping_kind::n_objects:
1679
0
                        visitor.end_object(*this, ec);
1680
0
                        more_ = !cursor_mode_;
1681
0
                        if (level_ == mark_level_)
1682
0
                        {
1683
0
                            more_ = false;
1684
0
                        }
1685
0
                        --level_;
1686
0
                        break;
1687
0
                    case csv_mapping_kind::m_columns:
1688
0
                        visitor.end_array(*this, ec);
1689
0
                        more_ = !cursor_mode_;
1690
0
                        --level_;
1691
0
                        break;
1692
3.93M
                }
1693
3.93M
                break;
1694
3.93M
            }
1695
3.93M
            default:
1696
0
                break;
1697
3.93M
        }
1698
3.93M
        column_index_ = 0;
1699
3.93M
    }
1700
1701
    void trim_string_buffer(bool trim_leading, bool trim_trailing)
1702
0
    {
1703
0
        std::size_t start = 0;
1704
0
        std::size_t length = buffer_.length();
1705
0
        if (trim_leading)
1706
0
        {
1707
0
            bool done = false;
1708
0
            while (!done && start < buffer_.length())
1709
0
            {
1710
0
                if ((buffer_[start] < 256) && std::isspace(buffer_[start]))
1711
0
                {
1712
0
                    ++start;
1713
0
                }
1714
0
                else
1715
0
                {
1716
0
                    done = true;
1717
0
                }
1718
0
            }
1719
0
        }
1720
0
        if (trim_trailing)
1721
0
        {
1722
0
            bool done = false;
1723
0
            while (!done && length > 0)
1724
0
            {
1725
0
                if ((buffer_[length-1] < 256) && std::isspace(buffer_[length-1]))
1726
0
                {
1727
0
                    --length;
1728
0
                }
1729
0
                else
1730
0
                {
1731
0
                    done = true;
1732
0
                }
1733
0
            }
1734
0
        }
1735
0
        if (start != 0 || length != buffer_.size())
1736
0
        {
1737
            // Do not use buffer_.substr(...), as this won't preserve the allocator state.
1738
0
            buffer_.resize(length);
1739
0
            buffer_.erase(0, start);
1740
0
        }
1741
0
    }
1742
1743
    /*
1744
        end_array, begin_array, xxx_value (end_value)
1745
    */
1746
    void end_unquoted_string_value(basic_json_visitor<CharT>& visitor, std::error_code& ec) 
1747
24.0M
    {
1748
24.0M
        switch (stack_.back())
1749
24.0M
        {
1750
11.4M
            case csv_mode::data:
1751
11.4M
            case csv_mode::subfields:
1752
11.4M
                switch (mapping_kind_)
1753
11.4M
                {
1754
11.4M
                case csv_mapping_kind::n_rows:
1755
11.4M
                    if (unquoted_empty_value_is_null_ && buffer_.empty())
1756
0
                    {
1757
0
                        visitor.null_value(semantic_tag::none, *this, ec);
1758
0
                        more_ = !cursor_mode_;
1759
0
                    }
1760
11.4M
                    else
1761
11.4M
                    {
1762
11.4M
                        end_value(visitor, infer_types_, ec);
1763
11.4M
                    }
1764
11.4M
                    break;
1765
0
                case csv_mapping_kind::n_objects:
1766
0
                    if (!(ignore_empty_values_ && buffer_.empty()))
1767
0
                    {
1768
0
                        if (column_index_ < column_names_.size() + offset_)
1769
0
                        {
1770
0
                            if (unquoted_empty_value_is_null_ && buffer_.empty())
1771
0
                            {
1772
0
                                visitor.null_value(semantic_tag::none, *this, ec);
1773
0
                                more_ = !cursor_mode_;
1774
0
                            }
1775
0
                            else
1776
0
                            {
1777
0
                                end_value(visitor, infer_types_, ec);
1778
0
                            }
1779
0
                        }
1780
0
                        else if (depth_ > 0)
1781
0
                        {
1782
0
                            if (unquoted_empty_value_is_null_ && buffer_.empty())
1783
0
                            {
1784
0
                                visitor.null_value(semantic_tag::none, *this, ec);
1785
0
                                more_ = !cursor_mode_;
1786
0
                            }
1787
0
                            else
1788
0
                            {
1789
0
                                end_value(visitor, infer_types_, ec);
1790
0
                            }
1791
0
                        }
1792
0
                    }
1793
0
                    break;
1794
0
                case csv_mapping_kind::m_columns:
1795
0
                    if (!(ignore_empty_values_ && buffer_.empty()))
1796
0
                    {
1797
0
                        end_value(visitor, infer_types_, ec);
1798
0
                    }
1799
0
                    else
1800
0
                    {
1801
0
                        m_columns_filter_.skip_column();
1802
0
                    }
1803
0
                    break;
1804
11.4M
                }
1805
11.4M
                break;
1806
12.5M
            default:
1807
12.5M
                break;
1808
24.0M
        }
1809
24.0M
    }
1810
1811
    void end_quoted_string_value(basic_json_visitor<CharT>& visitor, 
1812
        std::error_code& ec) 
1813
2.94k
    {
1814
2.94k
        switch (stack_.back())
1815
2.94k
        {
1816
2.01k
            case csv_mode::data:
1817
2.01k
            case csv_mode::subfields:
1818
2.01k
                if (trim_leading_inside_quotes_ || trim_trailing_inside_quotes_)
1819
0
                {
1820
0
                    trim_string_buffer(trim_leading_inside_quotes_,trim_trailing_inside_quotes_);
1821
0
                }
1822
2.01k
                switch (mapping_kind_)
1823
2.01k
                {
1824
2.01k
                case csv_mapping_kind::n_rows:
1825
2.01k
                    end_value(visitor, false, ec);
1826
2.01k
                    break;
1827
0
                case csv_mapping_kind::n_objects:
1828
0
                    if (!(ignore_empty_values_ && buffer_.empty()))
1829
0
                    {
1830
0
                        if (column_index_ < column_names_.size() + offset_)
1831
0
                        {
1832
0
                            if (unquoted_empty_value_is_null_ && buffer_.empty())
1833
0
                            {
1834
0
                                visitor.null_value(semantic_tag::none, *this, ec);
1835
0
                                more_ = !cursor_mode_;
1836
0
                            }
1837
0
                            else 
1838
0
                            {
1839
0
                                end_value(visitor, false, ec);
1840
0
                            }
1841
0
                        }
1842
0
                        else if (depth_ > 0)
1843
0
                        {
1844
0
                            if (unquoted_empty_value_is_null_ && buffer_.empty())
1845
0
                            {
1846
0
                                visitor.null_value(semantic_tag::none, *this, ec);
1847
0
                                more_ = !cursor_mode_;
1848
0
                            }
1849
0
                            else
1850
0
                            {
1851
0
                                end_value(visitor, false, ec);
1852
0
                            }
1853
0
                        }
1854
0
                    }
1855
0
                    break;
1856
0
                case csv_mapping_kind::m_columns:
1857
0
                    if (!(ignore_empty_values_ && buffer_.empty()))
1858
0
                    {
1859
0
                        end_value(visitor, false, ec);
1860
0
                    }
1861
0
                    else
1862
0
                    {
1863
0
                        m_columns_filter_.skip_column();
1864
0
                    }
1865
0
                    break;
1866
2.01k
                }
1867
2.01k
                break;
1868
2.01k
            default:
1869
937
                break;
1870
2.94k
        }
1871
2.94k
    }
1872
1873
    void end_value(basic_json_visitor<CharT>& visitor, 
1874
        bool infer_types, std::error_code&  ec)
1875
11.4M
    {
1876
11.4M
        if (enable_str_to_inf_ && buffer_ == inf_to_str_)
1877
0
        {
1878
0
            visitor.double_value(std::numeric_limits<double>::infinity(), semantic_tag::none, *this, ec);
1879
0
            more_ = !cursor_mode_;
1880
0
        }
1881
11.4M
        else if (enable_str_to_neginf_ && buffer_ == neginf_to_str_)
1882
0
        {
1883
0
            visitor.double_value(-std::numeric_limits<double>::infinity(), semantic_tag::none, *this, ec);
1884
0
            more_ = !cursor_mode_;
1885
0
        }
1886
11.4M
        else if (enable_str_to_nan_ && buffer_ == nan_to_str_)
1887
0
        {
1888
0
            visitor.double_value(std::numeric_limits<double>::quiet_NaN(), semantic_tag::none, *this, ec);
1889
0
            more_ = !cursor_mode_;
1890
0
        }
1891
11.4M
        else if (column_index_ < column_types_.size() + offset_)
1892
0
        {
1893
0
            if (column_types_[column_index_ - offset_].col_type == csv_column_type::repeat_t)
1894
0
            {
1895
0
                offset_ = offset_ + column_types_[column_index_ - offset_].rep_count;
1896
0
                if (column_index_ - offset_ + 1 < column_types_.size())
1897
0
                {
1898
0
                    if (column_index_ == offset_ || depth_ > column_types_[column_index_-offset_].level)
1899
0
                    {
1900
0
                        visitor.end_array(*this, ec);
1901
0
                        more_ = !cursor_mode_;
1902
0
                        if (mapping_kind_ != csv_mapping_kind::m_columns)
1903
0
                        {
1904
0
                            if (level() == mark_level_)
1905
0
                            {
1906
0
                                more_ = false;
1907
0
                            }
1908
0
                        }
1909
0
                        --level_;
1910
0
                    }
1911
0
                    depth_ = column_index_ == offset_ ? 0 : column_types_[column_index_ - offset_].level;
1912
0
                }
1913
0
            }
1914
0
            if (depth_ < column_types_[column_index_ - offset_].level)
1915
0
            {
1916
0
                visitor.begin_array(semantic_tag::none, *this, ec);
1917
0
                more_ = !cursor_mode_;
1918
0
                depth_ = column_types_[column_index_ - offset_].level;
1919
0
                ++level_;
1920
0
            }
1921
0
            else if (depth_ > column_types_[column_index_ - offset_].level)
1922
0
            {
1923
0
                visitor.end_array(*this, ec);
1924
0
                more_ = !cursor_mode_;
1925
0
                if (mapping_kind_ != csv_mapping_kind::m_columns)
1926
0
                {
1927
0
                    if (level() == mark_level_)
1928
0
                    {
1929
0
                        more_ = false;
1930
0
                    }
1931
0
                }
1932
0
                --level_;
1933
0
                depth_ = column_types_[column_index_ - offset_].level;
1934
0
            }
1935
0
            switch (column_types_[column_index_ - offset_].col_type)
1936
0
            {
1937
0
                case csv_column_type::integer_t:
1938
0
                    {
1939
0
                        std::basic_istringstream<CharT,std::char_traits<CharT>,char_allocator_type> iss{buffer_};
1940
0
                        int64_t val;
1941
0
                        iss >> val;
1942
0
                        if (!iss.fail())
1943
0
                        {
1944
0
                            visitor.int64_value(val, semantic_tag::none, *this, ec);
1945
0
                            more_ = !cursor_mode_;
1946
0
                        }
1947
0
                        else
1948
0
                        {
1949
0
                            if (column_index_ - offset_ < column_defaults_.size() && column_defaults_[column_index_ - offset_].length() > 0)
1950
0
                            {
1951
0
                                basic_json_parser<CharT,temp_allocator_type> parser(alloc_);
1952
0
                                parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length());
1953
0
                                parser.parse_some(visitor);
1954
0
                                parser.finish_parse(visitor);
1955
0
                            }
1956
0
                            else
1957
0
                            {
1958
0
                                visitor.null_value(semantic_tag::none, *this, ec);
1959
0
                                more_ = !cursor_mode_;
1960
0
                            }
1961
0
                        }
1962
0
                    }
1963
0
                    break;
1964
0
                case csv_column_type::float_t:
1965
0
                    {
1966
0
                        if (lossless_number_)
1967
0
                        {
1968
0
                            visitor.string_value(buffer_,semantic_tag::bigdec, *this, ec);
1969
0
                            more_ = !cursor_mode_;
1970
0
                        }
1971
0
                        else
1972
0
                        {
1973
0
                            std::basic_istringstream<CharT, std::char_traits<CharT>, char_allocator_type> iss{ buffer_ };
1974
0
                            double val;
1975
0
                            iss >> val;
1976
0
                            if (!iss.fail())
1977
0
                            {
1978
0
                                visitor.double_value(val, semantic_tag::none, *this, ec);
1979
0
                                more_ = !cursor_mode_;
1980
0
                            }
1981
0
                            else
1982
0
                            {
1983
0
                                if (column_index_ - offset_ < column_defaults_.size() && column_defaults_[column_index_ - offset_].length() > 0)
1984
0
                                {
1985
0
                                    basic_json_parser<CharT,temp_allocator_type> parser(alloc_);
1986
0
                                    parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length());
1987
0
                                    parser.parse_some(visitor);
1988
0
                                    parser.finish_parse(visitor);
1989
0
                                }
1990
0
                                else
1991
0
                                {
1992
0
                                    visitor.null_value(semantic_tag::none, *this, ec);
1993
0
                                    more_ = !cursor_mode_;
1994
0
                                }
1995
0
                            }
1996
0
                        }
1997
0
                    }
1998
0
                    break;
1999
0
                case csv_column_type::boolean_t:
2000
0
                    {
2001
0
                        if (buffer_.length() == 1 && buffer_[0] == '0')
2002
0
                        {
2003
0
                            visitor.bool_value(false, semantic_tag::none, *this, ec);
2004
0
                            more_ = !cursor_mode_;
2005
0
                        }
2006
0
                        else if (buffer_.length() == 1 && buffer_[0] == '1')
2007
0
                        {
2008
0
                            visitor.bool_value(true, semantic_tag::none, *this, ec);
2009
0
                            more_ = !cursor_mode_;
2010
0
                        }
2011
0
                        else if (buffer_.length() == 5 && ((buffer_[0] == 'f' || buffer_[0] == 'F') && (buffer_[1] == 'a' || buffer_[1] == 'A') && (buffer_[2] == 'l' || buffer_[2] == 'L') && (buffer_[3] == 's' || buffer_[3] == 'S') && (buffer_[4] == 'e' || buffer_[4] == 'E')))
2012
0
                        {
2013
0
                            visitor.bool_value(false, semantic_tag::none, *this, ec);
2014
0
                            more_ = !cursor_mode_;
2015
0
                        }
2016
0
                        else if (buffer_.length() == 4 && ((buffer_[0] == 't' || buffer_[0] == 'T') && (buffer_[1] == 'r' || buffer_[1] == 'R') && (buffer_[2] == 'u' || buffer_[2] == 'U') && (buffer_[3] == 'e' || buffer_[3] == 'E')))
2017
0
                        {
2018
0
                            visitor.bool_value(true, semantic_tag::none, *this, ec);
2019
0
                            more_ = !cursor_mode_;
2020
0
                        }
2021
0
                        else
2022
0
                        {
2023
0
                            if (column_index_ - offset_ < column_defaults_.size() && column_defaults_[column_index_ - offset_].length() > 0)
2024
0
                            {
2025
0
                                basic_json_parser<CharT,temp_allocator_type> parser(alloc_);
2026
0
                                parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length());
2027
0
                                parser.parse_some(visitor);
2028
0
                                parser.finish_parse(visitor);
2029
0
                            }
2030
0
                            else
2031
0
                            {
2032
0
                                visitor.null_value(semantic_tag::none, *this, ec);
2033
0
                                more_ = !cursor_mode_;
2034
0
                            }
2035
0
                        }
2036
0
                    }
2037
0
                    break;
2038
0
                default:
2039
0
                    if (buffer_.length() > 0)
2040
0
                    {
2041
0
                        visitor.string_value(buffer_, semantic_tag::none, *this, ec);
2042
0
                        more_ = !cursor_mode_;
2043
0
                    }
2044
0
                    else
2045
0
                    {
2046
0
                        if (column_index_ < column_defaults_.size() + offset_ && column_defaults_[column_index_ - offset_].length() > 0)
2047
0
                        {
2048
0
                            basic_json_parser<CharT,temp_allocator_type> parser(alloc_);
2049
0
                            parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length());
2050
0
                            parser.parse_some(visitor);
2051
0
                            parser.finish_parse(visitor);
2052
0
                        }
2053
0
                        else
2054
0
                        {
2055
0
                            visitor.string_value(string_view_type(), semantic_tag::none, *this, ec);
2056
0
                            more_ = !cursor_mode_;
2057
0
                        }
2058
0
                    }
2059
0
                    break;  
2060
0
            }
2061
0
        }
2062
11.4M
        else
2063
11.4M
        {
2064
11.4M
            if (infer_types)
2065
11.4M
            {
2066
11.4M
                end_value_with_numeric_check(visitor, ec);
2067
11.4M
            }
2068
2.01k
            else
2069
2.01k
            {
2070
2.01k
                visitor.string_value(buffer_, semantic_tag::none, *this, ec);
2071
2.01k
                more_ = !cursor_mode_;
2072
2.01k
            }
2073
11.4M
        }
2074
11.4M
    }
2075
2076
    enum class numeric_check_state 
2077
    {
2078
        initial,
2079
        null,
2080
        boolean_true,
2081
        boolean_false,
2082
        minus,
2083
        zero,
2084
        integer,
2085
        fraction1,
2086
        fraction,
2087
        exp1,
2088
        exp,
2089
        not_a_number
2090
    };
2091
2092
    /*
2093
        xxx_value 
2094
    */
2095
    void end_value_with_numeric_check(basic_json_visitor<CharT>& visitor, 
2096
        std::error_code& ec)
2097
11.4M
    {
2098
11.4M
        numeric_check_state state = numeric_check_state::initial;
2099
11.4M
        bool is_negative = false;
2100
        //int precision = 0;
2101
        //uint8_t decimal_places = 0;
2102
2103
11.4M
        auto last = buffer_.end();
2104
2105
11.4M
        std::string buffer;
2106
26.2M
        for (auto p = buffer_.begin(); state != numeric_check_state::not_a_number && p != last; ++p)
2107
14.7M
        {
2108
14.7M
            switch (state)
2109
14.7M
            {
2110
3.79M
                case numeric_check_state::initial:
2111
3.79M
                {
2112
3.79M
                    switch (*p)
2113
3.79M
                    {
2114
182k
                    case 'n':case 'N':
2115
182k
                        if ((last-p) == 4 && (p[1] == 'u' || p[1] == 'U') && (p[2] == 'l' || p[2] == 'L') && (p[3] == 'l' || p[3] == 'L'))
2116
156k
                        {
2117
156k
                            state = numeric_check_state::null;
2118
156k
                        }
2119
26.0k
                        else
2120
26.0k
                        {
2121
26.0k
                            state = numeric_check_state::not_a_number;
2122
26.0k
                        }
2123
182k
                        break;
2124
180k
                    case 't':case 'T':
2125
180k
                        if ((last-p) == 4 && (p[1] == 'r' || p[1] == 'R') && (p[2] == 'u' || p[2] == 'U') && (p[3] == 'e' || p[3] == 'U'))
2126
167k
                        {
2127
167k
                            state = numeric_check_state::boolean_true;
2128
167k
                        }
2129
12.8k
                        else
2130
12.8k
                        {
2131
12.8k
                            state = numeric_check_state::not_a_number;
2132
12.8k
                        }
2133
180k
                        break;
2134
15.8k
                    case 'f':case 'F':
2135
15.8k
                        if ((last-p) == 5 && (p[1] == 'a' || p[1] == 'A') && (p[2] == 'l' || p[2] == 'L') && (p[3] == 's' || p[3] == 'S') && (p[4] == 'e' || p[4] == 'E'))
2136
3.86k
                        {
2137
3.86k
                            state = numeric_check_state::boolean_false;
2138
3.86k
                        }
2139
12.0k
                        else
2140
12.0k
                        {
2141
12.0k
                            state = numeric_check_state::not_a_number;
2142
12.0k
                        }
2143
15.8k
                        break;
2144
442k
                    case '-':
2145
442k
                        is_negative = true;
2146
442k
                        buffer.push_back(*p);
2147
442k
                        state = numeric_check_state::minus;
2148
442k
                        break;
2149
82.3k
                    case '0':
2150
                        //++precision;
2151
82.3k
                        buffer.push_back(*p);
2152
82.3k
                        state = numeric_check_state::zero;
2153
82.3k
                        break;
2154
180k
                    case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2155
                        //++precision;
2156
180k
                        buffer.push_back(*p);
2157
180k
                        state = numeric_check_state::integer;
2158
180k
                        break;
2159
2.71M
                    default:
2160
2.71M
                        state = numeric_check_state::not_a_number;
2161
2.71M
                        break;
2162
3.79M
                    }
2163
3.79M
                    break;
2164
3.79M
                }
2165
3.79M
                case numeric_check_state::zero:
2166
49.1k
                {
2167
49.1k
                    switch (*p)
2168
49.1k
                    {
2169
35.3k
                        case '.':
2170
35.3k
                        {
2171
35.3k
                            buffer.push_back('.');
2172
35.3k
                            state = numeric_check_state::fraction1;
2173
35.3k
                        }
2174
35.3k
                        break;
2175
3.29k
                    case 'e':case 'E':
2176
3.29k
                        buffer.push_back(*p);
2177
3.29k
                        state = numeric_check_state::exp1;
2178
3.29k
                        break;
2179
10.5k
                    default:
2180
10.5k
                        state = numeric_check_state::not_a_number;
2181
10.5k
                        break;
2182
49.1k
                    }
2183
49.1k
                    break;
2184
49.1k
                }
2185
9.34M
                case numeric_check_state::integer:
2186
9.34M
                {
2187
9.34M
                    switch (*p)
2188
9.34M
                    {
2189
9.31M
                    case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2190
                        //++precision;
2191
9.31M
                        buffer.push_back(*p);
2192
9.31M
                        break;
2193
10.6k
                    case '.':
2194
10.6k
                        buffer.push_back('.');
2195
10.6k
                        state = numeric_check_state::fraction1;
2196
10.6k
                        break;
2197
11.7k
                    case 'e':case 'E':
2198
11.7k
                        buffer.push_back(*p);
2199
11.7k
                        state = numeric_check_state::exp1;
2200
11.7k
                        break;
2201
6.01k
                    default:
2202
6.01k
                        state = numeric_check_state::not_a_number;
2203
6.01k
                        break;
2204
9.34M
                    }
2205
9.34M
                    break;
2206
9.34M
                }
2207
9.34M
                case numeric_check_state::minus:
2208
411k
                {
2209
411k
                    switch (*p)
2210
411k
                    {
2211
382k
                    case '0':
2212
                        //++precision;
2213
382k
                        buffer.push_back(*p);
2214
382k
                        state = numeric_check_state::zero;
2215
382k
                        break;
2216
20.8k
                    case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2217
                        //++precision;
2218
20.8k
                        buffer.push_back(*p);
2219
20.8k
                        state = numeric_check_state::integer;
2220
20.8k
                        break;
2221
7.71k
                    default:
2222
7.71k
                        state = numeric_check_state::not_a_number;
2223
7.71k
                        break;
2224
411k
                    }
2225
411k
                    break;
2226
411k
                }
2227
411k
                case numeric_check_state::fraction1:
2228
43.7k
                {
2229
43.7k
                    switch (*p)
2230
43.7k
                    {
2231
42.2k
                    case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2232
                        //++precision;
2233
                        //++decimal_places;
2234
42.2k
                        buffer.push_back(*p);
2235
42.2k
                        state = numeric_check_state::fraction;
2236
42.2k
                        break;
2237
1.53k
                    default:
2238
1.53k
                        state = numeric_check_state::not_a_number;
2239
1.53k
                        break;
2240
43.7k
                    }
2241
43.7k
                    break;
2242
43.7k
                }
2243
62.7k
                case numeric_check_state::fraction:
2244
62.7k
                {
2245
62.7k
                    switch (*p)
2246
62.7k
                    {
2247
60.8k
                    case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2248
                        //++precision;
2249
                        //++decimal_places;
2250
60.8k
                        buffer.push_back(*p);
2251
60.8k
                        break;
2252
1.00k
                    case 'e':case 'E':
2253
1.00k
                        buffer.push_back(*p);
2254
1.00k
                        state = numeric_check_state::exp1;
2255
1.00k
                        break;
2256
880
                    default:
2257
880
                        state = numeric_check_state::not_a_number;
2258
880
                        break;
2259
62.7k
                    }
2260
62.7k
                    break;
2261
62.7k
                }
2262
62.7k
                case numeric_check_state::exp1:
2263
13.4k
                {
2264
13.4k
                    switch (*p)
2265
13.4k
                    {
2266
2.05k
                    case '-':
2267
2.05k
                        buffer.push_back(*p);
2268
2.05k
                        break;
2269
511
                    case '+':
2270
511
                        break;
2271
10.4k
                    case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2272
10.4k
                        state = numeric_check_state::exp;
2273
10.4k
                        buffer.push_back(*p);
2274
10.4k
                        break;
2275
440
                    default:
2276
440
                        state = numeric_check_state::not_a_number;
2277
440
                        break;
2278
13.4k
                    }
2279
13.4k
                    break;
2280
13.4k
                }
2281
46.4k
                case numeric_check_state::exp:
2282
46.4k
                {
2283
46.4k
                    switch (*p)
2284
46.4k
                    {
2285
43.3k
                    case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
2286
43.3k
                        buffer.push_back(*p);
2287
43.3k
                        break;
2288
3.11k
                    default:
2289
3.11k
                        state = numeric_check_state::not_a_number;
2290
3.11k
                        break;
2291
46.4k
                    }
2292
46.4k
                    break;
2293
46.4k
                }
2294
987k
                default:
2295
987k
                    break;
2296
14.7M
            }
2297
14.7M
        }
2298
2299
11.4M
        switch (state)
2300
11.4M
        {
2301
156k
            case numeric_check_state::null:
2302
156k
                visitor.null_value(semantic_tag::none, *this, ec);
2303
156k
                more_ = !cursor_mode_;
2304
156k
                break;
2305
167k
            case numeric_check_state::boolean_true:
2306
167k
                visitor.bool_value(true, semantic_tag::none, *this, ec);
2307
167k
                more_ = !cursor_mode_;
2308
167k
                break;
2309
3.86k
            case numeric_check_state::boolean_false:
2310
3.86k
                visitor.bool_value(false, semantic_tag::none, *this, ec);
2311
3.86k
                more_ = !cursor_mode_;
2312
3.86k
                break;
2313
415k
            case numeric_check_state::zero:
2314
589k
            case numeric_check_state::integer:
2315
589k
            {
2316
589k
                if (is_negative)
2317
390k
                {
2318
390k
                    int64_t val{ 0 };
2319
390k
                    auto result = jsoncons::dec_to_integer(buffer_.data(), buffer_.length(), val);
2320
390k
                    if (result)
2321
388k
                    {
2322
388k
                        visitor.int64_value(val, semantic_tag::none, *this, ec);
2323
388k
                        more_ = !cursor_mode_;
2324
388k
                    }
2325
1.72k
                    else // Must be overflow
2326
1.72k
                    {
2327
1.72k
                        visitor.string_value(buffer_, semantic_tag::bigint, *this, ec);
2328
1.72k
                        more_ = !cursor_mode_;
2329
1.72k
                    }
2330
390k
                }
2331
198k
                else
2332
198k
                {
2333
198k
                    uint64_t val{ 0 };
2334
198k
                    auto result = jsoncons::dec_to_integer(buffer_.data(), buffer_.length(), val);
2335
198k
                    if (result)
2336
196k
                    {
2337
196k
                        visitor.uint64_value(val, semantic_tag::none, *this, ec);
2338
196k
                        more_ = !cursor_mode_;
2339
196k
                    }
2340
2.15k
                    else if (result.ec == std::errc::result_out_of_range)
2341
2.15k
                    {
2342
2.15k
                        visitor.string_value(buffer_, semantic_tag::bigint, *this, ec);
2343
2.15k
                        more_ = !cursor_mode_;
2344
2.15k
                    }
2345
0
                    else
2346
0
                    {
2347
0
                        ec = csv_errc::invalid_number; 
2348
0
                        more_ = false;
2349
0
                        return;
2350
0
                    }
2351
198k
                }
2352
589k
                break;
2353
589k
            }
2354
589k
            case numeric_check_state::fraction:
2355
47.7k
            case numeric_check_state::exp:
2356
47.7k
            {
2357
47.7k
                if (lossless_number_)
2358
0
                {
2359
0
                    visitor.string_value(buffer_,semantic_tag::bigdec, *this, ec);
2360
0
                    more_ = !cursor_mode_;
2361
0
                }
2362
47.7k
                else
2363
47.7k
                {
2364
47.7k
                    double d{0};
2365
47.7k
                    auto result = jsoncons::decstr_to_double(buffer.data(), buffer.length(), d);
2366
47.7k
                    if (result.ec == std::errc::result_out_of_range)
2367
1.87k
                    {
2368
1.87k
                        d = buffer.front() == '-' ? -HUGE_VAL : HUGE_VAL;
2369
1.87k
                    }
2370
45.8k
                    else if (result.ec == std::errc::invalid_argument)
2371
4
                    {
2372
4
                        ec = csv_errc::invalid_number; 
2373
4
                        more_ = false;
2374
4
                        return;
2375
4
                    }
2376
47.7k
                    visitor.double_value(d, semantic_tag::none, *this, ec);
2377
47.7k
                    more_ = !cursor_mode_;
2378
47.7k
                }
2379
47.7k
                break;
2380
47.7k
            }
2381
10.5M
            default:
2382
10.5M
            {
2383
10.5M
                visitor.string_value(buffer_, semantic_tag::none, *this, ec);
2384
10.5M
                more_ = !cursor_mode_;
2385
10.5M
                break;
2386
47.7k
            }
2387
11.4M
        }
2388
11.4M
    } 
2389
2390
    void push_state(csv_parse_state state)
2391
5.08M
    {
2392
5.08M
        state_stack_.push_back(state);
2393
5.08M
    }
2394
2395
    csv_parse_state pop_state()
2396
5.08M
    {
2397
5.08M
        JSONCONS_ASSERT(!state_stack_.empty())
2398
5.08M
        csv_parse_state state = state_stack_.back();
2399
5.08M
        state_stack_.pop_back();
2400
5.08M
        return state;
2401
5.08M
    }
2402
};
2403
2404
using csv_parser = basic_csv_parser<char>;
2405
using wcsv_parser = basic_csv_parser<wchar_t>;
2406
2407
}}
2408
2409
#endif
2410