Skip to content

Commit

Permalink
Config Serialization + fix warnings
Browse files Browse the repository at this point in the history
- Moved FetchContent declarations to a dependecies/ subdir, to ease
  customization of each dependecy
- Added extra compiler warnings
- Fixed most of the warnings
- Added cereal lib for serialization, and defined functions to serialize
  Config objects with cereal
- Implemented to_file and from_file for Config with cereal
  • Loading branch information
f-michaut committed Dec 10, 2023
1 parent 6a9e16c commit 0d1b832
Show file tree
Hide file tree
Showing 20 changed files with 270 additions and 66 deletions.
17 changes: 7 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## Author Francois Michaut
##
## Started on Thu May 26 23:23:59 2022 Francois Michaut
## Last update Thu Dec 7 10:39:45 2023 Francois Michaut
## Last update Sun Dec 10 10:17:30 2023 Francois Michaut
##
## CMakeLists.txt : CMake to build the FileShareProtocol library
##
Expand All @@ -14,8 +14,6 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(FetchContent)

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

set(CMAKE_CXX_FLAGS_DEBUG_INIT "-O3 -DDEBUG -g3")
Expand All @@ -25,12 +23,7 @@ add_compile_definitions(_GNU_SOURCE)
project(LibFileShareProtocol VERSION 0.1.0 LANGUAGES C CXX)
configure_file(include/FileShare/Version.hpp.in FileShare/Version.hpp)

FetchContent_Declare(
cppsockets
GIT_REPOSITORY https://github.com/FileShare-Project/libcppsockets.git
GIT_TAG 94ac5087f8eca9dd25a1c87e347e16bb9a2168d2
)
FetchContent_MakeAvailable(cppsockets)
add_subdirectory(dependencies)

add_library(fsp
source/Errors/TransferErrors.cpp
Expand Down Expand Up @@ -60,8 +53,12 @@ add_library(fsp

target_include_directories(fsp PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>)
target_compile_definitions(fsp PRIVATE _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64)
target_compile_options(fsp PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Wall -Wextra>
$<$<CXX_COMPILER_ID:MSVC>:/W4>
)

target_link_libraries(fsp cppsockets)
target_link_libraries(fsp cppsockets cereal)

option(LIBFSP_BUILD_TESTS "TRUE to build the libfsp tests" FALSE)
if(LIBFSP_BUILD_TESTS)
Expand Down
26 changes: 26 additions & 0 deletions dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
##
## Project LibFileShareProtocol, 2023
##
## Author Francois Michaut
##
## Started on Sun Dec 10 10:27:39 2023 Francois Michaut
## Last update Sun Dec 10 10:29:09 2023 Francois Michaut
##
## CMakeLists.txt : CMake to fetch and build the dependecies of the FileShareProtocol library
##

include(FetchContent)

FetchContent_Declare(
cppsockets
GIT_REPOSITORY https://github.com/FileShare-Project/libcppsockets.git
GIT_TAG 7a0bd91b16f6c3aa808e26684916e0dcc935717a
)
FetchContent_MakeAvailable(cppsockets)

FetchContent_Declare(
cereal
GIT_REPOSITORY https://github.com/USCiLab/cereal.git
GIT_TAG d1fcec807b372f04e4c1041b3058e11c12853e6e
)
add_subdirectory(cereal)
14 changes: 14 additions & 0 deletions dependencies/cereal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
##
## Project LibFileShareProtocol, 2023
##
## Author Francois Michaut
##
## Started on Sun Dec 10 10:29:19 2023 Francois Michaut
## Last update Sun Dec 10 10:29:24 2023 Francois Michaut
##
## CMakeLists.txt : CMake to set build options for cereal dependency
##

set(JUST_INSTALL_CEREAL ON) # We don't want to build tests or benchmarks

FetchContent_MakeAvailable(cereal)
6 changes: 3 additions & 3 deletions include/FileShare/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Sun Aug 28 09:23:07 2022 Francois Michaut
** Last update Mon Dec 4 21:55:25 2023 Francois Michaut
** Last update Sat Dec 9 09:01:57 2023 Francois Michaut
**
** Client.hpp : Client to communicate with peers with the FileShareProtocol
*/
Expand Down Expand Up @@ -37,8 +37,8 @@ namespace FileShare {
void respond_to_request(Protocol::Request, Protocol::StatusCode);

// Blocking functions
Protocol::Response<void> send_file(std::string filepath, ProgressCallback progress_callback = [](const std::string &filepath, std::size_t current_size, std::size_t total_size){});
Protocol::Response<void> receive_file(std::string filepath, ProgressCallback progress_callback = [](const std::string &filepath, std::size_t current_size, std::size_t total_size){});
Protocol::Response<void> send_file(std::string filepath, ProgressCallback progress_callback = [](const std::string &, std::size_t, std::size_t){});
Protocol::Response<void> receive_file(std::string filepath, ProgressCallback progress_callback = [](const std::string &, std::size_t, std::size_t){});
Protocol::Response<std::vector<Protocol::FileInfo>> list_files(std::string folderpath = "");
// TODO: Async non-blocking Functions

Expand Down
12 changes: 5 additions & 7 deletions include/FileShare/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
** Author Francois Michaut
**
** Started on Tue Sep 13 11:23:57 2022 Francois Michaut
** Last update Wed Dec 6 06:26:43 2023 Francois Michaut
** Last update Sun Dec 10 17:37:30 2023 Francois Michaut
**
** Config.hpp : Configuration of the file sharing
*/

#pragma once

#include "FileShare/FileMapping.hpp"
#include "FileShare/Config/FileMapping.hpp"

#include <filesystem>
#include <vector>
Expand All @@ -26,12 +26,12 @@ namespace FileShare {
// on current operation and errors/latency
};

// paths starting with '~/' will have this part replaced by the current user's home directory
Config();
~Config() = default;

static Config from_file(std::filesystem::path config_file);
void to_file(std::filesystem::path config_file);
// paths starting with '~/' will have this part replaced by the current user's home directory
static Config from_file(std::filesystem::path config_file = "~/.fsp/config");
void to_file(std::filesystem::path config_file = "~/.fsp/config");

[[nodiscard]] const std::filesystem::path &get_downloads_folder() const;
Config &set_downloads_folder(const std::filesystem::path path);
Expand All @@ -45,9 +45,7 @@ namespace FileShare {
Config &set_private_keys_dir(std::filesystem::path path);
Config &set_private_key_name(std::string name);

[[nodiscard]] const std::string &get_root_name() const;
[[nodiscard]] TransportMode get_transport_mode() const;
Config &set_root_name(std::string root_name);
Config &set_transport_mode(TransportMode mode);

[[nodiscard]] bool is_server_disabled() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Sun Nov 19 11:23:07 2023 Francois Michaut
** Last update Wed Dec 6 02:24:38 2023 Francois Michaut
** Last update Sun Dec 10 17:33:23 2023 Francois Michaut
**
** FileMapping.hpp : Class to hold information about which files are available for listing/download
*/
Expand All @@ -27,6 +27,9 @@ namespace FileShare {
enum Visibility { VISIBLE, HIDDEN };
using NodeMap = std::unordered_map<std::string, PathNode, FileShare::Utils::string_hash, std::equal_to<>>;

PathNode() = default;
virtual ~PathNode() = default;

static PathNode make_virtual_node(std::string name, Visibility visibility = HIDDEN);
static PathNode make_virtual_node(std::string name, Visibility visibility, NodeMap child_nodes);
static PathNode make_virtual_node(std::string name, Visibility visibility, std::vector<PathNode> child_nodes);
Expand All @@ -41,6 +44,7 @@ namespace FileShare {
PathNode &clear_child_nodes();

[[nodiscard]] std::string_view get_name() const;
[[nodiscard]] const std::string &get_name_str() const;
PathNode &set_name(std::string name);

[[nodiscard]] Type get_type() const;
Expand Down Expand Up @@ -95,7 +99,8 @@ namespace FileShare {
public:
using FilepathSet=std::unordered_set<std::filesystem::path>;

FileMapping(RootPathNode root_node = {}, FilepathSet forbidden_paths = FileMapping::default_forbidden_paths());
FileMapping() = default;
FileMapping(RootPathNode root_node, FilepathSet forbidden_paths = FileMapping::default_forbidden_paths());

[[nodiscard]] std::string_view get_root_name() const;
void set_root_name(std::string root_name);
Expand Down
129 changes: 129 additions & 0 deletions include/FileShare/Config/Serialization.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
** Project LibFileShareProtocol, 2023
**
** Author Francois Michaut
**
** Started on Sun Dec 10 10:56:44 2023 Francois Michaut
** Last update Sun Dec 10 17:27:40 2023 Francois Michaut
**
** Serialization.hpp : FileShare Config serialization functions
*/

#pragma once

#include "FileShare/Config.hpp"

#include <cereal/cereal.hpp>
#include <cereal/types/filesystem.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/unordered_map.hpp>
#include <cereal/types/unordered_set.hpp>

static constexpr std::uint32_t file_share_config_version = 0;
static constexpr std::uint32_t file_share_file_mapping_version = 0;
static constexpr std::uint32_t file_share_path_node_version = 0;

CEREAL_CLASS_VERSION(FileShare::Config, file_share_config_version);
CEREAL_CLASS_VERSION(FileShare::FileMapping, file_share_file_mapping_version);
CEREAL_CLASS_VERSION(FileShare::RootPathNode, file_share_path_node_version);
CEREAL_CLASS_VERSION(FileShare::PathNode, file_share_path_node_version);

namespace FileShare {
template <class Archive>
void save(Archive &ar, const FileShare::Config &config, [[maybe_unused]] const std::uint32_t version)
{
ar(
config.get_transport_mode(),
config.get_file_mapping(),
config.get_downloads_folder(),
config.get_private_keys_dir(),
config.get_private_key_name(),
config.is_server_disabled()
);
}

template <class Archive>
void load(Archive &ar, FileShare::Config &config, const std::uint32_t version)
{
if (version > file_share_config_version) {
throw std::runtime_error("Config file format is more recent than what this program supports");
}

FileShare::Config::TransportMode mode;
FileShare::FileMapping mapping;
std::filesystem::path downloads_folder;
std::filesystem::path private_keys_dir;
std::string private_key_name;
bool server_disabled;

ar(mode, mapping, downloads_folder, private_keys_dir, private_key_name, server_disabled);

config.set_transport_mode(mode)
.set_file_mapping(std::move(mapping))
.set_downloads_folder(std::move(downloads_folder))
.set_private_keys_dir(std::move(private_keys_dir))
.set_private_key_name(std::move(private_key_name))
.set_server_disabled(server_disabled);
}

template <class Archive, typename Node>
typename std::enable_if_t<std::is_base_of_v<FileShare::PathNode, Node>, void>
save(Archive &ar, const Node &root_node, [[maybe_unused]] const std::uint32_t version)
{
ar(
root_node.get_name_str(),
root_node.get_type(),
root_node.get_visibility(),
root_node.get_host_path(),
root_node.get_child_nodes()
);
}

template <class Archive, typename Node>
typename std::enable_if_t<std::is_base_of_v<FileShare::PathNode, Node>, void>
load(Archive &ar, Node &root_node, const std::uint32_t version)
{
if (version > file_share_path_node_version) {
throw std::runtime_error("PathNode file format is more recent than what this program supports");
}

std::string name;
PathNode::Type type;
PathNode::Visibility visibility;
std::filesystem::path host_path;
PathNode::NodeMap child_nodes;

ar(name, type, visibility, host_path, child_nodes);

root_node.set_name(std::move(name));
root_node.set_type(type);
root_node.set_visibility(visibility);
root_node.set_host_path(std::move(host_path));
root_node.set_child_nodes(std::move(child_nodes));
}

template <class Archive>
void save(Archive &ar, const FileShare::FileMapping &file_mapping, [[maybe_unused]] const std::uint32_t version)
{
ar(
file_mapping.get_root_node(),
file_mapping.get_forbidden_paths()
);
}

template <class Archive>
void load(Archive &ar, FileShare::FileMapping &file_mapping, const std::uint32_t version)
{
if (version > file_share_file_mapping_version) {
throw std::runtime_error("FileMapping file format is more recent than what this program supports");
}

FileShare::RootPathNode root_node;
FileShare::FileMapping::FilepathSet forbidden_paths;

ar(root_node, forbidden_paths);

file_mapping.set_root_node(std::move(root_node));
file_mapping.set_forbidden_paths(std::move(forbidden_paths));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
** Author Francois Michaut
**
** Started on Fri May 5 21:32:03 2023 Francois Michaut
** Last update Thu Aug 24 09:42:01 2023 Francois Michaut
** Last update Sat Dec 9 08:59:02 2023 Francois Michaut
**
** ProtocolHandler.hpp : ProtocolHandler for the v0.0.0 of the protocol
*/
Expand All @@ -17,6 +17,8 @@
namespace FileShare::Protocol::Handler::v0_0_0 {
class ProtocolHandler : public IProtocolHandler {
public:
virtual ~ProtocolHandler() = default;

std::string format_send_file(std::uint8_t message_id, const SendFileData &data) override;
std::string format_receive_file(std::uint8_t message_id, const ReceiveFileData &data) override;
std::string format_list_files(std::uint8_t message_id, const ListFilesData &data) override;
Expand Down
Loading

0 comments on commit 0d1b832

Please sign in to comment.