changed project structure
Also made functions return result to know how the read went Also made the file derserializer work more efficiently
This commit is contained in:
parent
d161e31e63
commit
ceb65deca8
7 changed files with 75 additions and 31 deletions
|
@ -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)
|
||||
|
|
18
examples/test.cpp
Normal file
18
examples/test.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "../src/file_read.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <print>
|
||||
|
||||
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);
|
||||
}
|
1
examples/test.txt
Normal file
1
examples/test.txt
Normal file
|
@ -0,0 +1 @@
|
|||
18267127861827192871jasbajs
|
|
@ -4,7 +4,7 @@
|
|||
#include <print>
|
||||
#include <type_traits>
|
||||
#include "buffer.h"
|
||||
#define read_comp(size, ptr, t, sizes) const_for_<size>([&](auto i){read_var<std::tuple_element_t<i.value, std::remove_cvref_t<decltype(t)>>>::call(std::get<i.value>(t), &ptr, sizes[i.value]);});
|
||||
#define read_comp(size, ptr, t) const_for_<size>([&](auto i){read_var<std::tuple_element_t<i.value, std::remove_cvref_t<decltype(t)>>>::call(std::get<i.value>(t), &ptr);});
|
||||
#ifdef __APPLE__
|
||||
#include <libkern/OSByteOrder.h>
|
||||
|
||||
|
@ -37,9 +37,10 @@ struct parsing_buffer
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
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>(float &val, char *data, size_t size)
|
||||
inline void read_type<float>(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>(double &val, char *data, size_t size)
|
||||
inline void read_type<double>(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>(buffer &val, char *data, size_t size)
|
||||
inline void read_type<buffer>(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<typename T>
|
||||
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<T>(val, v->point, size);
|
||||
read_type<T>(val, v->point);
|
||||
v->point += size;
|
||||
v->consumed_size += size;
|
||||
}
|
|
@ -1,6 +1,16 @@
|
|||
#pragma once
|
||||
#include "file_deserialising.h"
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <print>
|
||||
#include <fcntl.h>
|
||||
|
||||
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<typename ...T>
|
||||
void read_from_tuple(std::tuple<T...> &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<typename ...T>
|
||||
std::pair<size_t, RESULT> read_from_tuple(std::tuple<T...> &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<size_t, size_tuple> sizes;
|
||||
int extra_size = 0;
|
||||
const_for_<size_tuple>([&](auto i)
|
||||
{
|
||||
if constexpr (typeid(std::get<i.value>(in)) == typeid(buffer))
|
||||
{
|
||||
size += std::get<i.value>(in).size;
|
||||
sizes[i.value] = std::get<i.value>(in).size;
|
||||
}
|
||||
else
|
||||
{
|
||||
size += sizeof(std::get<i.value>(in));
|
||||
sizes[i.value] = sizeof(std::get<i.value>(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;
|
Loading…
Add table
Add a link
Reference in a new issue