cgv
Loading...
Searching...
No Matches
csv_reader.h
1#pragma once
2
3#include <string>
4#include <vector>
5#include <functional>
8#include <cgv/math/fvec.h>
9
10#include <cgv/utils/lib_begin.h>
11
12namespace cgv {
13 namespace utils {
14
17{
18 CSV_HEADING = 1, // whether file starts with heading line
19 CSV_COMMA = 2, // whether comma is a separator
20 CSV_TAB = 4, // whether tab is a separator
21 CSV_SPACE = 8, // whether space is a separating white space (always merged)
22 CSV_QUOTES = 16, // whether quotes are used to combine text to single fields
23 CSV_DEFAULT = CSV_HEADING | CSV_COMMA| CSV_TAB | CSV_QUOTES
24};
25
27class CGV_API csv_reader_base
28{
29protected:
30 mutable std::string last_error;
31 mutable bool failed = false;
32 mutable size_t li = 0;
33 mutable size_t nr_cols = 0;
34
35 CSV_Flags flags;
36 std::string content;
37 std::vector<std::string> col_names;
38 std::vector<cgv::utils::line> lines;
39 const char* get_ws() const;
40 const char* get_sep() const;
41 bool has_heading() const;
42 bool find_column_index(const std::string& col_name, size_t& col_index) const;
43 csv_reader_base(const std::string& file_name, CSV_Flags _flags = CSV_DEFAULT);
44 bool parse_next_line(std::vector<cgv::utils::token>& tokens) const;
45public:
46 bool fail() const;
47};
48
51{
52public:
54 csv_matrix_reader(const std::string& file_name, CSV_Flags _flags = CSV_SPACE) : csv_reader_base(file_name, _flags) {}
56 template <typename T>
57 bool parse_matrix(std::vector<std::vector<T>>& matrix, T init = T(0)) {
58 std::vector<cgv::utils::token> tokens;
59 while (parse_next_line(tokens)) {
60 std::vector<T> vec(tokens.size(), init);
61 for (size_t i = 0; i < tokens.size(); ++i)
63 matrix.emplace_back(vec);
64 }
65 return true;
66 }
68 template <typename T, unsigned N>
69 bool parse_matrix(std::vector<cgv::math::fvec<T,N>>& matrix, T init = T(0)) {
70 std::vector<cgv::utils::token> tokens;
71 while (parse_next_line(tokens)) {
72 cgv::math::fvec<T,N> vec(init);
73 for (size_t i = 0; i < tokens.size() && i < N; ++i)
74 cgv::utils::from_string(vec[int(i)], cgv::utils::to_string(tokens[i]));
75 matrix.emplace_back(vec);
76 }
77 return true;
78 }
79};
80
81
83
112template <typename T>
114{
115protected:
116 typedef std::pair<size_t, std::function<bool (const std::string&, T&)>> setter;
117 std::vector<setter> setters;
118public:
120 csv_reader(const std::string& file_name, CSV_Flags _flags = CSV_DEFAULT) : csv_reader_base(file_name, _flags) {}
122 bool add_entry(size_t col_index, std::function<bool(const std::string&, T&)> s) {
123 setters.push_back({ col_index, s });
124 return true;
125 }
127 template <typename M>
128 bool add_entry(M T::*ptr, size_t col_index) {
129 add_entry(col_index, [ptr](const std::string& tok, T& obj) -> bool {
130 return cgv::utils::from_string(obj.*ptr, tok);
131 });
132 return true;
133 }
135 template <typename M>
136 bool add_entry(M T::* ptr, const std::string& col_name) {
137 size_t col_index;
138 if (!find_column_index(col_name, col_index))
139 return false;
140 return add_entry(ptr, col_index);
141 }
143 bool add_entry(const std::string& col_name, std::function<bool(const std::string&, T&)> s) {
144 size_t col_index;
145 if (!find_column_index(col_name, col_index))
146 return false;
147 return add_entry(col_index, s);
148 }
150 bool parse(std::vector<T>& data)
151 {
152 std::vector<cgv::utils::token> tokens;
153 while (parse_next_line(tokens)) {
154 T object;
155 for (auto s : setters) {
156 if (s.first >= tokens.size()) {
157 last_error = "column index <" + cgv::utils::to_string(s.first) +
158 "> out of range [0," +cgv::utils::to_string(tokens.size()) + "[";
159 return false;
160 }
161 if (!s.second(cgv::utils::to_string(tokens[s.first]), object)) {
162 last_error = "could not parse <" + cgv::utils::to_string(tokens[s.first]) + ">";
163 return false;
164 }
165 }
166 data.emplace_back(object);
167 }
168 return true;
169 }
170};
171
172 }
173}
174
175#include <cgv/config/lib_end.h>
More advanced text processing for splitting text into lines or tokens.
A vector with zero based index.
Definition fvec.h:29
csv reader for parsing matrices of a homogenous number type
Definition csv_reader.h:51
bool parse_matrix(std::vector< cgv::math::fvec< T, N > > &matrix, T init=T(0))
parse matrix into nested vector struct and initialize entries to given init value (only rectangular m...
Definition csv_reader.h:69
csv_matrix_reader(const std::string &file_name, CSV_Flags _flags=CSV_SPACE)
construct from csv file with flags defaulting to use of space as separator
Definition csv_reader.h:54
bool parse_matrix(std::vector< std::vector< T > > &matrix, T init=T(0))
parse matrix into nested vector struct and initialize entries to given init value (only rectangular m...
Definition csv_reader.h:57
base class of csv parser responsible for splitting file into lines and tokens
Definition csv_reader.h:28
csv reader for parsing csv files to a specific type T that can store one object with different entrie...
Definition csv_reader.h:114
bool add_entry(const std::string &col_name, std::function< bool(const std::string &, T &)> s)
add new entry based on heading of column with custom setter function
Definition csv_reader.h:143
bool parse(std::vector< T > &data)
parse csv file content into given data vector extracting added entries into members of objects of typ...
Definition csv_reader.h:150
csv_reader(const std::string &file_name, CSV_Flags _flags=CSV_DEFAULT)
construct from csv file with default flags (comma or tab as separator plus heading line) and extract ...
Definition csv_reader.h:120
bool add_entry(M T::*ptr, const std::string &col_name)
add new entry based on heading of column (assumes construction with has_heading=true) with default se...
Definition csv_reader.h:136
bool add_entry(M T::*ptr, size_t col_index)
add new entry based on column index (0, 1, ...) with default setter for member type
Definition csv_reader.h:128
bool add_entry(size_t col_index, std::function< bool(const std::string &, T &)> s)
add new entry based on column index (0, 1, ...) with custom setter function
Definition csv_reader.h:122
Helper functions to convert numeric types into strings using std streams.
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
CSV_Flags
different flags used by csv_reader classes
Definition csv_reader.h:17
bool from_string(std::string &v, const std::string &s)
specialization to extract string value from string
this header is dependency free
Definition print.h:11