Vince's CSV Parser
Loading...
Searching...
No Matches
csv_format.hpp
Go to the documentation of this file.
1
5#pragma once
6#include <iterator>
7#include <stdexcept>
8#include <string>
9#include <vector>
10
11#include "common.hpp"
12#include "csv_exceptions.hpp"
13
14namespace csv {
15 class CSVFormat;
16 namespace internals {
18 char resolved_delimiter(const CSVFormat& format) noexcept;
19 template<typename RowSink, typename ParsePolicy, typename FieldPolicy, typename RowPolicy>
21 namespace parser {
22 class CSVParserDriverBase;
23 }
24 }
25
26 class CSVReader;
27
30 THROW = -1,
31 IGNORE_ROW = 0,
32 KEEP = 1,
33 KEEP_NON_EMPTY = 2
34 };
35
37 enum class ColumnNamePolicy {
38 EXACT = 0,
40 };
41
44 char delim;
45 int header_row;
46 size_t n_cols;
47 };
48
52 class CSVFormat {
53 public:
55 CSVFormat() = default;
56
65#if CSV_EXCEPTIONS_ENABLED
66 CSVFormat& delimiter(char delim);
67#endif
68
75#if CSV_EXCEPTIONS_ENABLED
76 CSVFormat& delimiter(const std::vector<char> & delim);
77#endif
78
83#if CSV_EXCEPTIONS_ENABLED
84 CSVFormat& trim(const std::vector<char> & ws);
85#endif
86
91#if CSV_EXCEPTIONS_ENABLED
92 CSVFormat& quote(char quote);
93#else
94 // Prevent a char from silently selecting quote(bool).
95 CSVFormat& quote(char) = delete;
96#endif
97
99 bool try_delimiter(char delim, CSVError& error);
100 bool try_delimiter(const std::vector<char>& delims, CSVError& error);
101 bool try_trim(const std::vector<char>& whitespace, CSVError& error);
102 bool try_quote(char quote, CSVError& error);
103
105 bool try_chunk_size(size_t size, CSVError& error);
106
108 bool try_get_delim(char& out, CSVError& error) const;
109
114 CSVFormat& column_names(const std::vector<std::string>& names);
115
121 CSVFormat& header_row(int row);
122
129 this->header_row(-1);
130 return *this;
131 }
132
134 CSVFormat& quote(bool use_quote) {
135 this->no_quote = !use_quote;
136 return *this;
137 }
138
140 CONSTEXPR_14 CSVFormat& variable_columns(VariableColumnPolicy policy = VariableColumnPolicy::IGNORE_ROW) {
141 this->variable_column_policy = policy;
142 return *this;
143 }
144
146 CONSTEXPR_14 CSVFormat& variable_columns(bool policy) {
147 this->variable_column_policy = (VariableColumnPolicy)policy;
148 return *this;
149 }
150
158 this->_column_name_policy = policy;
159 return *this;
160 }
161
171#if CSV_EXCEPTIONS_ENABLED
172 CSVFormat& chunk_size(size_t size);
173#endif
174
184 CONSTEXPR_14 CSVFormat& threading(bool enabled = true) {
185 this->_threading = enabled;
186 return *this;
187 }
188
193 CONSTEXPR_14 CSVFormat& speculative_parallel_threads(size_t n_threads) {
194 this->_speculative_parallel_threads = n_threads;
195 return *this;
196 }
197
199 CONSTEXPR_14 CSVFormat& speculative_parallel_min_bytes(size_t bytes) {
200 this->_speculative_parallel_min_bytes = bytes;
201 return *this;
202 }
203
209 CONSTEXPR_14 CSVFormat& eager_field_classification(bool enabled = true) {
210 this->_eager_field_classification = enabled;
211 return *this;
212 }
213
214#ifndef DOXYGEN_SHOULD_SKIP_THIS
215#if CSV_EXCEPTIONS_ENABLED
216 char get_delim() const;
217#endif
218
219 CONSTEXPR bool is_quoting_enabled() const { return !this->no_quote; }
220 CONSTEXPR char get_quote_char() const { return this->quote_char; }
221 CONSTEXPR int get_header() const { return this->header; }
222 std::vector<char> get_possible_delims() const { return this->possible_delimiters; }
223 std::vector<char> get_trim_chars() const { return this->trim_chars; }
224 const std::vector<std::string>& get_col_names() const { return this->col_names; }
225 CONSTEXPR VariableColumnPolicy get_variable_column_policy() const { return this->variable_column_policy; }
226 CONSTEXPR ColumnNamePolicy get_column_name_policy() const { return this->_column_name_policy; }
227 CONSTEXPR size_t get_chunk_size() const { return this->_chunk_size; }
228 CONSTEXPR bool is_threading_enabled() const {
229#if CSV_ENABLE_THREADS
230 return this->_threading;
231#else
232 return false;
233#endif
234 }
235 CONSTEXPR size_t get_speculative_parallel_threads() const { return this->_speculative_parallel_threads; }
236 CONSTEXPR size_t get_speculative_parallel_min_bytes() const { return this->_speculative_parallel_min_bytes; }
237 CONSTEXPR bool is_eager_field_classification_enabled() const { return this->_eager_field_classification; }
238 CONSTEXPR bool should_use_speculative_parallel(size_t source_size, size_t n_threads) const {
239#if CSV_ENABLE_THREADS
240 return this->_threading
241 && n_threads > 1
242 && source_size >= this->_speculative_parallel_min_bytes;
243#else
244 (void)source_size;
245 (void)n_threads;
246 return false;
247#endif
248 }
249#endif
250
252 static CSVFormat guess_csv();
253
254 bool guess_delim() const {
255 return this->possible_delimiters.size() > 1;
256 }
257
258 friend CSVReader;
259 template<typename RowSink, typename ParsePolicy, typename FieldPolicy, typename RowPolicy>
260 friend class internals::CSVParserCore;
261 friend internals::parser::CSVParserDriverBase;
262 friend char internals::resolved_delimiter(const CSVFormat& format) noexcept;
263
264 private:
265 static bool validate_characters(
266 const std::vector<char>& delims, const std::vector<char>& whitespace,
267 char quote, CSVError& error);
268
270 std::vector<char> possible_delimiters = { ',' };
271
273 std::vector<char> trim_chars = {};
274
276 int header = 0;
277
279 bool header_explicitly_set_ = false;
280
282 bool no_quote = false;
283
285 char quote_char = '"';
286
288 std::vector<std::string> col_names = {};
289
291 bool col_names_explicitly_set_ = false;
292
294 VariableColumnPolicy variable_column_policy = VariableColumnPolicy::IGNORE_ROW;
295
297 ColumnNamePolicy _column_name_policy = ColumnNamePolicy::EXACT;
298
300 size_t _chunk_size = internals::CSV_CHUNK_SIZE_DEFAULT;
301
303 bool _threading = true;
304
306 size_t _speculative_parallel_threads = 0;
307
309 size_t _speculative_parallel_min_bytes = internals::CSV_SPECULATIVE_PARALLEL_MIN_BYTES;
310
312 bool _eager_field_classification = false;
313 };
314}
Stores information about how to parse a CSV file.
CSVFormat & column_names(const std::vector< std::string > &names)
Sets the column names.
CONSTEXPR_14 CSVFormat & variable_columns(VariableColumnPolicy policy=VariableColumnPolicy::IGNORE_ROW)
Tells the parser how to handle columns of a different length than the others.
CONSTEXPR_14 CSVFormat & column_names_policy(ColumnNamePolicy policy)
Sets the column name lookup policy.
CSVFormat()=default
Settings for parsing a RFC 4180 CSV file.
CSVFormat & chunk_size(size_t size)
Sets the chunk size used when reading the CSV.
CONSTEXPR_14 CSVFormat & eager_field_classification(bool enabled=true)
Enable parser-time scalar classification for typed consumers.
static CSVFormat guess_csv()
CSVFormat preset for delimiter inference with header/n_cols inference enabled.
CSVFormat & trim(const std::vector< char > &ws)
Sets the whitespace characters to be trimmed.
CSVFormat & delimiter(char delim)
Sets the delimiter of the CSV file.
CONSTEXPR_14 CSVFormat & speculative_parallel_threads(size_t n_threads)
Set the worker count used by speculative parallel parsing.
CSVFormat & quote(bool use_quote)
Turn quoting on or off.
CONSTEXPR_14 CSVFormat & threading(bool enabled=true)
Enable or disable parser threading at runtime.
CONSTEXPR_14 CSVFormat & speculative_parallel_min_bytes(size_t bytes)
Set the minimum source size required for speculative parallel parsing.
CONSTEXPR_14 CSVFormat & variable_columns(bool policy)
Tells the parser how to handle columns of a different length than the others.
bool try_get_delim(char &out, CSVError &error) const
Retrieve a resolved delimiter; unresolved candidate lists report InvalidFormat.
CSVFormat & no_header()
Tells the parser that this CSV has no header row.
bool try_delimiter(char delim, CSVError &error)
Set parsing characters, returning false and preserving the format on invalid input.
CSVFormat & header_row(int row)
Sets the header row.
CSVFormat & quote(char quote)
Sets the quote character.
bool try_chunk_size(size_t size, CSVError &error)
Set a valid chunk size, preserving the previous value on failure.
Main class for parsing CSVs from files and in-memory sources.
A standalone header file containing shared code.
#define CONSTEXPR
Expands to constexpr in decent compilers and inline otherwise.
Definition common.hpp:259
Shared exception message templates and throw helpers.
char resolved_delimiter(const CSVFormat &format) noexcept
Read a delimiter after configuration has been validated and resolved to one candidate.
The all encompassing namespace.
ColumnNamePolicy
Determines how column name lookups are performed.
@ CASE_INSENSITIVE
Case-insensitive match.
@ EXACT
Case-sensitive match (default)
VariableColumnPolicy
Determines how to handle rows that are shorter or longer than the majority.
std::vector< std::string > get_col_names(csv::string_view filename, const CSVFormat &format=CSVFormat::guess_csv())
Get the column names of a CSV file using just the first 500KB.
A diagnostic whose text remains valid for the lifetime of the error.
Definition csv_error.hpp:94
Stores the inferred format of a CSV file.