diff --git a/examples/test.cpp b/examples/test.cpp index 7797806..d3642b8 100644 --- a/examples/test.cpp +++ b/examples/test.cpp @@ -11,8 +11,18 @@ int main() t.allocated = 0; t.size = 10; auto tup = std::make_tuple(t); + auto tup2 = std::make_tuple(t); + auto tup3 = std::make_tuple(t); auto res = a.read_from_tuple(tup); + auto re2 = a.read_from_tuple(tup2); + auto re3 = a.read_from_tuple(tup3); if (res.second == READ_CORRECT) std::println("{}", std::get<0>(tup).data); + if (re2.second == READ_CORRECT) + std::println("{}", std::get<0>(tup2).data); + if (re3.second == READ_CORRECT) + std::println("{}", std::get<0>(tup3).data); + if (re3.second == READ_INCOMPLETE) + std::println("incomplete read with size {} {}", re3.first, std::get<0>(tup3).data); } \ No newline at end of file diff --git a/src/file_deserialising.h b/src/file_deserialising.h index 61bc1ed..fcd2fed 100644 --- a/src/file_deserialising.h +++ b/src/file_deserialising.h @@ -92,12 +92,19 @@ struct read_var static void call(T& val, parsing_buffer* v) { int size = 0; - if (typeid(T) == typeid(buffer)) + if constexpr (typeid(T) == typeid(buffer)) size = val.size; else size = sizeof(T); if (size + v->consumed_size > v->buf.size) - return ; + { + if constexpr (typeid(T) == typeid(buffer)) + { + val.size = v->buf.size; + } + else + return ; + } read_type(val, v->point); v->point += size; v->consumed_size += size; diff --git a/src/file_read.h b/src/file_read.h index 9c1816d..1f1af95 100644 --- a/src/file_read.h +++ b/src/file_read.h @@ -22,21 +22,51 @@ class file_reader buf.allocated = 0; buf.data = nullptr; file_size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); + if (file_size == -1) + { + std::println("lseek failed {}", strerror(errno)); + throw std::runtime_error("lseek failed"); + } + if (lseek(fd, 0, SEEK_SET) == -1) + { + std::println("lseek failed {}", strerror(errno)); + throw std::runtime_error("lseek failed"); + } file_size_remaining = file_size; } file_reader(std::string path) { fd = open(path.c_str(), O_RDONLY); + if (fd == -1) + { + std::println("Error opening the file {}", strerror(errno)); + throw std::runtime_error("Error opening file"); + } buf.size = 0; buf.allocated = 0; buf.data = nullptr; file_size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); + if (file_size == -1) + { + std::println("lseek failed {}", strerror(errno)); + throw std::runtime_error("lseek failed"); + } + if (lseek(fd, 0, SEEK_SET) == -1) + { + std::println("lseek failed {}", strerror(errno)); + throw std::runtime_error("lseek failed"); + } file_size_remaining = file_size; } + file_reader(const file_reader&) = delete; + file_reader & operator=(const file_reader &) = delete; + ~file_reader() + { + close(fd); + } + template std::pair read_from_tuple(std::tuple &in) { @@ -46,6 +76,7 @@ class file_reader 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) { if constexpr (typeid(std::get(in)) == typeid(buffer)) @@ -65,15 +96,29 @@ class file_reader ret = READ_INCOMPLETE; } char *new_read = (char *)calloc(size + extra_size, sizeof(char)); - size_t res = read(fd, new_read, size + extra_size); - if (res != size + extra_size) + total_read_size = size + extra_size; + size_t read_done = 0; + size_t res = 0; + while (read_done != size + extra_size) { - free(new_read); - std::println("Read error {}", strerror(errno)); - throw std::runtime_error("Read failed!"); + res = read(fd, &new_read[read_done], (size + extra_size) - read_done); + if (res == -1) + { + free(new_read); + std::println("Read error {}", strerror(errno)); + throw std::runtime_error("Read failed!"); + } + if (res == 0) + { + if (read_done != size + extra_size) + ret = READ_INCOMPLETE; + total_read_size = read_done; + break; + } + read_done += res; } - buf.write(new_read, size + extra_size); - file_size_remaining -= size + extra_size; + buf.write(new_read, total_read_size); + file_size_remaining -= total_read_size; free(new_read); } parsing_buffer par_buf(buf); @@ -81,8 +126,9 @@ class file_reader par_buf.consumed_size = 0; read_comp(size_tuple, par_buf, in); buf.remove(0, size); - return std::make_pair(size + extra_size, ret); + return std::make_pair(total_read_size, ret); } + private: buffer buf; int fd; off_t file_size;