diff --git a/include/ss/parser.hpp b/include/ss/parser.hpp index 19ca4cd..11ee763 100644 --- a/include/ss/parser.hpp +++ b/include/ss/parser.hpp @@ -89,7 +89,6 @@ public: return valid() ? reader_.line_number_ - 1 : 0; } - // TODO append file_name and line number to exception template no_void_validator_tup_t get_next() { std::optional error; @@ -209,12 +208,15 @@ public: using value = std::conditional_t>; - iterator() : parser_{nullptr} { + iterator() : parser_{nullptr}, value_{} { } - iterator(parser* parser) : parser_{parser} { + iterator(parser* parser) : parser_{parser}, value_{} { } + iterator(const iterator& other) = default; + iterator(iterator&& other) = default; + value& operator*() { return value_; } @@ -224,7 +226,7 @@ public: } iterator& operator++() { - if (parser_->eof()) { + if (!parser_ || parser_->eof()) { parser_ = nullptr; } else { if constexpr (get_object) { @@ -253,8 +255,8 @@ public: } private: - value value_; parser* parser_; + value value_; }; iterable(parser* parser) : parser_{parser} { @@ -465,7 +467,14 @@ private: std::string raw_header_copy = raw_header_; splitter.split(raw_header_copy.data(), reader_.delim_); for (const auto& [begin, end] : splitter.split_data_) { - header_.emplace_back(begin, end); + std::string field{begin, end}; + if (std::find(header_.begin(), header_.end(), field) != + header_.end()) { + handle_error_invalid_header(field); + header_.clear(); + return; + } + header_.push_back(std::move(field)); } } @@ -597,6 +606,19 @@ private: } } + void handle_error_invalid_header(const std::string& field) { + constexpr static auto error_msg = "header contains duplicates: "; + + if constexpr (string_error) { + error_.clear(); + error_.append(error_msg).append(error_msg); + } else if constexpr (throw_on_error) { + throw ss::exception{error_msg + field}; + } else { + error_ = true; + } + } + void decorate_rethrow(const ss::exception& e) const { static_assert(throw_on_error, "throw_on_error needs to be enabled to use this method"); diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 1e3bc23..40b5969 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -1286,6 +1286,9 @@ void test_invalid_fields(const std::vector& lines, TEST_CASE("parser test invalid header fields usage") { test_invalid_fields({"Int,String,Double", "1,hi,2.34"}, {"Int", "String", "Double"}); + + test_invalid_fields({"Int,Int,Int", "1,2,3"}, + {"Int", "Int", "Int"}); } template