From b7e58f3d30d93dfc5e0cab5b8beb6c8a2523d52e Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis <karakasis@cscs.ch> Date: Thu, 21 Jan 2016 16:02:42 +0100 Subject: [PATCH] Replaced line buffer by an std::string. The line buffer is no more a pure character array but a standard string. For reading lines from the input stream we use the higher level std::getline() function which takes care of overflow issues. Side improvements: String comment prefixes are now supported. Other changes: added `-pedantic' to the compilation flags, to force strict C++11 compliance. --- main.cpp | 7 ------- makefile | 2 +- swcio.hpp | 49 +++++++++++++++---------------------------------- 3 files changed, 16 insertions(+), 42 deletions(-) diff --git a/main.cpp b/main.cpp index cc9501eb..ed8c3307 100644 --- a/main.cpp +++ b/main.cpp @@ -343,13 +343,6 @@ TEST(swc_parser, invalid_input) EXPECT_THROW(is >> cell, std::logic_error); } - { - // Check long lines - std::istringstream is(std::string(256, 'a') + "\n"); - cell_record cell; - EXPECT_THROW(is >> cell, std::runtime_error); - } - { // Check non-parsable values std::istringstream is("1a 1 14.566132 34.873772 7.857000 0.717830 -1\n"); diff --git a/makefile b/makefile index 3a75e5b6..736a149f 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ CC=clang++ -FLAGS=-std=c++11 -g +FLAGS=-std=c++11 -g -pedantic test.exe : main.cpp *.hpp makefile gtest.o $(CC) $(FLAGS) main.cpp -o test.exe gtest.o -pthread diff --git a/swcio.hpp b/swcio.hpp index 3d144fd9..b32d5e9e 100644 --- a/swcio.hpp +++ b/swcio.hpp @@ -12,6 +12,11 @@ namespace io { +static bool starts_with(const std::string &str, const std::string &prefix) +{ + return (str.find(prefix) == 0); +} + class cell_record { public: @@ -140,37 +145,22 @@ class swc_parser { public: swc_parser(const std::string &delim, - char comment_prefix, - std::size_t max_fields, - std::size_t max_line) + std::string comment_prefix) : delim_(delim) , comment_prefix_(comment_prefix) - , max_fields_(max_fields) - , max_line_(max_line) - { - init_linebuff(); - } + { } swc_parser() : delim_(" ") - , comment_prefix_('#') - , max_fields_(7) - , max_line_(256) - { - init_linebuff(); - } - - ~swc_parser() - { - delete[] linebuff_; - } + , comment_prefix_("#") + { } std::istream &parse_record(std::istream &is, cell_record &cell) { while (!is.eof() && !is.bad()) { // consume empty and comment lines first - is.getline(linebuff_, max_line_); - if (linebuff_[0] && linebuff_[0] != comment_prefix_) + std::getline(is, linebuff_); + if (!linebuff_.empty() && !starts_with(linebuff_, comment_prefix_)) break; } @@ -179,11 +169,11 @@ public: return is; if (is.eof() && - (linebuff_[0] == 0 || linebuff_[0] == comment_prefix_)) + (linebuff_.empty() || starts_with(linebuff_, comment_prefix_))) // last line is either empty or a comment; don't parse anything return is; - if (is.fail() && is.gcount() == max_line_ - 1) + if (is.fail()) throw std::runtime_error("too long line detected"); std::istringstream line(linebuff_); @@ -192,11 +182,6 @@ public: } private: - void init_linebuff() - { - linebuff_ = new char[max_line_]; - } - void check_parse_status(const std::istream &is) { if (is.fail()) @@ -205,13 +190,11 @@ private: throw std::logic_error("could not parse value"); } - // FIXME: need not to be a member function template<typename T> T parse_value_strict(std::istream &is) { T val; is >> val; - // std::cout << val << "\n"; check_parse_status(is); // everything's fine @@ -222,10 +205,8 @@ private: cell_record parse_record(std::istringstream &is); std::string delim_; - char comment_prefix_; - std::size_t max_fields_; - std::size_t max_line_; - char *linebuff_; + std::string comment_prefix_; + std::string linebuff_; }; -- GitLab