mirror of
https://github.com/red0124/ssp.git
synced 2025-01-23 04:55:20 +01:00
Update get_line_buffer, update new version of get_line_file to work with data that has no new line at eof
This commit is contained in:
parent
273e8ad950
commit
8881649aca
@ -58,14 +58,15 @@ ssize_t get_line_file(char** lineptr, size_t* n, FILE* fp) {
|
|||||||
|
|
||||||
(*lineptr)[0] = '\0';
|
(*lineptr)[0] = '\0';
|
||||||
|
|
||||||
|
size_t line_used = 0;
|
||||||
while (fgets(buff, sizeof(buff), fp) != nullptr) {
|
while (fgets(buff, sizeof(buff), fp) != nullptr) {
|
||||||
size_t line_used = strlen(*lineptr);
|
line_used = strlen(*lineptr);
|
||||||
size_t buff_used = strlen(buff);
|
size_t buff_used = strlen(buff);
|
||||||
|
|
||||||
if (*n < buff_used + line_used) {
|
if (*n <= buff_used + line_used) {
|
||||||
size_t new_n = *n * 2;
|
size_t new_n = *n * 2;
|
||||||
|
|
||||||
auto new_lineptr = static_cast<char*>(realloc(*lineptr, *n));
|
auto new_lineptr = static_cast<char*>(realloc(*lineptr, new_n));
|
||||||
if (new_lineptr == nullptr) {
|
if (new_lineptr == nullptr) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -84,7 +85,7 @@ ssize_t get_line_file(char** lineptr, size_t* n, FILE* fp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return (line_used != 0) ? line_used : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -744,50 +744,52 @@ private:
|
|||||||
reader& operator=(const reader& other) = delete;
|
reader& operator=(const reader& other) = delete;
|
||||||
|
|
||||||
ssize_t get_line_buffer(char** lineptr, size_t* n,
|
ssize_t get_line_buffer(char** lineptr, size_t* n,
|
||||||
const char* const buffer, size_t csv_data_size,
|
const char* const csv_data_buffer,
|
||||||
size_t& curr_char) {
|
size_t csv_data_size, size_t& curr_char) {
|
||||||
size_t pos;
|
if (lineptr == nullptr || n == nullptr ||
|
||||||
int c;
|
csv_data_buffer == nullptr) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (curr_char >= csv_data_size) {
|
if (curr_char >= csv_data_size) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
c = buffer[curr_char++];
|
|
||||||
|
|
||||||
if (*lineptr == nullptr) {
|
if (*lineptr == nullptr || *n < get_line_initial_buffer_size) {
|
||||||
*lineptr =
|
auto new_lineptr = static_cast<char*>(
|
||||||
static_cast<char*>(malloc(get_line_initial_buffer_size));
|
realloc(*lineptr, get_line_initial_buffer_size));
|
||||||
if (*lineptr == nullptr) {
|
if (new_lineptr == nullptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*n = 128;
|
*lineptr = new_lineptr;
|
||||||
|
*n = get_line_initial_buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = 0;
|
size_t line_used = 0;
|
||||||
while (curr_char <= csv_data_size) {
|
while (curr_char <= csv_data_size) {
|
||||||
if (pos + 1 >= *n) {
|
if (line_used + 1 >= *n) {
|
||||||
size_t new_size = *n + (*n >> 2);
|
size_t new_n = *n * 2;
|
||||||
if (new_size < get_line_initial_buffer_size) {
|
|
||||||
new_size = get_line_initial_buffer_size;
|
char* new_lineptr =
|
||||||
}
|
static_cast<char*>(realloc(*lineptr, new_n));
|
||||||
char* new_ptr = static_cast<char*>(
|
if (new_lineptr == nullptr) {
|
||||||
realloc(static_cast<void*>(*lineptr), new_size));
|
errno = ENOMEM;
|
||||||
if (new_ptr == nullptr) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*n = new_size;
|
*n = new_n;
|
||||||
*lineptr = new_ptr;
|
*lineptr = new_lineptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*lineptr)[pos++] = c;
|
auto c = csv_data_buffer[curr_char++];
|
||||||
|
(*lineptr)[line_used++] = c;
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
break;
|
(*lineptr)[line_used] = '\0';
|
||||||
|
return line_used;
|
||||||
}
|
}
|
||||||
c = buffer[curr_char++];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*lineptr)[pos] = '\0';
|
return (line_used != 0) ? line_used : -1;
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read next line each time in order to set eof_
|
// read next line each time in order to set eof_
|
||||||
|
@ -571,9 +571,22 @@ template <bool buffer_mode>
|
|||||||
void test_no_new_line_at_eof() {
|
void test_no_new_line_at_eof() {
|
||||||
test_no_new_line_at_eof_impl<buffer_mode>({});
|
test_no_new_line_at_eof_impl<buffer_mode>({});
|
||||||
test_no_new_line_at_eof_impl<buffer_mode>({{1, 2, "X"}});
|
test_no_new_line_at_eof_impl<buffer_mode>({{1, 2, "X"}});
|
||||||
|
test_no_new_line_at_eof_impl<buffer_mode>({{1, 2, "X"}, {}});
|
||||||
test_no_new_line_at_eof_impl<buffer_mode>({{1, 2, "X"}, {3, 4, "YY"}});
|
test_no_new_line_at_eof_impl<buffer_mode>({{1, 2, "X"}, {3, 4, "YY"}});
|
||||||
|
test_no_new_line_at_eof_impl<buffer_mode>({{1, 2, "X"}, {3, 4, "YY"}, {}});
|
||||||
test_no_new_line_at_eof_impl<buffer_mode>(
|
test_no_new_line_at_eof_impl<buffer_mode>(
|
||||||
{{1, 2, "X"}, {3, 4, "YY"}, {5, 6, "ZZZ"}, {7, 8, "UUU"}});
|
{{1, 2, "X"}, {3, 4, "YY"}, {5, 6, "ZZZ"}, {7, 8, "UUU"}});
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 2 * ss::get_line_initial_buffer_size; ++i) {
|
||||||
|
test_no_new_line_at_eof_impl<buffer_mode>(
|
||||||
|
{{1, 2, std::string(i, 'X')}});
|
||||||
|
|
||||||
|
for (size_t j = 0; j < 2 * ss::get_line_initial_buffer_size; ++j) {
|
||||||
|
|
||||||
|
test_no_new_line_at_eof_impl<buffer_mode>(
|
||||||
|
{{1, 2, std::string(i, 'X')}, {3, 4, std::string(j, 'Y')}});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("test no new line at end of data") {
|
TEST_CASE("test no new line at end of data") {
|
||||||
|
Loading…
Reference in New Issue
Block a user