Now the file reader takes in account previous buffer size when reading more

This commit is contained in:
Luna 2025-07-08 08:58:07 +02:00
parent 238f9a9b97
commit 4d19f5ac40
3 changed files with 88 additions and 13 deletions

View file

@ -6,6 +6,13 @@
struct buffer struct buffer
{ {
buffer()
{
data = nullptr;
size = 0;
allocated = 0;
allocations = 0;
}
char *data; char *data;
size_t size; size_t size;
size_t allocated; size_t allocated;
@ -15,14 +22,24 @@ struct buffer
void remove(int offset, int remove_size); void remove(int offset, int remove_size);
void allocate(size_t s); void allocate(size_t s);
buffer(const buffer&) = delete;
buffer & operator=(const buffer &) = delete;
~buffer() ~buffer()
{ {
free(data); if (allocated > 0)
free(data);
} }
}; };
struct buffer_unsigned struct buffer_unsigned
{ {
buffer_unsigned()
{
data = nullptr;
size = 0;
allocated = 0;
allocations = 0;
}
unsigned char *data; unsigned char *data;
size_t size; size_t size;
size_t allocated; size_t allocated;
@ -32,8 +49,11 @@ struct buffer_unsigned
void remove(int offset, int remove_size); void remove(int offset, int remove_size);
void allocate(size_t s); void allocate(size_t s);
buffer_unsigned(const buffer_unsigned&) = delete;
buffer_unsigned & operator=(const buffer_unsigned &) = delete;
~buffer_unsigned() ~buffer_unsigned()
{ {
free(data); if (allocated > 0)
free(data);
} }
}; };

View file

@ -82,7 +82,7 @@ template<>
inline void read_type<buffer>(buffer &val, char *data) inline void read_type<buffer>(buffer &val, char *data)
{ {
val.allocated = val.size + 1; 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); std::memcpy(val.data, data, val.size);
} }

View file

@ -15,7 +15,7 @@ enum RESULT
class file_reader class file_reader
{ {
public: public:
file_reader(int file_fd) explicit file_reader(int file_fd)
:fd(file_fd) :fd(file_fd)
{ {
buf.size = 0; buf.size = 0;
@ -66,7 +66,7 @@ class file_reader
{ {
close(fd); close(fd);
} }
int extra_size = 0;
template<typename ...T> template<typename ...T>
std::pair<size_t, RESULT> read_from_tuple(std::tuple<T...> &in) std::pair<size_t, RESULT> read_from_tuple(std::tuple<T...> &in)
{ {
@ -75,7 +75,7 @@ class file_reader
return std::make_pair(0, READ_FILE_ENDED); return std::make_pair(0, READ_FILE_ENDED);
constexpr std::size_t size_tuple = sizeof...(T); constexpr std::size_t size_tuple = sizeof...(T);
int size = 0; int size = 0;
int extra_size = 0;
size_t total_read_size = 0; size_t total_read_size = 0;
const_for_<size_tuple>([&](auto i) const_for_<size_tuple>([&](auto i)
{ {
@ -86,22 +86,24 @@ class file_reader
}); });
if (size > buf.size) 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; 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; ret = READ_INCOMPLETE;
} }
char *new_read = (char *)calloc(size + extra_size, sizeof(char)); 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 read_done = 0;
size_t res = 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; read_done += res;
if (res == -1) if (res == -1)
{ {
@ -111,9 +113,10 @@ class file_reader
} }
if (res == 0) if (res == 0)
{ {
if (read_done != size + extra_size) if (read_done != extra_to_read + extra_size)
ret = READ_INCOMPLETE; ret = READ_INCOMPLETE;
total_read_size = read_done; total_read_size = read_done;
size = total_read_size;
break; break;
} }
} }
@ -132,6 +135,58 @@ class file_reader
buf.remove(0, size); buf.remove(0, size);
return std::make_pair(size, ret); return std::make_pair(size, ret);
} }
template <typename T>
std::pair<size_t, RESULT> 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: private:
buffer buf; buffer buf;
int fd; int fd;