diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-26 12:28:10 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-26 12:28:10 -0300 |
| commit | b71faa6e95a0736f1ff171e006b171467b65db90 (patch) | |
| tree | 7580c3ab515e8f50726dc68dbc240995ff4a1a4c /src/csv.cpp | |
| download | cpp-b71faa6e95a0736f1ff171e006b171467b65db90.tar.gz | |
Initial importv0.1.0
Diffstat (limited to 'src/csv.cpp')
| -rw-r--r-- | src/csv.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/csv.cpp b/src/csv.cpp new file mode 100644 index 0000000..32b9591 --- /dev/null +++ b/src/csv.cpp @@ -0,0 +1,72 @@ +#include "csv.hpp" + +#include <cstddef> + +namespace cepis::detail { + +std::vector<std::vector<std::string>> parse_csv(std::string_view text) { + if (text.compare(0, 3, "\xEF\xBB\xBF") == 0) { + text.remove_prefix(3); + } + + std::vector<std::vector<std::string>> rows; + std::vector<std::string> row; + std::string field; + bool in_quotes = false; + bool row_has_content = false; + + const auto end_row = [&] { + if (!row_has_content) { + field.clear(); + row.clear(); + return; + } + row.push_back(std::move(field)); + field.clear(); + rows.push_back(std::move(row)); + row.clear(); + row_has_content = false; + }; + + for (std::size_t i = 0; i < text.size(); ++i) { + const char c = text[i]; + + if (in_quotes) { + row_has_content = true; + if (c != '"') { + field.push_back(c); + } else if (i + 1 < text.size() && text[i + 1] == '"') { + field.push_back('"'); + ++i; + } else { + in_quotes = false; + } + continue; + } + + switch (c) { + case '"': + row_has_content = true; + in_quotes = true; + break; + case ',': + row_has_content = true; + row.push_back(std::move(field)); + field.clear(); + break; + case '\r': + break; + case '\n': + end_row(); + break; + default: + row_has_content = true; + field.push_back(c); + } + } + + end_row(); + return rows; +} + +} // namespace cepis::detail |