1#include "Conditions/GeneralCSVLoader.h"
9#include "Framework/Exception/Exception.h"
10#include "boost/tokenizer.hpp"
15 bool ignore_case)
const {
18 if (ignore_case && !strcasecmp(
colNames_[i].c_str(), colname.c_str()))
23 EXCEPTION_RAISE(
"CSVNoSuchColumn",
24 "No such column '" + colname +
"' reading CSV");
30 bool ignore_case)
const {
31 return atoi(
get(colname, ignore_case).c_str());
37 if (line.empty())
return false;
39 if (line[0] ==
'#')
continue;
41 std::vector<std::string> line_split;
43 line.erase(std::find_if(line.rbegin(), line.rend(),
44 [](
unsigned char c) { return !std::isspace(c); })
47 boost::tokenizer<boost::escaped_list_separator<char>> tok(line);
48 for (
auto chunk : tok) {
49 line_split.push_back(chunk);
55 if (line_split.size() ==
colNames_.size()) {
58 EXCEPTION_RAISE(
"CSVLineMismatch",
59 "Reading CSV found line with " +
60 std::to_string(line_split.size()) +
" in CSV with " +
61 std::to_string(
colNames_.size()) +
" columns");
69 const std::string lineseparators)
70 : source_{source}, linesep_{lineseparators}, rowBegin_{0}, rowEnd_{0} {
77 if (rowEnd_ == std::string::npos) {
89 rowEnd_ = std::string::npos;
95 : source_{0}, ownStream_{true} {
96 std::string expanded_fname = filename;
99 if (wordexp(filename.c_str(), &p, 0)) {
100 EXCEPTION_RAISE(
"StreamCSVFileNotFound",
101 "Error expanding '" + filename +
"'");
105 EXCEPTION_RAISE(
"StreamCSVFileNotFound",
106 "No file matching '" + filename +
"' found");
109 if (p.we_wordc != 1) {
110 int nfound = p.we_wordc;
112 EXCEPTION_RAISE(
"StreamCSVFileNotFound",
113 "Multiple files (" + std::to_string(nfound) +
114 ") matching '" + filename +
"' found");
117 expanded_fname = p.we_wordv[0];
120 source_ =
new std::ifstream(expanded_fname);
122 EXCEPTION_RAISE(
"StreamCSVFileNotFound",
123 "Unable to open '" + expanded_fname +
"'");
128 : source_{&stream}, ownStream_{false} {}
143 }
while (
line_.empty());
bool nextRow()
Advance to next row if possible.
const std::string & get(const std::string &colname, bool ignore_case=true) const
Get the value for the given column in the current row.
int getInteger(const std::string &colname, bool ignore_case=true) const
Get the value for the given column in the current row as an integer.
virtual std::string getNextLine()=0
Get the next line, returning an empty string when there is no further data.
std::vector< std::string > rowData_
The row data.
std::vector< std::string > colNames_
The column names.
virtual ~StreamCSVLoader()
Clean-up the stream if we own it.
virtual std::string getNextLine()
Get the next line, returning an empty string when there is no further data.
bool ownStream_
Own stream?
StreamCSVLoader(const std::string &filename)
Constructor a loader from the provided file name.
std::string line_
Line buffer.
std::istream * source_
The stream.
const std::string & source_
The original string.
std::string::size_type rowBegin_
The current start and end pointers.
StringCSVLoader(const std::string &source, const std::string lineseparators="\n")
Constructor.
const std::string linesep_
The separators.
virtual std::string getNextLine()
Get the next line, returning an empty string when there is no further data.