diff --git a/include/updater/csv_file_parser.hpp b/include/updater/csv_file_parser.hpp index 9f1d2b7b8..a94df690a 100644 --- a/include/updater/csv_file_parser.hpp +++ b/include/updater/csv_file_parser.hpp @@ -10,13 +10,10 @@ #include #include -#include -#include +#include #include #include -#include -#include #include namespace osrm @@ -35,7 +32,7 @@ namespace qi = boost::spirit::qi; // with the corresponding file index in the CSV filenames vector. template struct CSVFilesParser { - using Iterator = boost::spirit::line_pos_iterator; + using Iterator = boost::iostreams::mapped_file_source::iterator; using KeyRule = qi::rule; using ValueRule = qi::rule; @@ -95,11 +92,8 @@ template struct CSVFilesParser // Parse a single CSV file and return result as a vector auto ParseCSVFile(const std::string &filename, std::size_t file_id) const { - std::ifstream input_stream(filename, std::ios::binary); - input_stream.unsetf(std::ios::skipws); - - boost::spirit::istream_iterator sfirst(input_stream), slast; - Iterator first(sfirst), last(slast); + boost::iostreams::mapped_file_source mmap(filename); + auto first = mmap.begin(), last = mmap.end(); BOOST_ASSERT(file_id <= std::numeric_limits::max()); ValueRule value_source = @@ -111,8 +105,13 @@ template struct CSVFilesParser if (!ok || first != last) { - const auto message = - boost::format("CSV file %1% malformed on line %2%") % filename % first.position(); + auto begin_of_line = first - 1; + while (begin_of_line >= mmap.begin() && *begin_of_line != '\n') + --begin_of_line; + auto line_number = std::count(mmap.begin(), first, '\n') + 1; + const auto message = boost::format("CSV file %1% malformed on line %2%: %3%") % + filename % std::to_string(line_number) % + std::string(begin_of_line + 1, std::find(first, last, '\n')); throw util::exception(message.str() + SOURCE_REF); }