Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
163
libs/coding/csv_reader.cpp
Normal file
163
libs/coding/csv_reader.cpp
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#include "coding/csv_reader.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
namespace coding
|
||||
{
|
||||
CSVReader::CSVReader(std::unique_ptr<ReaderInterface> reader, bool hasHeader, char delimiter)
|
||||
: m_reader(std::move(reader))
|
||||
, m_hasHeader(hasHeader)
|
||||
, m_delimiter(delimiter)
|
||||
{
|
||||
if (!HasHeader())
|
||||
return;
|
||||
|
||||
auto const row = ReadRow();
|
||||
if (row)
|
||||
m_header = *row;
|
||||
}
|
||||
|
||||
CSVReader::CSVReader(std::string const & filename, bool hasHeader, char delimiter)
|
||||
: CSVReader(std::make_unique<DefaultReader>(filename), hasHeader, delimiter)
|
||||
{}
|
||||
|
||||
CSVReader::CSVReader(std::istream & stream, bool hasHeader, char delimiter)
|
||||
: CSVReader(std::make_unique<IstreamWrapper>(stream), hasHeader, delimiter)
|
||||
{}
|
||||
|
||||
CSVReader::CSVReader(Reader const & reader, bool hasHeader, char delimiter)
|
||||
: CSVReader(std::make_unique<ReaderWrapper>(reader), hasHeader, delimiter)
|
||||
{}
|
||||
|
||||
bool CSVReader::HasHeader() const
|
||||
{
|
||||
return m_hasHeader;
|
||||
}
|
||||
|
||||
char CSVReader::GetDelimiter() const
|
||||
{
|
||||
return m_delimiter;
|
||||
}
|
||||
|
||||
CSVReader::Row const & CSVReader::GetHeader() const
|
||||
{
|
||||
return m_header;
|
||||
}
|
||||
|
||||
CSVReader::Rows CSVReader::ReadAll()
|
||||
{
|
||||
Rows file;
|
||||
ForEachRow([&](auto const & row) { file.emplace_back(row); });
|
||||
return file;
|
||||
}
|
||||
|
||||
std::optional<CSVReader::Row> CSVReader::ReadRow()
|
||||
{
|
||||
auto const line = m_reader->ReadLine();
|
||||
if (!line)
|
||||
return {};
|
||||
|
||||
Row row;
|
||||
strings::ParseCSVRow(*line, m_delimiter, row);
|
||||
++m_currentLine;
|
||||
return row;
|
||||
}
|
||||
|
||||
size_t CSVReader::GetCurrentLineNumber() const
|
||||
{
|
||||
return m_currentLine;
|
||||
}
|
||||
|
||||
CSVReader::IstreamWrapper::IstreamWrapper(std::istream & stream) : m_stream(stream) {}
|
||||
|
||||
std::optional<std::string> CSVReader::IstreamWrapper::ReadLine()
|
||||
{
|
||||
std::string line;
|
||||
return std::getline(m_stream, line) ? line : std::optional<std::string>();
|
||||
}
|
||||
|
||||
CSVReader::ReaderWrapper::ReaderWrapper(Reader const & reader) : m_reader(reader) {}
|
||||
|
||||
std::optional<std::string> CSVReader::ReaderWrapper::ReadLine()
|
||||
{
|
||||
std::vector<char> line;
|
||||
char ch = '\0';
|
||||
while (m_pos < m_reader.Size() && ch != '\n')
|
||||
{
|
||||
m_reader.Read(m_pos, &ch, sizeof(ch));
|
||||
line.emplace_back(ch);
|
||||
++m_pos;
|
||||
}
|
||||
|
||||
if (line.empty())
|
||||
return {};
|
||||
|
||||
auto end = std::end(line);
|
||||
if (line.back() == '\n')
|
||||
--end;
|
||||
|
||||
return std::string(std::begin(line), end);
|
||||
}
|
||||
|
||||
CSVReader::DefaultReader::DefaultReader(std::string const & filename) : m_stream(filename)
|
||||
{
|
||||
if (!m_stream)
|
||||
LOG(LERROR, ("Can't open file ", filename));
|
||||
|
||||
m_stream.exceptions(std::ios::badbit);
|
||||
}
|
||||
|
||||
std::optional<std::string> CSVReader::DefaultReader::ReadLine()
|
||||
{
|
||||
return IstreamWrapper(m_stream).ReadLine();
|
||||
}
|
||||
|
||||
CSVRunner::Iterator::Iterator(CSVReader & reader, bool isEnd) : m_reader(reader)
|
||||
{
|
||||
if (!isEnd)
|
||||
m_current = m_reader.ReadRow();
|
||||
}
|
||||
|
||||
CSVRunner::Iterator::Iterator(Iterator const & other) : m_reader(other.m_reader), m_current(other.m_current) {}
|
||||
|
||||
CSVRunner::Iterator & CSVRunner::Iterator::operator++()
|
||||
{
|
||||
m_current = m_reader.ReadRow();
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSVRunner::Iterator CSVRunner::Iterator::operator++(int)
|
||||
{
|
||||
Iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool CSVRunner::Iterator::operator==(Iterator const & other) const
|
||||
{
|
||||
return &m_reader == &other.m_reader && static_cast<bool>(m_current) == static_cast<bool>(other.m_current);
|
||||
}
|
||||
|
||||
bool CSVRunner::Iterator::operator!=(Iterator const & other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
CSVReader::Row & CSVRunner::Iterator::operator*()
|
||||
{
|
||||
return *m_current;
|
||||
}
|
||||
|
||||
CSVRunner::CSVRunner(CSVReader && reader) : m_reader(std::move(reader)) {}
|
||||
|
||||
CSVRunner::Iterator CSVRunner::begin()
|
||||
{
|
||||
return Iterator(m_reader);
|
||||
}
|
||||
|
||||
CSVRunner::Iterator CSVRunner::end()
|
||||
{
|
||||
return Iterator(m_reader, true /* isEnd */);
|
||||
}
|
||||
} // namespace coding
|
||||
Loading…
Add table
Add a link
Reference in a new issue