portingtools/src/csv.cpp

92 lines
2.5 KiB
C++
Raw Normal View History

2022-11-08 21:59:56 +01:00
#include "csv.hpp"
2022-11-09 22:02:26 +01:00
2022-11-08 21:59:56 +01:00
#include <istream>
#include <string>
#include <vector>
namespace csv {
2022-11-09 22:02:26 +01:00
enum class CSVState {
UnquotedField,
QuotedField,
QuotedQuote
};
// this function has been made in collaboration with
// StackOverflow https://stackoverflow.com/a/30338543
void readCSVRow(const std::string& row, std::vector<std::string>& fields) {
2022-11-08 21:59:56 +01:00
fields.push_back("");
2022-11-09 22:02:26 +01:00
CSVState state = CSVState::UnquotedField;
size_t i = 0; // index of the current field
for (char c : row) {
switch (state) {
case CSVState::UnquotedField:
switch (c) {
case ',': // end of field
fields.push_back("");
i++;
break;
case '"':
state = CSVState::QuotedField;
break;
default:
fields[i].push_back(c);
break;
}
break;
case CSVState::QuotedField:
switch (c) {
case '"':
state = CSVState::QuotedQuote;
break;
default:
fields[i].push_back(c);
break;
}
break;
case CSVState::QuotedQuote:
switch (c) {
case ',': // , after closing quote
fields.push_back("");
i++;
state = CSVState::UnquotedField;
break;
case '"': // "" -> "
fields[i].push_back('"');
state = CSVState::QuotedField;
break;
default: // end of quote
state = CSVState::UnquotedField;
break;
}
break;
}
}
2022-11-08 21:59:56 +01:00
}
2022-11-09 22:02:26 +01:00
bool CsvReader::operator>>(std::vector<std::string>& line) {
line.clear();
if (!m_stream) {
return false;
}
2022-11-08 21:59:56 +01:00
2022-11-09 22:02:26 +01:00
std::string row;
std::getline(m_stream, row);
2022-11-08 21:59:56 +01:00
2022-11-09 22:02:26 +01:00
readCSVRow(row, line);
return !!m_stream;
}
2022-11-08 21:59:56 +01:00
}