cgv
Loading...
Searching...
No Matches
csv_reader.cxx
1#include "csv_reader.h"
2#include <cgv/utils/file.h>
3
4namespace cgv {
5 namespace utils {
6
7const char* csv_reader_base::get_ws() const
8{
9 return ((flags & CSV_SPACE) != 0) ? " " : "";
10}
11const char* csv_reader_base::get_sep() const
12{
13 if ((flags & CSV_COMMA) != 0) {
14 if ((flags & CSV_TAB) != 0)
15 return ",\t";
16 else
17 return ",";
18 }
19 else
20 if ((flags & CSV_TAB) != 0)
21 return "\t";
22 return "";
23}
24bool csv_reader_base::has_heading() const
25{
26 return (flags & CSV_HEADING) != 0;
27}
28bool csv_reader_base::fail() const
29{
30 return failed;
31}
32bool csv_reader_base::find_column_index(const std::string& col_name, size_t& col_index) const
33{
34 auto iter = std::find(col_names.begin(), col_names.end(), col_name);
35 if (iter == col_names.end())
36 return false;
37 col_index = unsigned(iter - col_names.begin());
38 return true;
39}
40csv_reader_base::csv_reader_base(const std::string& file_name, CSV_Flags _flags)
41{
42 flags = _flags;
43 if (!cgv::utils::file::read(file_name, content, true)) {
44 last_error = "cannot read <" + file_name + ">";
45 failed = true;
46 return;
47 }
48 cgv::utils::split_to_lines(content, lines, true);
49 while (li < lines.size()) {
50 if (!lines[li].empty())
51 break;
52 ++li;
53 }
54 if (li >= lines.size()) {
55 last_error = "all lines in csv file are empty";
56 failed = true;
57 return;
58 }
59 if (has_heading()) {
60 std::vector<cgv::utils::token> tokens;
61 cgv::utils::split_to_tokens(lines[li], tokens, "", false, "", "", get_sep());
62 for (auto tok : tokens)
63 col_names.push_back(cgv::utils::to_string(tok));
64 ++li;
65 nr_cols = col_names.size();
66 }
67}
68
69bool csv_reader_base::parse_next_line(std::vector<cgv::utils::token>& tokens) const
70{
71 while (li < lines.size()) {
72 if (lines[li].empty()) {
73 ++li;
74 continue;
75 }
76 // split with seperator extration to support empty entries
77 std::vector<cgv::utils::token> sep_tokens;
78 cgv::utils::split_to_tokens(lines[li], sep_tokens, get_sep(), false, "'\"", "'\"", get_ws());
79 // filter out separators
80 tokens.clear();
81 bool last_was_empty = true;
82 for (auto tok : sep_tokens) {
83 if (tok == "," || tok == "\t") {
84 if (last_was_empty)
85 tokens.push_back(cgv::utils::token(tok.begin, tok.begin));
86 else
87 last_was_empty = true;
88 }
89 else {
90 tokens.push_back(tok);
91 last_was_empty = false;
92 }
93 }
94 if (nr_cols == 0)
95 nr_cols = tokens.size();
96 else
97 if (tokens.size() < col_names.size()) {
98 ++li;
99 continue;
100 }
101 ++li;
102 return true;
103 }
104 return false;
105}
106
107 }
108}
void split_to_tokens(const char *begin, const char *end, std::vector< token > &tokens, const std::string &separators, bool merge_separators, const std::string &open_parenthesis, const std::string &close_parenthesis, const std::string &whitespaces, unsigned int max_nr_tokens)
this function splits a text range into tokens.
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
void split_to_lines(const char *global_begin, const char *global_end, std::vector< line > &lines, bool truncate_trailing_spaces)
this function splits a text range at the newline characters into single lines.
CSV_Flags
different flags used by csv_reader classes
Definition csv_reader.h:17
this header is dependency free
Definition print.h:11
representation of a token in a text by two pointers begin and end, that point to the first character ...
Definition token.h:18