Add null data buffer error handler and unit test, resolve TODOs

This commit is contained in:
ado 2024-02-19 01:00:42 +01:00
parent 775b8c93e2
commit aaa22046a5
3 changed files with 76 additions and 35 deletions

View File

@ -52,12 +52,17 @@ public:
const std::string& delim = ss::default_delimiter) const std::string& delim = ss::default_delimiter)
: file_name_{"buffer line"}, : file_name_{"buffer line"},
reader_{csv_data_buffer, csv_data_size, delim} { reader_{csv_data_buffer, csv_data_size, delim} {
if (csv_data_buffer) {
read_line(); read_line();
if constexpr (ignore_header) { if constexpr (ignore_header) {
ignore_next(); ignore_next();
} else { } else {
raw_header_ = reader_.get_buffer(); raw_header_ = reader_.get_buffer();
} }
} else {
handle_error_null_buffer();
eof_ = true;
}
} }
parser(parser&& other) = default; parser(parser&& other) = default;
@ -524,6 +529,19 @@ private:
} }
} }
void handle_error_null_buffer() {
constexpr static auto error_msg = " received null data buffer";
if constexpr (string_error) {
error_.clear();
error_.append(file_name_).append(error_msg);
} else if constexpr (throw_on_error) {
throw ss::exception{file_name_ + error_msg};
} else {
error_ = true;
}
}
void handle_error_file_not_open() { void handle_error_file_not_open() {
constexpr static auto error_msg = " could not be opened"; constexpr static auto error_msg = " could not be opened";
@ -728,17 +746,11 @@ private:
size_t pos; size_t pos;
int c; int c;
// TODO remove check
if (lineptr == nullptr || buffer == nullptr || n == nullptr) {
return -1;
}
if (curr_char >= csv_data_size) { if (curr_char >= csv_data_size) {
return -1; return -1;
} }
c = buffer[curr_char++]; c = buffer[curr_char++];
// TODO maybe remove this too
if (*lineptr == nullptr) { if (*lineptr == nullptr) {
*lineptr = static_cast<char*>(malloc(128)); *lineptr = static_cast<char*>(malloc(128));
if (*lineptr == nullptr) { if (*lineptr == nullptr) {
@ -751,13 +763,11 @@ private:
while (curr_char <= csv_data_size) { while (curr_char <= csv_data_size) {
if (pos + 1 >= *n) { if (pos + 1 >= *n) {
size_t new_size = *n + (*n >> 2); size_t new_size = *n + (*n >> 2);
// TODO maybe remove this too
if (new_size < 128) { if (new_size < 128) {
new_size = 128; new_size = 128;
} }
char* new_ptr = static_cast<char*>( char* new_ptr = static_cast<char*>(
realloc(static_cast<void*>(*lineptr), new_size)); realloc(static_cast<void*>(*lineptr), new_size));
// TODO check for failed malloc in the callee
if (new_ptr == nullptr) { if (new_ptr == nullptr) {
return -1; return -1;
} }
@ -924,11 +934,11 @@ private:
} }
void realloc_concat(char*& first, size_t& first_size, void realloc_concat(char*& first, size_t& first_size,
const char* const second, size_t second_size) { size_t& buffer_size, const char* const second,
// TODO make buffer_size an argument size_t second_size) {
next_line_buffer_size_ = first_size + second_size + 3; buffer_size = first_size + second_size + 3;
auto new_first = static_cast<char*>( auto new_first = static_cast<char*>(
realloc(static_cast<void*>(first), next_line_buffer_size_)); realloc(static_cast<void*>(first), buffer_size));
if (!first) { if (!first) {
throw std::bad_alloc{}; throw std::bad_alloc{};
} }
@ -958,7 +968,8 @@ private:
++line_number_; ++line_number_;
size_t next_size = remove_eol(helper_buffer_, next_ssize); size_t next_size = remove_eol(helper_buffer_, next_ssize);
realloc_concat(buffer, size, helper_buffer_, next_size); realloc_concat(buffer, size, next_line_buffer_size_, helper_buffer_,
next_size);
return true; return true;
} }

37
ssp.hpp
View File

@ -2178,12 +2178,17 @@ public:
const std::string& delim = ss::default_delimiter) const std::string& delim = ss::default_delimiter)
: file_name_{"buffer line"}, : file_name_{"buffer line"},
reader_{csv_data_buffer, csv_data_size, delim} { reader_{csv_data_buffer, csv_data_size, delim} {
if (csv_data_buffer) {
read_line(); read_line();
if constexpr (ignore_header) { if constexpr (ignore_header) {
ignore_next(); ignore_next();
} else { } else {
raw_header_ = reader_.get_buffer(); raw_header_ = reader_.get_buffer();
} }
} else {
handle_error_null_buffer();
eof_ = true;
}
} }
parser(parser&& other) = default; parser(parser&& other) = default;
@ -2650,6 +2655,19 @@ private:
} }
} }
void handle_error_null_buffer() {
constexpr static auto error_msg = " received null data buffer";
if constexpr (string_error) {
error_.clear();
error_.append(file_name_).append(error_msg);
} else if constexpr (throw_on_error) {
throw ss::exception{file_name_ + error_msg};
} else {
error_ = true;
}
}
void handle_error_file_not_open() { void handle_error_file_not_open() {
constexpr static auto error_msg = " could not be opened"; constexpr static auto error_msg = " could not be opened";
@ -2854,17 +2872,11 @@ private:
size_t pos; size_t pos;
int c; int c;
// TODO remove check
if (lineptr == nullptr || buffer == nullptr || n == nullptr) {
return -1;
}
if (curr_char >= csv_data_size) { if (curr_char >= csv_data_size) {
return -1; return -1;
} }
c = buffer[curr_char++]; c = buffer[curr_char++];
// TODO maybe remove this too
if (*lineptr == nullptr) { if (*lineptr == nullptr) {
*lineptr = static_cast<char*>(malloc(128)); *lineptr = static_cast<char*>(malloc(128));
if (*lineptr == nullptr) { if (*lineptr == nullptr) {
@ -2877,13 +2889,11 @@ private:
while (curr_char <= csv_data_size) { while (curr_char <= csv_data_size) {
if (pos + 1 >= *n) { if (pos + 1 >= *n) {
size_t new_size = *n + (*n >> 2); size_t new_size = *n + (*n >> 2);
// TODO maybe remove this too
if (new_size < 128) { if (new_size < 128) {
new_size = 128; new_size = 128;
} }
char* new_ptr = static_cast<char*>( char* new_ptr = static_cast<char*>(
realloc(static_cast<void*>(*lineptr), new_size)); realloc(static_cast<void*>(*lineptr), new_size));
// TODO check for failed malloc in the callee
if (new_ptr == nullptr) { if (new_ptr == nullptr) {
return -1; return -1;
} }
@ -3050,11 +3060,11 @@ private:
} }
void realloc_concat(char*& first, size_t& first_size, void realloc_concat(char*& first, size_t& first_size,
const char* const second, size_t second_size) { size_t& buffer_size, const char* const second,
// TODO make buffer_size an argument size_t second_size) {
next_line_buffer_size_ = first_size + second_size + 3; buffer_size = first_size + second_size + 3;
auto new_first = static_cast<char*>( auto new_first = static_cast<char*>(
realloc(static_cast<void*>(first), next_line_buffer_size_)); realloc(static_cast<void*>(first), buffer_size));
if (!first) { if (!first) {
throw std::bad_alloc{}; throw std::bad_alloc{};
} }
@ -3084,7 +3094,8 @@ private:
++line_number_; ++line_number_;
size_t next_size = remove_eol(helper_buffer_, next_ssize); size_t next_size = remove_eol(helper_buffer_, next_ssize);
realloc_concat(buffer, size, helper_buffer_, next_size); realloc_concat(buffer, size, next_line_buffer_size_, helper_buffer_,
next_size);
return true; return true;
} }

View File

@ -21,6 +21,25 @@ TEST_CASE("test file not found") {
} }
} }
TEST_CASE("test null buffer") {
{
ss::parser p{nullptr, 10, ","};
CHECK_FALSE(p.valid());
}
{
ss::parser<ss::string_error> p{nullptr, 10, ","};
CHECK_FALSE(p.valid());
}
try {
ss::parser<ss::throw_on_error> p{nullptr, 10, ","};
FAIL("Expected exception...");
} catch (const std::exception& e) {
CHECK_FALSE(std::string{e.what()}.empty());
}
}
template <bool buffer_mode, typename... Ts> template <bool buffer_mode, typename... Ts>
void test_various_cases() { void test_various_cases() {
unique_file_name f{"test_parser"}; unique_file_name f{"test_parser"};