From 4d19f5ac40b126c38f0adddc3a4e97a6f2610c61 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 8 Jul 2025 08:58:07 +0200 Subject: [PATCH] Now the file reader takes in account previous buffer size when reading more --- src/buffer.h | 24 +++++++++++-- src/file_deserialising.h | 2 +- src/file_read.h | 75 ++++++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src/buffer.h b/src/buffer.h index 9fbce09..633f726 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -6,6 +6,13 @@ struct buffer { + buffer() + { + data = nullptr; + size = 0; + allocated = 0; + allocations = 0; + } char *data; size_t size; size_t allocated; @@ -15,14 +22,24 @@ struct buffer void remove(int offset, int remove_size); void allocate(size_t s); + buffer(const buffer&) = delete; + buffer & operator=(const buffer &) = delete; ~buffer() { - free(data); + if (allocated > 0) + free(data); } }; struct buffer_unsigned { + buffer_unsigned() + { + data = nullptr; + size = 0; + allocated = 0; + allocations = 0; + } unsigned char *data; size_t size; size_t allocated; @@ -32,8 +49,11 @@ struct buffer_unsigned void remove(int offset, int remove_size); void allocate(size_t s); + buffer_unsigned(const buffer_unsigned&) = delete; + buffer_unsigned & operator=(const buffer_unsigned &) = delete; ~buffer_unsigned() { - free(data); + if (allocated > 0) + free(data); } }; diff --git a/src/file_deserialising.h b/src/file_deserialising.h index fcd2fed..1bf2d95 100644 --- a/src/file_deserialising.h +++ b/src/file_deserialising.h @@ -82,7 +82,7 @@ template<> inline void read_type(buffer &val, char *data) { val.allocated = val.size + 1; - val.data = (char *)malloc(val.size * sizeof(char) + 1); + val.data = (char *)calloc(val.size + 1,sizeof(char)); std::memcpy(val.data, data, val.size); } diff --git a/src/file_read.h b/src/file_read.h index 3ec801f..99a50b6 100644 --- a/src/file_read.h +++ b/src/file_read.h @@ -15,7 +15,7 @@ enum RESULT class file_reader { public: - file_reader(int file_fd) + explicit file_reader(int file_fd) :fd(file_fd) { buf.size = 0; @@ -66,7 +66,7 @@ class file_reader { close(fd); } - + int extra_size = 0; template std::pair read_from_tuple(std::tuple &in) { @@ -75,7 +75,7 @@ class file_reader return std::make_pair(0, READ_FILE_ENDED); constexpr std::size_t size_tuple = sizeof...(T); int size = 0; - int extra_size = 0; + size_t total_read_size = 0; const_for_([&](auto i) { @@ -86,22 +86,24 @@ class file_reader }); if (size > buf.size) { - if (size + BUFFER_SIZE <= file_size_remaining) + int extra_to_read = size - buf.size; + int extra_size = 0; + if (extra_to_read + BUFFER_SIZE <= file_size_remaining) { extra_size = BUFFER_SIZE; } - else if (size > file_size_remaining) + else if (file_size_remaining + buf.size > file_size_remaining + buf.size) { - extra_size = file_size_remaining - size; + extra_to_read = file_size_remaining + buf.size; ret = READ_INCOMPLETE; } char *new_read = (char *)calloc(size + extra_size, sizeof(char)); - total_read_size = size + extra_size; + total_read_size = extra_to_read + extra_size; size_t read_done = 0; size_t res = 0; - while (read_done != size + extra_size) + while (read_done != extra_to_read + extra_size) { - res = read(fd, &new_read[read_done], (size + extra_size) - read_done); + res = read(fd, &new_read[read_done], (extra_to_read + extra_size) - read_done); read_done += res; if (res == -1) { @@ -111,9 +113,10 @@ class file_reader } if (res == 0) { - if (read_done != size + extra_size) + if (read_done != extra_to_read + extra_size) ret = READ_INCOMPLETE; total_read_size = read_done; + size = total_read_size; break; } } @@ -132,6 +135,58 @@ class file_reader buf.remove(0, size); return std::make_pair(size, ret); } + + template + std::pair read_buffer(T *buffer, int size) + { + RESULT ret = READ_CORRECT; + if (file_size_remaining <= 0 && buf.size <= 0) + return std::make_pair(0, READ_FILE_ENDED); + size_t total_read_size = 0; + if (size > buf.size) + { + int extra_to_read = size - buf.size; + int extra_size = 0; + if (extra_to_read + BUFFER_SIZE <= file_size_remaining) + { + extra_size = BUFFER_SIZE; + } + else if (file_size_remaining + buf.size > file_size_remaining + buf.size) + { + extra_to_read = file_size_remaining + buf.size; + ret = READ_INCOMPLETE; + } + char *new_read = (char *)calloc(size + extra_size, sizeof(char)); + total_read_size = extra_to_read + extra_size; + size_t read_done = 0; + size_t res = 0; + while (read_done != extra_to_read + extra_size) + { + res = read(fd, &new_read[read_done], (extra_to_read + extra_size) - read_done); + read_done += res; + if (res == -1) + { + free(new_read); + std::println("Read error {}", strerror(errno)); + throw std::runtime_error("Read failed!"); + } + if (res == 0) + { + if (read_done != extra_to_read + extra_size) + ret = READ_INCOMPLETE; + total_read_size = read_done; + size = total_read_size; + break; + } + } + buf.write(new_read, total_read_size); + file_size_remaining -= total_read_size; + free(new_read); + } + std::memcpy(buffer, buf.data, size); + buf.remove(0, size); + return std::make_pair(size, ret); + } private: buffer buf; int fd;