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