Skip to content

Commit

Permalink
refactor with strategy pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
iku-iku-iku committed Dec 23, 2023
1 parent 0314c07 commit c335892
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 39 deletions.
4 changes: 2 additions & 2 deletions ZpodsLib/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ FILE(GLOB_RECURSE SRC *.cpp *.c)

find_package(OpenSSL REQUIRED)

include_directories(./base ./core ./network ./)
include_directories(./base ./core ./transform ./)
add_library(${PROJECT_NAME} SHARED zpods_lib.h ${SRC})

collect_and_set_global_include_dirs(${CMAKE_CURRENT_SOURCE_DIR} ZPODS_LIB_INCLUDE_DIRS)

target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto)

target_precompile_headers(${PROJECT_NAME} PRIVATE ${PCH_PATH})
target_precompile_headers(${PROJECT_NAME} PRIVATE ${PCH_PATH})
27 changes: 20 additions & 7 deletions ZpodsLib/src/core/archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@

using namespace zpods;

Status zpods::archive(const char* src_dir, const char* dest_dir,
const BackupConfig& config)
std::pair<Status, std::string> zpods::make_archive(const char* src_dir,
const char* dest_dir,
const BackupConfig& config)
{
ZPODS_ASSERT(fs::is_directory(dest_dir));

size_t pod_total_size = 0;

let_mut collector = zpods::fs::FileCollector{src_dir, config.filter};
Expand Down Expand Up @@ -46,7 +45,7 @@ Status zpods::archive(const char* src_dir, const char* dest_dir,
if (pea_cnt == 0)
{
spdlog::info("no new pea to archive");
return Status::NO_NEW_TO_ARCHIVE;
return {Status::NO_NEW_TO_ARCHIVE, {}};
}

for (let_ref pea : pod)
Expand Down Expand Up @@ -100,10 +99,24 @@ Status zpods::archive(const char* src_dir, const char* dest_dir,
}

memset(p, 0, header_size);

return {Status::OK, {(const char*)buffer.get(), pod_total_size}};
}

Status zpods::archive(const char* src_dir, const char* dest_dir,
const BackupConfig& config)
{
ZPODS_ASSERT(fs::is_directory(dest_dir));

let[status, buffer] = make_archive(src_dir, dest_dir, config);
if (status != Status::OK)
{
return status;
}

let_mut ofs = fs::open_or_create_file_as_ofs(
config.current_pod_path.c_str(), fs::ios::binary);
ofs.write((char*)buffer.get(), (long)pod_total_size);

ofs << buffer;
return Status::OK;
}

Expand Down
3 changes: 3 additions & 0 deletions ZpodsLib/src/core/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ namespace zpods
Status archive(const char* src_dir, const char* dest_dir,
const BackupConfig& config = {});

std::pair<Status, std::string> make_archive(const char* src_dir,
const char* dest_dir,
const BackupConfig& config);
/*
* @brief unarchive a archive file indicated by src_path to a directory in
* target_dir
Expand Down
76 changes: 46 additions & 30 deletions ZpodsLib/src/core/backup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "archive.h"
#include "backup.h"
#include "manager.h"
#include "transform/transform_pipeline_builder.h"

using namespace zpods;

Expand All @@ -27,48 +28,63 @@ static Status backup_internal(const char* src_dir, const char* target_dir,
} while (fs::exists(config.current_pod_path.c_str()));

// 1. archive files of src_path to a single file in target_dir

status = zpods::archive(src_dir, target_dir, config);
if (status == Status::NO_NEW_TO_ARCHIVE)
{
return Status::OK;
}
else if (status != Status::OK)
{
return status;
}

let_mut bytes = fs::read_from_file(config.current_pod_path.c_str());
std::unique_ptr<byte[]> buf;
size_t buf_len;
TransformPipelineBuilder builder;

builder.enable_archive(src_dir, target_dir, config);

/* status = zpods::archive(src_dir, target_dir, config); */
/* if (status == Status::NO_NEW_TO_ARCHIVE) */
/* { */
/* return Status::OK; */
/* } */
/* else if (status != Status::OK) */
/* { */
/* return status; */
/* } */

/* let_mut bytes = fs::read_from_file(config.current_pod_path.c_str()); */
/* std::unique_ptr<byte[]> buf; */
/* size_t buf_len; */
// 2. compress if needed
if (config.compress)
{
std::tie(buf_len, buf) = compress({(p_byte)bytes.data(), bytes.size()});
bytes = {as_c_str(buf.get()), buf_len};
spdlog::info("file compression succeeded : {}",
config.current_pod_path.c_str());
builder.enable_compress();
/* std::tie(buf_len, buf) = compress({(p_byte)bytes.data(),
* bytes.size()}); */
/* bytes = {as_c_str(buf.get()), buf_len}; */
/* spdlog::info("file compression succeeded : {}", */
/* config.current_pod_path.c_str()); */
}

// 3. encrypt if needed
if (config.crypto_config)
{
let_ref conf = config.crypto_config;
let cipher = encrypt({as_c_str(bytes.data()), bytes.size()}, conf->key_,
conf->iv_);
if (!cipher.has_value())
{
spdlog::error("file encryption failed: {}",
config.current_pod_path.c_str());
return Status::ERROR;
}
bytes = {cipher->data(), cipher->size()};
spdlog::info("file encryption succeeded : {}",
config.current_pod_path.c_str());
let key = config.crypto_config->key_;
let iv = config.crypto_config->iv_;
builder.enable_encrypt(key, iv);
/* let_ref conf = config.crypto_config; */
/* let cipher = encrypt({as_c_str(bytes.data()), bytes.size()},
* conf->key_, */
/* conf->iv_); */
/* if (!cipher.has_value()) */
/* { */
/* spdlog::error("file encryption failed: {}", */
/* config.current_pod_path.c_str()); */
/* return Status::ERROR; */
/* } */
/* bytes = {cipher->data(), cipher->size()}; */
/* spdlog::info("file encryption succeeded : {}", */
/* config.current_pod_path.c_str()); */
}

// output to target file
{
let[status, bytes] = builder.build()->execute({});
if (status != Status::OK)
{
return status;
}

let_mut ofs = fs::open_or_create_file_as_ofs(
config.current_pod_path.c_str(), fs::ios::binary);

Expand Down
35 changes: 35 additions & 0 deletions ZpodsLib/src/transform/archive_transform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once
#include "transform.h"

#include "archive.h"

namespace zpods
{
class ArchiveTransform : public Transform
{
public:
ArchiveTransform(const char* src_dir, const char* dest_dir,
const BackupConfig& config)
: src_dir_(src_dir), dest_dir_(dest_dir), config_(config)
{
}

auto execute(std::string&& bytes) -> Transform::ResType override
{
let_mut[status, buf] =
make_archive(src_dir_.c_str(), dest_dir_.c_str(), config_);
if (status == Status::NO_NEW_TO_ARCHIVE)
{
spdlog::info("no new pea to archive");
status = Status::OK;
}
return {status, std::move(buf)};
}

private:
std::string src_dir_;
std::string dest_dir_;
const BackupConfig& config_;
};

} // namespace zpods
18 changes: 18 additions & 0 deletions ZpodsLib/src/transform/compress_transform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once
#include "compress.h"
#include "transform.h"

namespace zpods
{
class CompressTransform : public Transform
{
public:
auto execute(std::string&& bytes) -> Transform::ResType override
{
let[size, ptr] = zpods::compress({(byte*)bytes.data(), bytes.size()});
return {Status::OK, std::string{(const char*)ptr.get(), size}};
}

private:
}; // namespace zpods
} // namespace zpods
30 changes: 30 additions & 0 deletions ZpodsLib/src/transform/encrypt_transform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include "base/crypto.h"
#include "transform.h"

namespace zpods
{
class EncryptTransform : public Transform
{
public:
EncryptTransform(std::string_view key, std::string_view iv)
: key_(key), iv_(iv)
{
}
auto execute(std::string&& bytes) -> Transform::ResType override
{
auto ciphertext = zpods::encrypt(bytes, key_, iv_);
if (!ciphertext)
{
spdlog::error("encrypt failed!");
return {zpods::Status::ERROR, {}};
}
return {zpods::Status::OK, std::move(*ciphertext)};
}

private:
std::string key_;
std::string iv_;
};
} // namespace zpods
15 changes: 15 additions & 0 deletions ZpodsLib/src/transform/transform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "pch.h"

namespace zpods
{

class Transform
{
public:
using ResType = std::pair<zpods::Status, std::string>;
virtual auto execute(std::string&& bytes) -> ResType = 0;
virtual ~Transform() {}
};
} // namespace zpods
45 changes: 45 additions & 0 deletions ZpodsLib/src/transform/transform_pipeline.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "transform.h"

namespace zpods
{

class TransformPipeline : public Transform
{
public:
auto execute(std::string&& _bytes) -> Transform::ResType override
{
Status status;
std::string bytes = std::move(_bytes);
for (auto& transform : transforms_)
{
std::tie(status, bytes) = transform->execute(std::move(bytes));
if (status != Status::OK)
{
return {status, {}};
}
}
return {Status::OK, std::move(bytes)};
}

template <typename TransType, typename... Param>
requires std::derived_from<TransType, Transform>
void add_transform(Param&&... param)
{
transforms_.push_back(new TransType(std::forward<Param>(param)...));
}

~TransformPipeline() override
{
for (auto& transform : transforms_)
{
delete transform;
transform = nullptr;
}
}

private:
std::vector<Transform*> transforms_;
};
} // namespace zpods
45 changes: 45 additions & 0 deletions ZpodsLib/src/transform/transform_pipeline_builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "transform/archive_transform.h"
#include "transform/compress_transform.h"
#include "transform/encrypt_transform.h"
#include "transform_pipeline.h"

namespace zpods
{
class TransformPipelineBuilder
{
public:
TransformPipelineBuilder()
: pipeline_(std::make_unique<TransformPipeline>())
{
}

TransformPipelineBuilder& enable_archive(const char* src_dir,
const char* dest_dir,
const BackupConfig& config)
{
pipeline_->add_transform<ArchiveTransform>(src_dir, dest_dir, config);
return *this;
}
TransformPipelineBuilder& enable_compress()
{
pipeline_->add_transform<CompressTransform>();
return *this;
}
TransformPipelineBuilder& enable_encrypt(std::string_view key,
std::string_view iv)
{
pipeline_->add_transform<EncryptTransform>(key, iv);
return *this;
}

auto build() -> std::unique_ptr<TransformPipeline>
{
return std::move(pipeline_);
}

private:
std::unique_ptr<TransformPipeline> pipeline_;
};
} // namespace zpods

0 comments on commit c335892

Please sign in to comment.