diff --git a/CMakeLists.txt b/CMakeLists.txt index e74f44e..4631ae1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(file_read) set(CMAKE_CXX_STANDARD 23) add_library(file_read STATIC - file_deserialising.h - buffer.cpp - buffer.h - file_read.h) + src/file_deserialising.h + src/buffer.cpp + src/buffer.h + src/file_read.h) diff --git a/examples/test.cpp b/examples/test.cpp new file mode 100644 index 0000000..7797806 --- /dev/null +++ b/examples/test.cpp @@ -0,0 +1,18 @@ +#include "../src/file_read.h" +#include +#include +#include + +int main() +{ + file_reader a("test.txt"); + buffer t; + t.data = nullptr; + t.allocated = 0; + t.size = 10; + auto tup = std::make_tuple(t); + auto res = a.read_from_tuple(tup); + + if (res.second == READ_CORRECT) + std::println("{}", std::get<0>(tup).data); +} \ No newline at end of file diff --git a/examples/test.txt b/examples/test.txt new file mode 100644 index 0000000..4bd610f --- /dev/null +++ b/examples/test.txt @@ -0,0 +1 @@ +18267127861827192871jasbajs \ No newline at end of file diff --git a/buffer.cpp b/src/buffer.cpp similarity index 100% rename from buffer.cpp rename to src/buffer.cpp diff --git a/buffer.h b/src/buffer.h similarity index 100% rename from buffer.h rename to src/buffer.h diff --git a/file_deserialising.h b/src/file_deserialising.h similarity index 65% rename from file_deserialising.h rename to src/file_deserialising.h index 5955c3f..61bc1ed 100644 --- a/file_deserialising.h +++ b/src/file_deserialising.h @@ -4,7 +4,7 @@ #include #include #include "buffer.h" -#define read_comp(size, ptr, t, sizes) const_for_([&](auto i){read_var>>::call(std::get(t), &ptr, sizes[i.value]);}); +#define read_comp(size, ptr, t) const_for_([&](auto i){read_var>>::call(std::get(t), &ptr);}); #ifdef __APPLE__ #include @@ -37,9 +37,10 @@ struct parsing_buffer }; template -static void read_type(T& val, char *data, size_t size) +static void read_type(T& val, char *data) { - switch (size) + std::memcpy(&val, data, sizeof(T)); + switch (sizeof(T)) { case 1: break; @@ -58,42 +59,46 @@ static void read_type(T& val, char *data, size_t size) } template <> -void read_type(float &val, char *data, size_t size) +inline void read_type(float &val, char *data) { uint32_t num_as_uint32; - memcpy(&num_as_uint32, data, size); + memcpy(&num_as_uint32, data, sizeof(float)); num_as_uint32 = be32toh(num_as_uint32); - memcpy(&val, &num_as_uint32, size); + memcpy(&val, &num_as_uint32, sizeof(float)); } template <> -void read_type(double &val, char *data, size_t size) +inline void read_type(double &val, char *data) { uint64_t num_as_uint64; - memcpy(&num_as_uint64, data, size); + memcpy(&num_as_uint64, data, sizeof(double)); num_as_uint64 = be64toh(num_as_uint64); - memcpy(&val, &num_as_uint64, size); + memcpy(&val, &num_as_uint64, sizeof(double)); } template<> -void read_type(buffer &val, char *data, size_t size) +inline void read_type(buffer &val, char *data) { - val.allocated = size + 1; - val.size = size; - val.data = (char *)malloc(size * sizeof(char) + 1); - std::memcpy(val.data, data, size); + val.allocated = val.size + 1; + val.data = (char *)malloc(val.size * sizeof(char) + 1); + std::memcpy(val.data, data, val.size); } template struct read_var { - static void call(T& val, parsing_buffer* v, size_t size) + static void call(T& val, parsing_buffer* v) { + int size = 0; + if (typeid(T) == typeid(buffer)) + size = val.size; + else + size = sizeof(T); if (size + v->consumed_size > v->buf.size) return ; - read_type(val, v->point, size); + read_type(val, v->point); v->point += size; v->consumed_size += size; } diff --git a/file_read.h b/src/file_read.h similarity index 61% rename from file_read.h rename to src/file_read.h index 376cec4..9c1816d 100644 --- a/file_read.h +++ b/src/file_read.h @@ -1,6 +1,16 @@ #pragma once #include "file_deserialising.h" #include +#include +#include +#include + +enum RESULT +{ + READ_CORRECT, //read was as expected + READ_INCOMPLETE, //read is incomplete (probably because of the file ending) + READ_FILE_ENDED //cannot read because there's not more file to read +}; class file_reader { @@ -16,28 +26,35 @@ class file_reader file_size_remaining = file_size; } - template - void read_from_tuple(std::tuple &in) + file_reader(std::string path) { + fd = open(path.c_str(), O_RDONLY); + buf.size = 0; + buf.allocated = 0; + buf.data = nullptr; + file_size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + file_size_remaining = file_size; + } + + template + std::pair read_from_tuple(std::tuple &in) + { + RESULT ret = READ_CORRECT; + if (file_size_remaining <= 0) + return std::make_pair(0, READ_FILE_ENDED); constexpr std::size_t size_tuple = sizeof...(T); int size = 0; - std::array sizes; + int extra_size = 0; const_for_([&](auto i) { if constexpr (typeid(std::get(in)) == typeid(buffer)) - { size += std::get(in).size; - sizes[i.value] = std::get(in).size; - } else - { size += sizeof(std::get(in)); - sizes[i.value] = sizeof(std::get(in)); - } }); if (size > buf.size) { - int extra_size = 0; if (size + BUFFER_SIZE <= file_size_remaining) { extra_size = BUFFER_SIZE; @@ -45,12 +62,14 @@ class file_reader else if (size > file_size_remaining) { extra_size = file_size_remaining - size; + 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) { free(new_read); + std::println("Read error {}", strerror(errno)); throw std::runtime_error("Read failed!"); } buf.write(new_read, size + extra_size); @@ -60,8 +79,9 @@ class file_reader parsing_buffer par_buf(buf); par_buf.point = buf.data; par_buf.consumed_size = 0; - read_comp(size_tuple, par_buf, in, sizes); + read_comp(size_tuple, par_buf, in); buf.remove(0, size); + return std::make_pair(size + extra_size, ret); } buffer buf; int fd;