Made project more solid, made deserialiser do incomplete buffer read, made file_reader non copyable, updated test.cpp
This commit is contained in:
parent
ceb65deca8
commit
02b593c237
3 changed files with 75 additions and 12 deletions
|
@ -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);
|
||||
}
|
|
@ -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<T>(val, v->point);
|
||||
v->point += size;
|
||||
v->consumed_size += size;
|
||||
|
|
|
@ -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<typename ...T>
|
||||
std::pair<size_t, RESULT> read_from_tuple(std::tuple<T...> &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_<size_tuple>([&](auto i)
|
||||
{
|
||||
if constexpr (typeid(std::get<i.value>(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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue