5 Commits

Author SHA1 Message Date
ebe78d1fbd updated build system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2024-08-08 20:11:53 -05:00
f2dc325774 updated build system 2024-08-08 19:33:16 -05:00
7977b4b304 updated build system 2024-08-08 19:20:38 -05:00
e1ac9efaaa refactor 2024-08-08 19:03:55 -05:00
0b5efef569 updated build system 2024-08-08 18:59:14 -05:00
41 changed files with 1302 additions and 722 deletions

View File

@ -42,6 +42,13 @@ if(PROJECT_IS_ARM64)
add_definitions(-DPROJECT_IS_ARM64)
endif()
if(PROJECT_IS_MINGW)
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
add_definitions(-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
endif()
endif()
include(cmake/settings.cmake)
include(cmake/flags.cmake)
@ -127,6 +134,7 @@ endif()
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
-DPROJECT_DESC=${PROJECT_DESC}
-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR}
-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}
-DPROJECT_ENABLE_BACKWARD_CPP=${PROJECT_ENABLE_BACKWARD_CPP}
-DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST}
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB}

View File

@ -19,6 +19,8 @@ PROJECT_APP_LIST=(${PROJECT_NAME})
PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY}
PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_ENABLE_BACKWARD_CPP=ON
PROJECT_ENABLE_BOOST=ON
PROJECT_ENABLE_CPP_HTTPLIB=ON

View File

@ -33,7 +33,7 @@ using response_callback =
struct read_file_info final {
stop_type &stop_requested;
utils::file::file file{};
std::unique_ptr<utils::file::i_file> file{};
std::uint64_t offset{};
};
@ -42,7 +42,7 @@ inline const auto read_file_data = static_cast<read_callback>(
auto *read_info = reinterpret_cast<read_file_info *>(instream);
std::size_t bytes_read{};
auto ret =
read_info->file.read(reinterpret_cast<unsigned char *>(buffer),
read_info->file->read(reinterpret_cast<unsigned char *>(buffer),
size * nitems, read_info->offset, &bytes_read);
if (ret) {
read_info->offset += bytes_read;

View File

@ -1269,7 +1269,7 @@ public:
data_buffer buffer(write_size);
if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
buffer = macaron::Base64::Decode(
std::string{buffer.begin(), buffer.end()});
std::string(buffer.begin(), buffer.end()));
write_size = buffer.size();
remote::file_offset write_offset{};

View File

@ -131,7 +131,7 @@ public:
std::atomic<std::chrono::system_clock::time_point> last_access_{
std::chrono::system_clock::now()};
bool modified_{false};
utils::file::file nf_;
std::unique_ptr<utils::file::i_file> nf_;
mutable std::mutex io_thread_mtx_;
std::condition_variable io_thread_notify_;
std::deque<std::shared_ptr<io_item>> io_thread_queue_;

View File

@ -38,15 +38,6 @@ void change_to_process_directory();
[[nodiscard]] auto copy_file(std::string from_path,
std::string to_path) -> bool;
[[nodiscard]] auto create_full_directory_path(std::string path) -> bool;
[[nodiscard]] auto delete_directory(std::string path,
bool recursive = false) -> bool;
[[nodiscard]] auto delete_directory_recursively(std::string path) -> bool;
[[nodiscard]] auto delete_file(std::string path) -> bool;
[[nodiscard]] auto generate_sha256(const std::string &file_path) -> std::string;
[[nodiscard]] auto get_accessed_time(const std::string &path,

View File

@ -103,15 +103,15 @@ app_config::app_config(const provider_type &prov,
hc_.api_password = get_provider_api_password(prov_);
hc_.api_port = default_api_port(prov_);
if (not utils::file::create_full_directory_path(data_directory_)) {
if (not utils::file::create_directories(data_directory_)) {
throw startup_exception("unable to create: " + data_directory_);
}
if (not utils::file::create_full_directory_path(cache_directory_)) {
if (not utils::file::create_directories(cache_directory_)) {
throw startup_exception("unable to create: " + cache_directory_);
}
if (not utils::file::create_full_directory_path(log_directory_)) {
if (not utils::file::create_directories(log_directory_)) {
throw startup_exception("unable to create: " + log_directory_);
}
@ -715,7 +715,7 @@ void app_config::save() {
recur_mutex_lock lock(read_write_mutex_);
if (config_changed_ || not utils::file::is_file(file_path)) {
if (not utils::file::is_directory(data_directory_)) {
if (not utils::file::create_full_directory_path(data_directory_)) {
if (not utils::file::create_directories(data_directory_)) {
utils::error::raise_error(
function_name, "failed to create directory|sp|" + data_directory_ +
"|err|" +

View File

@ -49,11 +49,11 @@ auto http_put_file::set_method(CURL *curl,
utils::file::file::open_or_create_file(source_path),
});
if (not read_info->file) {
if (not *read_info->file) {
return false;
}
auto file_size = read_info->file.size();
auto file_size = read_info->file->size();
curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data);

View File

@ -38,7 +38,7 @@ void packet::clear() {
auto packet::decode(std::string &data) -> packet::error_type {
const auto *str = reinterpret_cast<const char *>(&buffer_[decode_offset_]);
const auto length = strnlen(str, buffer_.size() - decode_offset_);
data = std::string{str, length};
data = std::string(str, length);
decode_offset_ += (length + 1);
return utils::from_api_error(api_error::success);

View File

@ -68,7 +68,7 @@ file_manager::open_file::open_file(
if (not fsi.directory) {
nf_ = utils::file::file::open_or_create_file(fsi.source_path,
provider_.is_direct_only());
set_api_error(nf_ ? api_error::success : api_error::os_error);
set_api_error(*nf_ ? api_error::success : api_error::os_error);
if (get_api_error() == api_error::success) {
if (read_state.has_value()) {
read_state_ = read_state.value();
@ -78,16 +78,16 @@ file_manager::open_file::open_file(
fsi_.size, chunk_size)),
false);
auto file_size = nf_.size();
auto file_size = nf_->size();
if (provider_.is_direct_only() || file_size == fsi.size) {
read_state_.set(0U, read_state_.size(), true);
} else if (not nf_.truncate(fsi.size)) {
} else if (not nf_->truncate(fsi.size)) {
set_api_error(api_error::os_error);
}
}
if (get_api_error() != api_error::success && nf_) {
nf_.close();
if (get_api_error() != api_error::success && *nf_) {
nf_->close();
}
}
}
@ -182,7 +182,7 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
res = do_io([&]() -> api_error {
std::size_t bytes_written{};
if (not nf_.write(data, data_offset, &bytes_written)) {
if (not nf_->write(data, data_offset, &bytes_written)) {
return api_error::os_error;
}
@ -242,7 +242,7 @@ auto file_manager::open_file::native_operation(
}
file_lock.unlock();
return do_io([&]() -> api_error { return callback(nf_.get_handle()); });
return do_io([&]() -> api_error { return callback(nf_->get_handle()); });
}
auto file_manager::open_file::native_operation(
@ -283,7 +283,7 @@ auto file_manager::open_file::native_operation(
const auto original_file_size = get_file_size();
auto res = do_io([&]() -> api_error { return callback(nf_.get_handle()); });
auto res = do_io([&]() -> api_error { return callback(nf_->get_handle()); });
if (res != api_error::success) {
utils::error::raise_api_path_error(function_name, get_api_path(),
utils::get_last_error_code(),
@ -292,7 +292,7 @@ auto file_manager::open_file::native_operation(
}
{
auto file_size = nf_.size();
auto file_size = nf_->size();
if (file_size != new_file_size) {
utils::error::raise_api_path_error(
function_name, get_api_path(), api_error::file_size_mismatch,
@ -361,7 +361,7 @@ auto file_manager::open_file::read(std::size_t read_size,
data.resize(read_size);
std::size_t bytes_read{};
return nf_.read(data.data(), read_size, read_offset, &bytes_read)
return nf_->read(data.data(), read_size, read_offset, &bytes_read)
? api_error::success
: api_error::os_error;
});
@ -412,7 +412,7 @@ auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error {
return native_operation(
new_file_size, [this, &new_file_size](native_handle) -> api_error {
return nf_.truncate(new_file_size) ? api_error::success
return nf_->truncate(new_file_size) ? api_error::success
: api_error::os_error;
});
}
@ -449,7 +449,7 @@ auto file_manager::open_file::close() -> bool {
}
}
nf_.close();
nf_->close();
if (modified_ && (get_api_error() == api_error::success)) {
mgr_.queue_upload(*this);
@ -464,7 +464,7 @@ auto file_manager::open_file::close() -> bool {
utils::get_last_error_code(), "failed to delete file");
}
auto parent = utils::path::remove_file_name(fsi_.source_path);
auto parent = utils::path::get_parent_directory(fsi_.source_path);
fsi_.source_path =
utils::path::combine(parent, {utils::create_uuid_string()});
const auto res = provider_.set_item_meta(fsi_.api_path, META_SOURCE,
@ -575,7 +575,7 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
}
auto res = do_io([&]() -> api_error {
if (not nf_.write(data, write_offset, &bytes_written)) {
if (not nf_->write(data, write_offset, &bytes_written)) {
return api_error::os_error;
}

View File

@ -64,7 +64,7 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
ring_state_.set(0U, ring_state_.size(), true);
buffer_directory = utils::path::absolute(buffer_directory);
if (not utils::file::create_full_directory_path(buffer_directory)) {
if (not utils::file::create_directories(buffer_directory)) {
throw std::runtime_error("failed to create buffer directory|path|" +
buffer_directory + "|err|" +
std::to_string(utils::get_last_error_code()));
@ -73,13 +73,13 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
fsi_.source_path =
utils::path::combine(buffer_directory, {utils::create_uuid_string()});
nf_ = utils::file::file::open_or_create_file(fsi_.source_path);
if (not nf_) {
if (not *nf_) {
throw std::runtime_error("failed to create buffer file|err|" +
std::to_string(utils::get_last_error_code()));
}
if (not nf_.truncate(ring_state_.size() * chunk_size)) {
nf_.close();
if (not nf_->truncate(ring_state_.size() * chunk_size)) {
nf_->close();
throw std::runtime_error("failed to resize buffer file|err|" +
std::to_string(utils::get_last_error_code()));
}
@ -92,7 +92,7 @@ file_manager::ring_buffer_open_file::~ring_buffer_open_file() {
close();
nf_.close();
nf_->close();
if (not utils::file::retry_delete_file(fsi_.source_path)) {
utils::error::raise_api_path_error(
function_name, fsi_.api_path, fsi_.source_path,
@ -128,7 +128,7 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk(
if (res == api_error::success) {
res = do_io([&]() -> api_error {
std::size_t bytes_written{};
if (not nf_.write(buffer, (chunk % ring_state_.size()) * chunk_size_,
if (not nf_->write(buffer, (chunk % ring_state_.size()) * chunk_size_,
&bytes_written)) {
return api_error::os_error;
}
@ -200,7 +200,7 @@ auto file_manager::ring_buffer_open_file::is_download_complete() const -> bool {
auto file_manager::ring_buffer_open_file::native_operation(
i_open_file::native_operation_callback callback) -> api_error {
return do_io([&]() -> api_error { return callback(nf_.get_handle()); });
return do_io([&]() -> api_error { return callback(nf_->get_handle()); });
}
void file_manager::ring_buffer_open_file::reverse(std::size_t count) {
@ -270,7 +270,7 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
&to_read]() -> api_error {
std::size_t bytes_read{};
auto ret =
nf_.read(buffer, ((chunk % ring_state_.size()) * chunk_size_),
nf_->read(buffer, ((chunk % ring_state_.size()) * chunk_size_),
&bytes_read)
? api_error::success
: api_error::os_error;

View File

@ -57,7 +57,7 @@ lock_data::~lock_data() {
auto lock_data::get_lock_data_file() -> std::string {
const auto dir = get_state_directory();
if (not utils::file::create_full_directory_path(dir)) {
if (not utils::file::create_directories(dir)) {
throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code()));
}
@ -67,7 +67,7 @@ auto lock_data::get_lock_data_file() -> std::string {
auto lock_data::get_lock_file() -> std::string {
const auto dir = get_state_directory();
if (not utils::file::create_full_directory_path(dir)) {
if (not utils::file::create_directories(dir)) {
throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code()));
}

View File

@ -485,7 +485,7 @@ void base_provider::remove_deleted_files() {
if (utils::file::is_file(item.source_path)) {
const auto orphaned_directory =
utils::path::combine(config_.get_data_directory(), {"orphaned"});
if (utils::file::create_full_directory_path(orphaned_directory)) {
if (utils::file::create_directories(orphaned_directory)) {
const auto parts = utils::string::split(item.api_path, '/', false);
const auto orphaned_file = utils::path::combine(
orphaned_directory,

View File

@ -117,7 +117,7 @@ auto copy_directory_recursively(std::string from_path,
std::string to_path) -> bool {
from_path = utils::path::absolute(from_path);
to_path = utils::path::absolute(to_path);
auto ret = create_full_directory_path(to_path);
auto ret = create_directories(to_path);
if (ret) {
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
@ -167,108 +167,6 @@ auto copy_directory_recursively(std::string from_path,
return ret;
}
auto create_full_directory_path(std::string path) -> bool {
#if defined(_WIN32)
const auto unicode_path =
utils::string::from_utf8(utils::path::absolute(path));
return is_directory(path) ||
(::SHCreateDirectory(nullptr, unicode_path.c_str()) == ERROR_SUCCESS);
#else
auto ret = true;
const auto paths = utils::string::split(
utils::path::absolute(path), utils::path::directory_seperator[0U], false);
std::string current_path;
for (std::size_t i = 0U; ret && (i < paths.size()); i++) {
if (paths[i].empty()) { // Skip root
current_path = utils::path::directory_seperator;
} else {
current_path = utils::path::combine(current_path, {paths[i]});
const auto status = mkdir(current_path.c_str(), S_IRWXU);
ret = ((status == 0) || (errno == EEXIST));
}
}
return ret;
#endif
}
auto delete_directory(std::string path, bool recursive) -> bool {
if (recursive) {
return delete_directory_recursively(path);
}
path = utils::path::absolute(path);
#if defined(_WIN32)
return (not is_directory(path) || utils::retryable_action([&]() -> bool {
return !!::RemoveDirectoryA(path.c_str());
}));
#else
return not is_directory(path) || (rmdir(path.c_str()) == 0);
#endif
}
auto delete_directory_recursively(std::string path) -> bool {
path = utils::path::absolute(path);
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
auto res = true;
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
res = delete_directory_recursively(
utils::path::combine(path, {fd.cFileName}));
}
} else {
res = retry_delete_file(utils::path::combine(path, {fd.cFileName}));
}
} while (res && (::FindNextFile(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(path.c_str());
if (root) {
auto res = true;
struct dirent *de{};
while (res && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
res = delete_directory_recursively(
utils::path::combine(path, {de->d_name}));
}
} else {
res = retry_delete_file(utils::path::combine(path, {de->d_name}));
}
}
closedir(root);
}
#endif
return delete_directory(path, false);
}
auto delete_file(std::string path) -> bool {
path = utils::path::absolute(path);
#if defined(_WIN32)
return (not is_file(path) || utils::retryable_action([&]() -> bool {
const auto ret = !!::DeleteFileA(path.c_str());
if (not ret) {
std::cout << "delete failed:" << path << std::endl;
}
return ret;
}));
#else
return (not is_file(path) || (unlink(path.c_str()) == 0));
#endif
}
auto generate_sha256(const std::string &file_path) -> std::string {
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
@ -277,16 +175,16 @@ auto generate_sha256(const std::string &file_path) -> std::string {
std::to_string(res));
}
auto nf = utils::file::file::open_file(file_path);
if (not nf) {
{
auto input_file = utils::file::file::open_file(file_path);
if (not *input_file) {
throw std::runtime_error("failed to open file|" + file_path);
}
{
data_buffer buffer(1048576u);
std::uint64_t read_offset = 0U;
std::size_t bytes_read = 0U;
while (nf.read(buffer, read_offset, &bytes_read)) {
data_buffer buffer(input_file->get_read_buffer_size());
std::uint64_t read_offset{0U};
std::size_t bytes_read{0U};
while (input_file->read(buffer, read_offset, &bytes_read)) {
if (not bytes_read) {
break;
}
@ -506,8 +404,8 @@ auto move_file(std::string from, std::string to) -> bool {
from = utils::path::absolute(from);
to = utils::path::absolute(to);
const auto directory = utils::path::remove_file_name(to);
if (not create_full_directory_path(directory)) {
const auto directory = utils::path::get_parent_directory(to);
if (not create_directories(directory)) {
return false;
}
@ -563,7 +461,7 @@ auto reset_modified_time(const std::string &path) -> bool {
auto retry_delete_directory(const std::string &dir) -> bool {
auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_directory(dir)) && (i < 200U);
for (std::uint8_t i = 0U; not(deleted = remove_directory(dir)) && (i < 200U);
i++) {
std::this_thread::sleep_for(10ms);
}
@ -573,8 +471,8 @@ auto retry_delete_directory(const std::string &dir) -> bool {
auto retry_delete_file(const std::string &file) -> bool {
auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_file(file)) && (i < 200U);
i++) {
for (std::uint8_t i = 0U;
not(deleted = utils::file::file{file}.remove()) && (i < 200U); i++) {
std::this_thread::sleep_for(10ms);
}

View File

@ -49,10 +49,11 @@ protected:
void SetUp() override {
if (PROVIDER_INDEX != 0) {
if (PROVIDER_INDEX == 1) {
EXPECT_TRUE(
utils::file::delete_directory_recursively(utils::path::combine(
EXPECT_TRUE(utils::file::remove_directory(
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)})));
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}),
true));
app_config src_cfg(
provider_type::s3,
@ -96,10 +97,11 @@ protected:
}
if (PROVIDER_INDEX == 2) {
EXPECT_TRUE(
utils::file::delete_directory_recursively(utils::path::combine(
EXPECT_TRUE(utils::file::remove_directory(
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)})));
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}),
true));
app_config src_cfg(
provider_type::sia,
@ -147,10 +149,11 @@ protected:
config.reset();
event_system::instance().stop();
EXPECT_TRUE(
utils::file::delete_directory_recursively(utils::path::combine(
EXPECT_TRUE(utils::file::remove_directory(
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)})));
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}),
true));
}
}
};

View File

@ -40,13 +40,15 @@ public:
void SetUp() override {
event_system::instance().start();
ASSERT_TRUE(utils::file::delete_directory_recursively(
utils::path::combine(test::get_test_output_dir(), {"config_test"})));
ASSERT_TRUE(utils::file::remove_directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}),
true));
}
void TearDown() override {
ASSERT_TRUE(utils::file::delete_directory_recursively(
utils::path::combine(test::get_test_output_dir(), {"config_test"})));
ASSERT_TRUE(utils::file::remove_directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}),
true));
event_system::instance().stop();
}
};

View File

@ -32,7 +32,7 @@ namespace repertory {
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose");
auto source_file = create_random_file(source_file_name, 1024UL);
auto &source_file = create_random_file(source_file_name, 1024UL);
EXPECT_TRUE(source_file != nullptr);
if (source_file) {
stop_type stop_requested = false;

View File

@ -171,8 +171,8 @@ TEST(open_file, will_change_source_path_if_file_size_is_greater_than_0) {
TEST(open_file,
will_not_change_source_path_if_file_size_matches_existing_source) {
auto rf = test::create_random_file(test_chunk_size);
const auto source_path = rf.get_path().string();
auto &rf = test::create_random_file(test_chunk_size);
const auto source_path = rf.get_path();
rf.close();
mock_provider mp;
@ -197,7 +197,7 @@ TEST(open_file,
TEST(open_file, write_with_incomplete_download) {
const auto source_path = test::generate_test_file_name("test");
auto nf = test::create_random_file(test_chunk_size * 2u);
auto &nf = test::create_random_file(test_chunk_size * 2u);
mock_provider mp;
mock_upload_manager um;
@ -449,8 +449,8 @@ TEST(open_file, write_new_file_multiple_chunks) {
}
TEST(open_file, resize_file_to_0_bytes) {
auto rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path().string();
auto &rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path();
rf.close();
mock_provider mp;
@ -499,8 +499,8 @@ TEST(open_file, resize_file_to_0_bytes) {
}
TEST(open_file, resize_file_by_full_chunk) {
auto rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path().string();
auto &rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path();
rf.close();
mock_provider mp;

View File

@ -61,7 +61,7 @@ TEST(ring_buffer_open_file, can_forward_to_last_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file,
@ -93,7 +93,7 @@ TEST(ring_buffer_open_file,
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, can_forward_after_last_chunk) {
@ -125,7 +125,7 @@ TEST(ring_buffer_open_file, can_forward_after_last_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) {
@ -153,7 +153,7 @@ TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) {
EXPECT_EQ(std::size_t(28u), rb.get_last_chunk());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, can_reverse_to_first_chunk) {
@ -184,7 +184,7 @@ TEST(ring_buffer_open_file, can_reverse_to_first_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file,
@ -216,7 +216,7 @@ TEST(ring_buffer_open_file,
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, can_reverse_before_first_chunk) {
@ -248,7 +248,7 @@ TEST(ring_buffer_open_file, can_reverse_before_first_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) {
@ -284,7 +284,7 @@ TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, can_reverse_full_ring) {
@ -316,12 +316,12 @@ TEST(ring_buffer_open_file, can_reverse_full_ring) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, read_full_file) {
auto nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string();
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
@ -352,7 +352,8 @@ TEST(ring_buffer_open_file, read_full_file) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
auto nf2 = utils::file::file::open_or_create_file(dest_path);
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto to_read = fsi.size;
@ -374,12 +375,12 @@ TEST(ring_buffer_open_file, read_full_file) {
utils::file::generate_sha256(dest_path).c_str());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, read_full_file_in_reverse) {
auto nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string();
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
@ -410,7 +411,8 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
auto nf2 = utils::file::file::open_or_create_file(dest_path);
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto to_read = fsi.size;
@ -432,12 +434,12 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
utils::file::generate_sha256(dest_path).c_str());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
auto nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string();
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("test");
@ -468,7 +470,8 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
auto nf2 = utils::file::file::open_or_create_file(dest_path);
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
// EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path,
// nf2));
@ -491,12 +494,12 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
utils::file::generate_sha256(dest_path).c_str());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
auto nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string();
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
@ -527,7 +530,8 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
auto nf2 = utils::file::file::open_or_create_file(dest_path);
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
std::uint64_t total_read{0U};
@ -555,6 +559,6 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
utils::file::generate_sha256(dest_path).c_str());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::remove_directory(ring_buffer_dir, true));
}
} // namespace repertory

View File

@ -84,7 +84,7 @@ TEST(file_manager, can_start_and_stop) {
}
event_system::instance().stop();
// EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
// EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_create_and_close_file) {
@ -201,7 +201,7 @@ TEST(file_manager, can_create_and_close_file) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_open_and_close_file) {
@ -317,7 +317,7 @@ TEST(file_manager, can_open_and_close_file) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
@ -390,7 +390,7 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
@ -425,7 +425,7 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u);
auto nf =
auto &nf =
test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item)
@ -543,7 +543,7 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
@ -586,7 +586,7 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u);
auto nf =
auto &nf =
test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item)
@ -660,11 +660,11 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_evict_file) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
console_consumer c;
event_system::instance().start();
@ -765,11 +765,11 @@ TEST(file_manager, can_evict_file) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_file_is_pinned) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false);
@ -791,11 +791,11 @@ TEST(file_manager, evict_file_fails_if_file_is_pinned) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_provider_is_direct_only) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -807,11 +807,11 @@ TEST(file_manager, evict_file_fails_if_provider_is_direct_only) {
EXPECT_FALSE(fm.evict_file("/test.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_file_is_open) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -857,12 +857,12 @@ TEST(file_manager, evict_file_fails_if_file_is_open) {
fm.close(handle);
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager,
evict_file_fails_if_unable_to_get_source_path_from_item_meta) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -892,11 +892,11 @@ TEST(file_manager,
EXPECT_FALSE(fm.evict_file("/test_open.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_source_path_is_empty) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -926,11 +926,11 @@ TEST(file_manager, evict_file_fails_if_source_path_is_empty) {
EXPECT_FALSE(fm.evict_file("/test_open.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_file_is_uploading) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
console_consumer c;
event_system::instance().start();
@ -1021,11 +1021,11 @@ TEST(file_manager, evict_file_fails_if_file_is_uploading) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1046,11 +1046,11 @@ TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_file_is_modified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1092,11 +1092,11 @@ TEST(file_manager, evict_file_fails_if_file_is_modified) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, evict_file_fails_if_file_is_not_complete) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1140,11 +1140,11 @@ TEST(file_manager, evict_file_fails_if_file_is_not_complete) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_get_directory_items) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1174,11 +1174,11 @@ TEST(file_manager, can_get_directory_items) {
EXPECT_EQ(std::size_t(2U), list.size());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1210,11 +1210,11 @@ TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1241,12 +1241,12 @@ TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, get_open_file_fails_if_file_is_not_open) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1265,12 +1265,12 @@ TEST(file_manager, get_open_file_fails_if_file_is_not_open) {
EXPECT_FALSE(f);
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager,
get_open_file_promotes_non_writeable_file_if_writeable_is_specified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1350,11 +1350,11 @@ TEST(file_manager,
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, open_file_fails_if_file_is_not_found) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1375,11 +1375,11 @@ TEST(file_manager, open_file_fails_if_file_is_not_found) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1419,11 +1419,11 @@ TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1470,11 +1470,11 @@ TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, open_file_creates_source_path_if_empty) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1533,11 +1533,11 @@ TEST(file_manager, open_file_creates_source_path_if_empty) {
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, open_file_first_file_handle_is_not_zero) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1581,11 +1581,11 @@ TEST(file_manager, open_file_first_file_handle_is_not_zero) {
EXPECT_GT(handle, std::uint64_t(0U));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_remove_file) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1596,9 +1596,10 @@ TEST(file_manager, can_remove_file) {
file_manager fm(cfg, mp);
{
auto file = utils::file::file::open_or_create_file("./test_remove.txt");
EXPECT_TRUE(file);
file.close();
EXPECT_TRUE(*file);
}
EXPECT_TRUE(utils::file::is_file("./test_remove.txt"));
EXPECT_CALL(mp, get_filesystem_item)
@ -1621,11 +1622,11 @@ TEST(file_manager, can_remove_file) {
EXPECT_FALSE(utils::file::is_file("./test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_queue_and_remove_upload) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
console_consumer c;
event_system::instance().start();
@ -1656,11 +1657,11 @@ TEST(file_manager, can_queue_and_remove_upload) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, remove_file_fails_if_open_file_is_modified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1710,7 +1711,7 @@ TEST(file_manager, remove_file_fails_if_open_file_is_modified) {
EXPECT_EQ(api_error::file_in_use, fm.remove_file("/test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, file_is_closed_after_download_timeout) {
@ -1808,11 +1809,11 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, remove_file_fails_if_file_does_not_exist) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false);
@ -1833,11 +1834,11 @@ TEST(file_manager, remove_file_fails_if_file_does_not_exist) {
EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
{
app_config cfg(provider_type::sia, file_manager_dir);
@ -1865,6 +1866,6 @@ TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) {
EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
} // namespace repertory

View File

@ -516,12 +516,12 @@ TEST(fuse_drive, all_tests) {
const auto test_directory = utils::path::combine(
test::get_test_output_dir(), {"fuse_drive" + std::to_string(idx)});
EXPECT_TRUE(utils::file::delete_directory_recursively(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory, true));
const auto mount_location =
utils::path::combine(test_directory, {"mount", std::to_string(idx)});
EXPECT_TRUE(utils::file::create_full_directory_path(mount_location));
EXPECT_TRUE(utils::file::create_directories(mount_location));
{
std::unique_ptr<app_config> config_ptr{};
std::unique_ptr<curl_comm> comm_ptr{};
@ -529,7 +529,7 @@ TEST(fuse_drive, all_tests) {
const auto cfg_directory =
utils::path::combine(test_directory, {"cfg", std::to_string(idx)});
EXPECT_TRUE(utils::file::create_full_directory_path(cfg_directory));
EXPECT_TRUE(utils::file::create_directories(cfg_directory));
std::vector<std::string> drive_args{};

View File

@ -120,7 +120,7 @@ const auto create_file = [](repertory::i_provider &provider,
EXPECT_EQ(repertory::api_error::success, provider.is_file(api_path, exists));
EXPECT_TRUE(exists);
EXPECT_TRUE(repertory::utils::file::delete_file(source_path));
EXPECT_TRUE(repertory::utils::file::file{source_path}.remove());
repertory::api_meta_map meta2{};
EXPECT_EQ(repertory::api_error::success,
@ -630,7 +630,7 @@ static void run_tests(const app_config &cfg, i_provider &provider) {
TEST(providers, encrypt_provider) {
const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"encrypt_provider"});
ASSERT_TRUE(utils::file::delete_directory_recursively(config_path));
ASSERT_TRUE(utils::file::remove_directory(config_path, true));
console_consumer consumer{};
event_system::instance().start();
@ -673,7 +673,7 @@ TEST(providers, encrypt_provider) {
TEST(providers, s3_provider) {
const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"s3_provider"});
ASSERT_TRUE(utils::file::delete_directory_recursively(config_path));
ASSERT_TRUE(utils::file::remove_directory(config_path, true));
console_consumer consumer{};
event_system::instance().start();
@ -712,7 +712,7 @@ TEST(providers, s3_provider) {
TEST(providers, sia_provider) {
const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"sia_provider"});
ASSERT_TRUE(utils::file::delete_directory_recursively(config_path));
ASSERT_TRUE(utils::file::remove_directory(config_path, true));
console_consumer consumer{};
event_system::instance().start();

View File

@ -434,7 +434,7 @@ static void mkdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"mkdir_test"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
@ -443,7 +443,7 @@ static void mkdir_test(repertory::remote_fuse::remote_client &client) {
#endif
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
}
static void open_test(repertory::remote_fuse::remote_client &client) {
@ -479,7 +479,7 @@ opendir_and_releasedir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"opendir_and_release_dir"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
@ -492,7 +492,7 @@ opendir_and_releasedir_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_opendir(api_path.c_str(), handle));
EXPECT_EQ(0, client.fuse_releasedir(api_path.c_str(), handle));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
}
static void read_and_write_test(repertory::remote_fuse::remote_client &client) {
@ -551,7 +551,7 @@ static void readdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"readdir_test"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
@ -572,7 +572,7 @@ static void readdir_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_releasedir(api_path.c_str(), handle));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
}
/*static void removexattr_test(repertory::remote_fuse::remote_client &client) {
@ -633,7 +633,7 @@ static void rmdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"rmdir_test"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
@ -645,7 +645,7 @@ static void rmdir_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_rmdir(api_path.c_str()));
EXPECT_FALSE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
}
static void setattr_x_test(repertory::remote_fuse::remote_client &client) {
@ -934,11 +934,11 @@ TEST(remote_fuse, all_tests) {
event_system::instance().start();
#if defined(_WIN32)
mount_location_ = test::get_test_output_dir().substr(0, 2);
mount_location_ = fuse_remote_dir.substr(0, 2);
mock_winfsp_drive drive(mount_location_);
remote_server server(config, drive, mount_location_);
#else
mount_location_ = utils::path::absolute(".");
mount_location_ = fuse_remote_dir;
mock_fuse_drive drive(mount_location_);
remote_server server(config, drive, mount_location_);
#endif
@ -990,6 +990,6 @@ TEST(remote_fuse, all_tests) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(fuse_remote_dir));
EXPECT_TRUE(utils::file::remove_directory(fuse_remote_dir, true));
}
} // namespace fuse_test

View File

@ -49,7 +49,8 @@ static void can_delete_test(remote_client &client) {
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
auto nf = utils::file::file::open_or_create_file(test_file);
auto ptr = utils::file::file::open_or_create_file(test_file);
auto &nf = *ptr;
EXPECT_TRUE(nf);
if (nf) {
EXPECT_EQ(STATUS_INVALID_HANDLE,
@ -264,7 +265,7 @@ static void overwrite_test(remote_client &client) {
static void create_and_read_directory_test(remote_client &client) {
const auto test_directory =
utils::path::combine(win_remote_dir, {"read_directory"});
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
auto api_path =
utils::string::from_utf8(test_directory).substr(mount_location_.size());
@ -286,13 +287,13 @@ static void create_and_read_directory_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
}
static void open_and_read_directory_test(remote_client &client) {
const auto test_directory =
utils::path::combine(win_remote_dir, {"open_and_read_directory"});
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
auto api_path =
utils::string::from_utf8(test_directory).substr(mount_location_.size());
@ -322,7 +323,7 @@ static void open_and_read_directory_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::remove_directory(test_directory));
}
static void read_and_write_test(remote_client &client) {
@ -500,11 +501,11 @@ TEST(remote_winfsp, all_tests) {
event_system::instance().start();
#if defined(_WIN32)
mount_location_ = test::get_test_output_dir().substr(0, 2);
mount_location_ = win_remote_dir.substr(0, 2);
mock_winfsp_drive drive(mount_location_);
remote_server server(config, drive, mount_location_);
#else
mount_location_ = utils::path::absolute(".");
mount_location_ = win_remote_dir;
mock_fuse_drive drive(mount_location_);
remote_fuse::remote_server server(config, drive, mount_location_);
#endif
@ -534,6 +535,6 @@ TEST(remote_winfsp, all_tests) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(win_remote_dir));
EXPECT_TRUE(utils::file::remove_directory(win_remote_dir, true));
}
} // namespace winfsp_test

View File

@ -40,6 +40,7 @@ done
PROJECT_APP_LIST=()
PROJECT_CMAKE_OPTS=""
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_IS_ALPINE=0
PROJECT_IS_ARM64=0
PROJECT_MINGW64_COPY_DEPENDENCIES=()
@ -73,6 +74,10 @@ fi
. "${PROJECT_SOURCE_DIR}/config.sh"
if [ "${PROJECT_IS_MINGW}" == "0" ]; then
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
fi
if [ "${PROJECT_ENABLE_SFML}" == "ON" ]; then
PROJECT_ENABLE_FLAC=ON
PROJECT_ENABLE_FONTCONFIG=ON
@ -223,6 +228,7 @@ PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_DIR=${PROJECT_BUILD_DIR} ${PROJECT_CMAKE_OPT
PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_CMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_EXTERNAL_BUILD_ROOT=${PROJECT_EXTERNAL_BUILD_ROOT} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_GIT_REV=${PROJECT_GIT_REV} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE} ${PROJECT_CMAKE_OPTS}"
@ -288,6 +294,7 @@ export PROJECT_COMPANY_NAME
export PROJECT_COPYRIGHT
export PROJECT_DESC
export PROJECT_DIST_DIR
export PROJECT_ENABLE_WIN32_LONG_PATH_NAMES
export PROJECT_FILE_PART
export PROJECT_GIT_REV
export PROJECT_IS_ALPINE
@ -346,6 +353,9 @@ echo " Is MINGW on Unix: ${PROJECT_IS_MINGW_UNIX}"
echo " Is MINGW: ${PROJECT_IS_MINGW}"
echo " Job count: ${NUM_JOBS}"
echo " Link type: ${PROJECT_LINK_TYPE}"
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
echo " Long path names: ${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}"
fi
echo " Meson toolchain file: ${PROJECT_TOOLCHAIN_FILE_MESON}"
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then
echo " MinGW docker build args: ${PROJECT_MINGW64_DOCKER_BUILD_ARGS}"

View File

@ -307,8 +307,15 @@ using unique_mutex_lock = std::unique_lock<std::mutex>;
using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
#if defined(_WIN32)
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
inline constexpr const auto max_path_length = std::size_t{32767U};
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
inline constexpr const auto max_path_length = std::size_t{MAX_PATH};
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
using native_handle = HANDLE;
#else // !defined(_WIN32)
inline constexpr const auto max_path_length = std::size_t{PATH_MAX};
using native_handle = int;
#if !defined(INVALID_HANDLE_VALUE)
#define INVALID_HANDLE_VALUE (-1)

View File

@ -65,7 +65,7 @@ private:
utils::encryption::hash_256_t key_;
stop_type &stop_requested_;
size_t error_return_;
utils::file::file source_file_;
std::unique_ptr<utils::file::i_file> source_file_;
private:
std::unordered_map<std::size_t, data_buffer> chunk_buffers_;

View File

@ -24,104 +24,362 @@
#include "utils/config.hpp"
#include "utils/path.hpp"
#include <memory>
namespace repertory::utils::file {
class file final {
struct i_file {
virtual ~i_file() = default;
virtual void close() = 0;
[[nodiscard]] virtual auto exists() const -> bool = 0;
virtual void flush() const = 0;
[[nodiscard]] virtual auto get_handle() const -> native_handle = 0;
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
[[nodiscard]] virtual auto get_read_buffer_size() const -> std::uint32_t = 0;
[[nodiscard]] virtual auto is_read_only() const -> bool = 0;
[[nodiscard]] virtual auto move_to(std::string_view new_path) -> bool = 0;
[[nodiscard]] virtual auto
read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool = 0;
[[nodiscard]] virtual auto
read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool = 0;
[[nodiscard]] virtual auto
read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool = 0;
[[nodiscard]] virtual auto remove() -> bool = 0;
virtual auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t = 0;
[[nodiscard]] virtual auto size() const -> std::uint64_t = 0;
[[nodiscard]] virtual auto truncate() -> bool = 0;
[[nodiscard]] virtual auto truncate(std::size_t size) -> bool = 0;
[[nodiscard]] virtual auto
write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool = 0;
[[nodiscard]] virtual auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool = 0;
public:
[[nodiscard]] static auto attach_file(native_handle handle,
bool read_only = false) -> file;
[[nodiscard]] virtual operator bool() const = 0;
[[nodiscard]] static auto open_file(std::filesystem::path path,
bool read_only = false) -> file;
protected:
i_file() noexcept = default;
[[nodiscard]] static auto open_or_create_file(std::filesystem::path path,
bool read_only = false) -> file;
i_file(const i_file &) noexcept = delete;
i_file(i_file &&) noexcept = delete;
auto operator=(i_file &&) noexcept -> i_file & = delete;
auto operator=(const i_file &) noexcept -> i_file & = delete;
};
class file final : public i_file {
public:
[[nodiscard]] static auto
attach_file(native_handle handle,
bool read_only = false) -> std::unique_ptr<i_file>;
[[nodiscard]] static auto
open_file(std::string_view path,
bool read_only = false) -> std::unique_ptr<i_file>;
[[nodiscard]] static auto
open_file(std::wstring_view path,
bool read_only = false) -> std::unique_ptr<i_file> {
return open_file(utils::string::to_utf8(path), read_only);
}
[[nodiscard]] static auto
open_or_create_file(std::string_view path,
bool read_only = false) -> std::unique_ptr<i_file>;
[[nodiscard]] static auto
open_or_create_file(std::wstring_view path,
bool read_only = false) -> std::unique_ptr<i_file> {
return open_or_create_file(utils::string::to_utf8(path), read_only);
}
public:
file() noexcept = default;
protected:
file(file_t file_ptr, std::filesystem::path path)
: file_(std::move(file_ptr)), path_(std::move(path)) {}
file(std::string_view path)
: file_(nullptr), path_(utils::path::absolute(path)) {}
file(std::wstring_view path)
: file_(nullptr),
path_(utils::path::absolute(utils::string::to_utf8(path))) {}
private:
file(file_t file_ptr, std::string_view path, bool read_only)
: file_(std::move(file_ptr)), path_(path), read_only_(read_only) {}
public:
file(const file &) = delete;
file(file &&move_file) noexcept
: file_(std::move(move_file.file_)),
path_(std::move(move_file.path_))
path_(std::move(move_file.path_)),
read_only_(move_file.read_only_)
#if defined(_WIN32)
,
mtx_()
mtx_(std::move(move_file.mtx_))
#endif // defined(_WIN32)
{
}
~file() { close(); }
~file() override { close(); }
private:
file_t file_;
std::string path_;
bool read_only_{false};
#if defined(_WIN32)
mutable std::unique_ptr<std::recursive_mutex> mtx_{
new std::recursive_mutex(),
};
#endif // defined(_WIN32)
private:
std::atomic_uint32_t read_buffer_size{65536U};
private:
void open();
public:
void close() override;
[[nodiscard]] auto exists() const -> bool override;
void flush() const override;
[[nodiscard]] auto get_handle() const -> native_handle override;
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
return read_buffer_size;
}
[[nodiscard]] auto is_read_only() const -> bool override {
return read_only_;
};
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto
read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto remove() -> bool override;
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
read_buffer_size = size;
return read_buffer_size;
}
[[nodiscard]] auto size() const -> std::uint64_t override;
[[nodiscard]] auto truncate() -> bool override { return truncate(0U); }
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
[[nodiscard]] auto
write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool override;
[[nodiscard]] auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool override;
public:
auto operator=(const file &) noexcept -> file & = delete;
auto operator=(file &&move_file) noexcept -> file & {
if (&move_file != this) {
file_ = std::move(move_file.file_);
path_ = std::move(move_file.path_);
read_only_ = move_file.read_only_;
#if defined(_WIN32)
mtx_ = std::move(move_file.mtx_);
#endif // defined(_WIN32)
}
return *this;
}
private:
file_t file_{nullptr};
std::filesystem::path path_;
#if defined(_WIN32)
mutable std::recursive_mutex mtx_{};
#endif // defined(_WIN32)
[[nodiscard]] operator bool() const override { return file_ != nullptr; }
};
class thread_file final : public i_file {
public:
[[nodiscard]] static auto
attach_file(native_handle handle,
bool read_only = false) -> std::unique_ptr<i_file>;
[[nodiscard]] static auto
open_file(std::string_view path,
bool read_only = false) -> std::unique_ptr<i_file>;
[[nodiscard]] static auto
open_file(std::wstring_view path,
bool read_only = false) -> std::unique_ptr<i_file> {
return open_file(utils::string::to_utf8(path), read_only);
}
[[nodiscard]] static auto
open_or_create_file(std::string_view path,
bool read_only = false) -> std::unique_ptr<i_file>;
[[nodiscard]] static auto
open_or_create_file(std::wstring_view path,
bool read_only = false) -> std::unique_ptr<i_file> {
return open_or_create_file(utils::string::to_utf8(path), read_only);
}
public:
void close();
thread_file() noexcept = default;
void flush();
thread_file(std::string_view path) : file_(new file(path)) {}
[[nodiscard]] auto get_handle() const -> native_handle;
thread_file(std::wstring_view path)
: file_(new file(utils::string::to_utf8(path))) {}
[[nodiscard]] auto get_path() const -> std::filesystem::path { return path_; }
protected:
thread_file(std::unique_ptr<i_file> file);
[[nodiscard]] auto move_to(std::filesystem::path new_path) -> bool;
public:
thread_file(const thread_file &) = delete;
thread_file(thread_file &&move_file) noexcept
: file_(std::move(move_file.file_)) {}
~thread_file() override { close(); }
private:
std::unique_ptr<i_file> file_;
public:
void close() override;
[[nodiscard]] auto exists() const -> bool override { return file_->exists(); }
void flush() const override;
[[nodiscard]] auto get_handle() const -> native_handle override {
return file_->get_handle();
}
[[nodiscard]] auto get_path() const -> std::string override {
return file_->get_path();
}
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
return file_->get_read_buffer_size();
}
[[nodiscard]] auto is_read_only() const -> bool override {
return file_->is_read_only();
};
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool;
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool;
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool;
[[nodiscard]] auto
read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto remove() -> bool;
[[nodiscard]] auto remove() -> bool override;
[[nodiscard]] auto size() const -> std::uint64_t;
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
return file_->set_read_buffer_size(size);
}
[[nodiscard]] auto truncate() -> bool { return truncate(0U); }
[[nodiscard]] auto size() const -> std::uint64_t override;
[[nodiscard]] auto truncate(std::size_t size) -> bool;
[[nodiscard]] auto truncate() -> bool override { return truncate(0U); }
[[nodiscard]] auto write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool;
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
[[nodiscard]] auto write(const unsigned char *data, std::size_t to_write,
std::size_t offset,
std::size_t *total_written = nullptr) -> bool;
[[nodiscard]] auto
write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool override;
[[nodiscard]] auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool override;
public:
[[nodiscard]] operator bool() const { return file_ != nullptr; }
[[nodiscard]] operator bool() const override {
return static_cast<bool>(*file_);
}
auto operator=(const file &) noexcept -> thread_file & = delete;
auto operator=(thread_file &&move_file) noexcept -> thread_file & {
if (&move_file != this) {
file_ = std::move(move_file.file_);
}
return *this;
}
};
[[nodiscard]] auto create_directories(std::string_view path) -> bool;
[[nodiscard]] auto create_directories(std::wstring_view path) -> bool;
[[nodiscard]] auto
directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool;
[[nodiscard]] auto
directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool;
[[nodiscard]] auto get_file_size(std::string_view path,
std::uint64_t &file_size) -> bool;
[[nodiscard]] auto get_file_size(std::wstring_view path,
std::uint64_t &file_size) -> bool;
[[nodiscard]] auto file_exists_in_path(std::string_view path,
std::string_view file_name) -> bool;
[[nodiscard]] auto file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool;
[[nodiscard]] auto is_directory(std::string_view path) -> bool;
[[nodiscard]] auto is_directory(std::wstring_view path) -> bool;
@ -130,6 +388,12 @@ public:
[[nodiscard]] auto is_file(std::wstring_view path) -> bool;
[[nodiscard]] auto remove_directory(std::string_view path,
bool recursive = false) -> bool;
[[nodiscard]] auto remove_directory(std::wstring_view path,
bool recursive = false) -> bool;
#if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto
@ -161,6 +425,21 @@ read_json_file(std::string_view path, nlohmann::json &data,
const nlohmann::json &data) -> bool;
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#endif // defined(PROJECT_ENABLE_JSON)
template <typename string_t>
inline auto directory_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> sub_directory)
-> bool {
return is_directory(utils::path::combine(path, {sub_directory}));
}
template <typename string_t>
inline auto file_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> file_name) -> bool {
return is_file(utils::path::combine(path, {file_name}));
}
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_HPP_

View File

@ -30,8 +30,12 @@ inline constexpr const std::string_view backslash{"\\"};
inline constexpr const std::wstring_view backslash_w{L"\\"};
inline constexpr const std::string_view dot{"."};
inline constexpr const std::wstring_view dot_w{L"."};
inline constexpr const std::string_view dot_backslash{".\\"};
inline constexpr const std::wstring_view dot_backslash_w{L".\\"};
inline constexpr const std::string_view dot_slash{"./"};
inline constexpr const std::wstring_view dot_slash_w{L"./"};
inline constexpr const std::string_view long_notation{"\\\\?\\"};
inline constexpr const std::wstring_view long_notation_w{L"\\\\?\\"};
inline constexpr const std::string_view slash{"/"};
inline constexpr const std::wstring_view slash_w{L"/"};
#if defined(_WIN32)
@ -62,53 +66,6 @@ get_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
return backslash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto get_dot() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot<char>() -> std::basic_string_view<char> {
return dot;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<char>() -> std::basic_string_view<char> {
return dot_slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_slash<char>() -> std::basic_string_view<char> {
return slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_directory_seperator() -> std::basic_string_view<char_t>;
@ -141,16 +98,98 @@ get_not_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
return not_directory_seperator_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto get_dot() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot<char>() -> std::basic_string_view<char> {
return dot;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_backslash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_backslash<char>() -> std::basic_string_view<char> {
return dot_backslash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_backslash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<char>() -> std::basic_string_view<char> {
return dot_slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_long_notation() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_long_notation<char>() -> std::basic_string_view<char> {
return long_notation;
}
template <>
[[nodiscard]] inline constexpr auto
get_long_notation<wchar_t>() -> std::basic_string_view<wchar_t> {
return long_notation_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_slash<char>() -> std::basic_string_view<char> {
return slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return slash_w;
}
template <typename string_t>
[[nodiscard]] inline auto get_current_path() -> string_t;
[[nodiscard]] auto absolute(std::string_view path) -> std::string;
[[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
combine(std::string path,
combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string;
[[nodiscard]] inline auto
combine(std::wstring path,
combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring;
[[nodiscard]] auto inline create_api_path(std::string_view path) -> std::string;
@ -158,27 +197,12 @@ combine(std::wstring path,
[[nodiscard]] auto inline create_api_path(std::wstring_view path)
-> std::wstring;
[[nodiscard]] inline auto
directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool;
[[nodiscard]] inline auto
directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool;
[[nodiscard]] inline auto
file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
[[nodiscard]] inline auto
file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool;
[[nodiscard]] inline auto finalize(std::string_view path) -> std::string;
[[nodiscard]] inline auto finalize(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto
find_program_in_path(const std::string &name_without_extension) -> std::string;
[[nodiscard]] auto find_program_in_path(
const std::string_view &name_without_extension) -> std::string;
[[nodiscard]] auto
find_program_in_path(std::wstring_view name_without_extension) -> std::wstring;
@ -208,10 +232,6 @@ get_parent_api_path(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto make_file_uri(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto remove_file_name(std::string_view path) -> std::string;
[[nodiscard]] auto remove_file_name(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto strip_to_file_name(std::string path) -> std::string;
[[nodiscard]] auto strip_to_file_name(std::wstring path) -> std::wstring;
@ -222,31 +242,30 @@ get_parent_api_path(std::wstring_view path) -> std::wstring;
template <typename string_t>
[[nodiscard]] inline auto combine_t(
string_t path,
std::basic_string_view<typename string_t::value_type> path,
const std::vector<std::basic_string_view<typename string_t::value_type>>
&paths) -> string_t {
path = std::accumulate(
paths.begin(), paths.end(), path, [](auto next_path, auto &&path_part) {
auto dir_sep_t =
string_t{get_directory_seperator<typename string_t::value_type>()};
return absolute(
std::accumulate(paths.begin(), paths.end(),
std::basic_string<typename string_t::value_type>{path},
[&dir_sep_t](auto next_path, auto &&path_part) {
if (next_path.empty()) {
return string_t{path_part};
}
return next_path +
string_t{
get_directory_seperator<typename string_t::value_type>()} +
string_t{path_part};
});
return absolute(path);
return next_path + dir_sep_t + string_t{path_part};
}));
}
inline auto combine(std::string path,
inline auto combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string {
return combine_t<std::string>(path, paths);
}
inline auto
combine(std::wstring path,
combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring {
return combine_t<std::wstring>(path, paths);
}
@ -255,12 +274,20 @@ template <typename string_t>
[[nodiscard]] inline auto create_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
auto backslash_t = get_backslash<typename string_t::value_type>();
auto dot_t = get_dot<typename string_t::value_type>();
auto dot_backslash_t = get_dot_backslash<typename string_t::value_type>();
auto dot_slash_t = get_dot_slash<typename string_t::value_type>();
auto dot_t = get_dot<typename string_t::value_type>();
auto slash_t = get_slash<typename string_t::value_type>();
#if defined(_WIN32)
auto long_notation_t = get_long_notation<typename string_t::value_type>();
if (utils::string::begins_with(path, long_notation_t)) {
path = path.substr(long_notation_t.size());
}
#endif // defined(_WIN32)
if (path.empty() || path == backslash_t || path == dot_t ||
path == dot_slash_t || path == slash_t) {
path == dot_slash_t || path == slash_t || path == dot_backslash_t) {
return string_t{slash_t};
}
@ -292,50 +319,52 @@ inline auto create_api_path(std::wstring_view path) -> std::wstring {
return create_api_path_t<std::wstring>(path);
}
template <typename string_t>
[[nodiscard]] inline auto directory_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> sub_directory)
-> bool {
return std::filesystem::is_directory(
std::filesystem::path(path).append(sub_directory));
}
inline auto directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool {
return directory_exists_in_path_t<std::string>(path, sub_directory);
}
inline auto directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool {
return directory_exists_in_path_t<std::wstring>(path, sub_directory);
}
template <typename string_t>
[[nodiscard]] inline auto file_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> file_name) -> bool {
return std::filesystem::is_regular_file(
std::filesystem::path(path).append(file_name));
}
inline auto file_exists_in_path(std::string_view path,
std::string_view file_name) -> bool {
return file_exists_in_path_t<std::string>(path, file_name);
}
inline auto file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool {
return file_exists_in_path_t<std::wstring>(path, file_name);
}
template <typename string_t>
[[nodiscard]] inline auto finalize_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
string_t dir_sep_t{get_directory_seperator<typename string_t::value_type>()};
string_t fmt_path{path};
format_path(fmt_path,
get_directory_seperator<typename string_t::value_type>(),
if (fmt_path.empty()) {
return fmt_path;
}
format_path(fmt_path, dir_sep_t,
get_not_directory_seperator<typename string_t::value_type>());
#if defined(_WIN32)
auto dot_t = get_dot<typename string_t::value_type>();
auto dot_sep_t = string_t{dot_t} + dir_sep_t;
if (fmt_path == dot_t || fmt_path == dot_sep_t) {
return get_current_path<string_t>();
}
if (fmt_path == dir_sep_t) {
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, long_notation.size() + 2U);
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, 2U);
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
}
if (utils::string::begins_with(fmt_path, dir_sep_t)) {
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, long_notation.size() + 2U) +
fmt_path;
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, 2U) + fmt_path;
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
}
if (utils::string::begins_with(fmt_path, dot_sep_t)) {
return get_current_path<string_t>() + dir_sep_t + fmt_path.substr(2U);
}
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return string_t{get_long_notation<typename string_t::value_type>()} +
fmt_path;
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
#endif // defined(_WIN32)
return fmt_path;
}
@ -355,6 +384,13 @@ format_path(string_t &path,
-> string_t & {
utils::string::replace(path, not_sep, sep);
#if defined(_WIN32)
auto long_notation_t = get_long_notation<typename string_t::value_type>();
if (utils::string::begins_with(path, long_notation_t)) {
path = path.substr(long_notation_t.size());
}
#endif // defined(_WIN32)
string_t double_sep(2U, sep.at(0U));
while (utils::string::contains(path, double_sep)) {
utils::string::replace(path, double_sep, sep);
@ -373,6 +409,24 @@ format_path(string_t &path,
return path;
}
template <>
[[nodiscard]] inline auto get_current_path<std::string>() -> std::string {
#if defined(_WIN32)
std::string path;
path.resize(repertory::max_path_length + 1);
::GetCurrentDirectoryA(static_cast<DWORD>(path.size()), path.data());
path = path.c_str();
return finalize(path);
#else // !defined(_WIN32)
return finalize(std::filesystem::current_path().string());
#endif // defined(_WIN32)
}
template <>
[[nodiscard]] inline auto get_current_path<std::wstring>() -> std::wstring {
return utils::string::from_utf8(get_current_path<std::string>());
}
template <typename string_t>
[[nodiscard]] inline auto get_parent_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
@ -383,12 +437,12 @@ template <typename string_t>
return ret;
}
ret = path.substr(0, path.rfind('/') + 1);
ret = path.substr(0, path.rfind(slash_t) + 1);
if (ret == slash_t) {
return ret;
}
return utils::string::right_trim(ret, '/');
return utils::string::right_trim(ret, slash_t.at(0U));
}
inline auto get_parent_api_path(std::string_view path) -> std::string {

View File

@ -178,7 +178,7 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested),
error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path});
}
@ -190,16 +190,18 @@ encrypting_reader::encrypting_reader(
encrypted_file_name_ = utils::collection::to_hex_string(result);
if (relative_parent_path.has_value()) {
for (auto &&part : std::filesystem::path(relative_parent_path.value())) {
for (auto &&part :
utils::string::split(relative_parent_path.value(),
utils::path::directory_seperator, false)) {
utils::encryption::encrypt_data(
key_, reinterpret_cast<const unsigned char *>(part.string().c_str()),
strnlen(part.string().c_str(), part.string().size()), result);
key_, reinterpret_cast<const unsigned char *>(part.c_str()),
strnlen(part.c_str(), part.size()), result);
encrypted_file_path_ += '/' + utils::collection::to_hex_string(result);
}
encrypted_file_path_ += '/' + encrypted_file_name_;
}
auto file_size = source_file_.size();
auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -225,16 +227,15 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
stop_requested_(stop_requested),
error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path});
}
encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ =
std::filesystem::path(encrypted_file_path_).filename().string();
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
auto file_size = source_file_.size();
auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -262,16 +263,15 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested),
error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path});
}
encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ =
std::filesystem::path(encrypted_file_path_).filename().string();
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
auto file_size = source_file_.size();
auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -289,7 +289,7 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
stop_requested_(reader.stop_requested_),
error_return_(reader.error_return_),
source_file_(
utils::file::file::open_file(reader.source_file_.get_path(), true)),
utils::file::file::open_file(reader.source_file_->get_path(), true)),
chunk_buffers_(reader.chunk_buffers_),
encrypted_file_name_(reader.encrypted_file_name_),
encrypted_file_path_(reader.encrypted_file_path_),
@ -298,9 +298,9 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
last_data_chunk_size_(reader.last_data_chunk_size_),
read_offset_(reader.read_offset_),
total_size_(reader.total_size_) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
source_file_.get_path().string());
source_file_->get_path());
}
}
@ -359,7 +359,7 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
chunk_buffer.resize(file_data.size() + encryption_header_size);
std::size_t bytes_read{};
if ((ret = source_file_.read(file_data, chunk * data_chunk_size_,
if ((ret = source_file_->read(file_data, chunk * data_chunk_size_,
&bytes_read))) {
utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data,
chunk_buffer);

View File

@ -26,13 +26,127 @@
#include "utils/path.hpp"
#include "utils/string.hpp"
namespace {
[[nodiscard]] auto remove_directory_recursively(std::string_view path) -> bool {
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
auto search = repertory::utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFileA(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
auto res{true};
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
res = remove_directory_recursively(
repertory::utils::path::combine(path, {fd.cFileName}));
}
} else {
res = repertory::utils::file::file(
repertory::utils::path::combine(path, {fd.cFileName}))
.remove();
}
} while (res && (::FindNextFileA(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(std::string{path}.c_str());
if (root != nullptr) {
auto res{true};
struct dirent *de{};
while (res && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
res = remove_directory_recursively(
repertory::utils::path::combine(path, {de->d_name}));
}
} else {
res = repertory::utils::file::file(
repertory::utils::path::combine(path, {de->d_name}))
.remove();
}
}
closedir(root);
}
#endif
return repertory::utils::file::remove_directory(path, false);
}
} // namespace
namespace repertory::utils::file {
auto create_directories(std::string_view path) -> bool {
#if defined(_WIN32)
return is_directory(path) ||
(::SHCreateDirectory(
nullptr,
utils::string::from_utf8(utils::path::absolute(path)).c_str()) ==
ERROR_SUCCESS);
#else // !defined(_WIN32)
auto ret{true};
auto paths = utils::string::split(utils::path::absolute(path),
utils::path::directory_seperator, false);
std::string current_path;
for (std::size_t idx = 0U; ret && (idx < paths.size()); idx++) {
if (paths.at(idx).empty()) {
current_path = utils::path::directory_seperator;
continue;
}
current_path = utils::path::combine(current_path, {paths.at(idx)});
auto status = mkdir(current_path.c_str(), S_IRWXU);
ret = ((status == 0) || (errno == EEXIST));
}
return ret;
#endif
}
auto create_directories(std::wstring_view path) -> bool {
return create_directories(utils::string::to_utf8(path));
}
auto directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool {
return directory_exists_in_path_t<std::string>(path, sub_directory);
}
auto directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool {
return directory_exists_in_path_t<std::wstring>(path, sub_directory);
}
auto file_exists_in_path(std::string_view path,
std::string_view file_name) -> bool {
return file_exists_in_path_t<std::string>(path, file_name);
}
auto file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool {
return file_exists_in_path_t<std::wstring>(path, file_name);
}
auto get_file_size(std::string_view path, std::uint64_t &file_size) -> bool {
auto abs_path = utils::path::absolute(path);
file_size = 0U;
#if defined(_WIN32)
struct _stat64 st {};
auto res = _stat64(std::string{path}.c_str(), &st);
if (res != 0) {
return false;
}
file_size = static_cast<std::uint64_t>(st.st_size);
return true;
#else // !defined(_WIN32)
std::error_code ec{};
file_size = std::filesystem::file_size(abs_path, ec);
return ec.value() == 0;
return (ec.value() == 0);
#endif // defined(_WIN32)
}
auto get_file_size(std::wstring_view path, std::uint64_t &file_size) -> bool {
@ -70,6 +184,23 @@ auto is_file(std::wstring_view path) -> bool {
return is_file(utils::string::to_utf8(path));
}
auto remove_directory(std::string_view path, bool recursive) -> bool {
auto abs_path = utils::path::absolute(path);
if (recursive) {
return remove_directory_recursively(abs_path);
}
#if defined(_WIN32)
return (not is_directory(abs_path) || ::RemoveDirectoryA(abs_path.c_str()));
#else // !defined(_WIN32)
return not is_directory(abs_path) || (rmdir(abs_path.c_str()) == 0);
#endif // defined(_WIN32)
}
auto remove_directory(std::wstring_view path, bool recursive) -> bool {
return remove_directory(utils::string::to_utf8(path), recursive);
}
#if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::string_view path, nlohmann::json &data,
@ -84,13 +215,13 @@ auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
try {
auto abs_path = utils::path::absolute(path);
auto file = file::open_file(abs_path);
if (not file) {
if (not *file) {
return false;
}
try {
data_buffer buffer{};
if (not file.read_all(buffer, 0U)) {
if (not file->read_all(buffer, 0U)) {
return false;
}
@ -141,7 +272,7 @@ auto write_json_file(std::string_view path,
try {
auto file = file::open_or_create_file(path);
if (not file.truncate()) {
if (not file->truncate()) {
throw std::runtime_error("failed to truncate file");
}
@ -153,12 +284,13 @@ auto write_json_file(std::string_view path,
utils::encryption::encrypt_data(
*password, reinterpret_cast<const unsigned char *>(str_data.c_str()),
str_data.size(), encrypted_data);
return file.write(encrypted_data, 0U);
return file->write(encrypted_data, 0U);
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto json_str = data.dump();
return file.write(reinterpret_cast<const unsigned char *>(json_str.c_str()),
return file->write(
reinterpret_cast<const unsigned char *>(json_str.c_str()),
json_str.size(), 0U);
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);

View File

@ -27,7 +27,8 @@
#include "utils/string.hpp"
namespace repertory::utils::file {
auto file::attach_file(native_handle handle, bool read_only) -> file {
auto file::attach_file(native_handle handle,
bool read_only) -> std::unique_ptr<i_file> {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
@ -36,13 +37,12 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
std::string path;
#if defined(_WIN32)
path.resize(MAX_PATH + 1);
path.resize(repertory::max_path_length + 1);
::GetFinalPathNameByHandleA(handle, path.data(),
static_cast<DWORD>(path.size()),
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
#else // !defined(_WIN32)
path.resize(PATH_MAX + 1);
path.resize(repertory::max_path_length + 1);
#if defined(__APPLE__)
fcntl(handle, F_GETPATH, source_path.data());
@ -63,54 +63,60 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
auto *ptr = fdopen(handle, read_only ? "rb" : "rb+");
#endif // defined(_WIN32)
return file{
return std::unique_ptr<i_file>(new file{
file_t{ptr},
utils::path::absolute(path),
};
read_only,
});
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return {};
return nullptr;
}
auto file::open_file(std::filesystem::path path, bool read_only) -> file {
void file::open() {
if (not is_file(path_)) {
throw std::runtime_error("file not found: " + path_);
}
#if defined(_WIN32)
file_.reset(_fsopen(path_.c_str(), read_only_ ? "rb" : "rb+", _SH_DENYNO));
#else // !defined(_WIN32)
file_.reset(fopen(path_.c_str(), read_only_ ? "rb" : "rb+"));
#endif // defined(_WIN32)
}
auto file::open_file(std::string_view path,
bool read_only) -> std::unique_ptr<i_file> {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
path = utils::path::absolute(path.string());
if (not is_file(path.string())) {
throw std::runtime_error("file not found: " + path.string());
}
#if defined(_WIN32)
auto *ptr =
_fsopen(path.string().c_str(), read_only ? "rb" : "rb+", _SH_DENYNO);
#else // !defined(_WIN32)
auto *ptr = fopen(path.string().c_str(), read_only ? "rb" : "rb+");
#endif // defined(_WIN32)
return file{
file_t{ptr},
path,
auto *ptr = new file{
nullptr,
utils::path::absolute(path),
read_only,
};
auto new_file = std::unique_ptr<i_file>(ptr);
try {
ptr->open();
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return {};
return new_file;
}
auto file::open_or_create_file(std::filesystem::path path,
bool read_only) -> file {
path = utils::path::absolute(path.string());
if (not utils::file::is_file(path.string())) {
auto file::open_or_create_file(std::string_view path,
bool read_only) -> std::unique_ptr<i_file> {
auto abs_path = utils::path::absolute(path);
if (not is_file(abs_path)) {
#if defined(_WIN32)
int old_mode{};
_umask_s(077, &old_mode);
@ -119,36 +125,44 @@ auto file::open_or_create_file(std::filesystem::path path,
#endif // defined(_WIN32)
#if defined(_WIN32)
auto *ptr = _fsopen(path.string().c_str(), "ab+", _SH_DENYNO);
auto *ptr = _fsopen(abs_path.c_str(), "ab+", _SH_DENYNO);
#else // !defined(_WIN32)
auto *ptr = fopen(path.string().c_str(), "ab+");
auto *ptr = fopen(abs_path.c_str(), "ab+");
#endif // defined(_WIN32)
if (ptr != nullptr) {
fclose(ptr);
}
#if defined(_WIN32)
_umask_s(old_mode, nullptr);
#else // !defined(_WIN32)
umask(old_mode);
#endif // defined(_WIN32)
if (ptr != nullptr) {
fclose(ptr);
}
}
return open_file(path, read_only);
return open_file(abs_path, read_only);
}
void file::close() {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
file_.reset();
}
void file::flush() {
auto file::exists() const -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
return is_file(path_);
}
void file::flush() const {
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (file_) {
@ -157,6 +171,10 @@ void file::flush() {
}
auto file::get_handle() const -> native_handle {
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (file_) {
#if defined(_WIN32)
return reinterpret_cast<native_handle>(
@ -169,12 +187,16 @@ auto file::get_handle() const -> native_handle {
return INVALID_HANDLE_VALUE;
}
auto file::move_to(std::filesystem::path new_path) -> bool {
auto file::move_to(std::string_view path) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
new_path = utils::path::absolute(new_path.string());
auto abs_path = utils::path::absolute(path);
auto reopen{false};
if (file_) {
@ -182,19 +204,29 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
close();
}
auto success{false};
#if defined(_WIN32)
success = !!::MoveFileExA(path_.c_str(), abs_path.c_str(),
MOVEFILE_REPLACE_EXISTING);
#else // !// defined(_WIN32)
std::error_code ec{};
std::filesystem::rename(path_, new_path, ec);
if (not ec) {
path_ = new_path;
if (reopen) {
*this = open_file(path_);
}
std::filesystem::rename(path_, abs_path, ec);
success = ec.value() == 0;
#endif // defined(_WIN32)
return true;
if (success) {
path_ = abs_path;
}
if (reopen) {
*this = open_file(path_);
try {
open();
return success;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
}
return false;
@ -203,11 +235,11 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
auto file::read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
data_buffer buffer;
buffer.resize(65536U);
buffer.resize(read_buffer_size);
std::size_t current_read{};
while (read(reinterpret_cast<unsigned char *>(buffer.data()),
@ -237,7 +269,7 @@ auto file::read_all(data_buffer &data, std::uint64_t offset,
auto file::read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
std::size_t bytes_read{};
@ -255,14 +287,14 @@ auto file::read(data_buffer &data, std::uint64_t offset,
auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
std::size_t *total_read) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
#endif // defined(_WIN32)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (total_read != nullptr) {
(*total_read) = 0U;
}
@ -298,18 +330,30 @@ auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
auto file::remove() -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
close();
if (not exists()) {
return true;
}
#if defined(_WIN32)
return !!::DeleteFileA(path_.c_str());
#else // !defined(_WIN32)
std::error_code ec{};
return std::filesystem::remove(path_, ec);
#endif // defined(_WIN32)
}
auto file::truncate(std::size_t size) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
auto reopen{false};
@ -320,23 +364,34 @@ auto file::truncate(std::size_t size) -> bool {
std::error_code ec{};
std::filesystem::resize_file(path_, size, ec);
auto success{ec.value() == 0};
if (reopen) {
*this = open_file(path_);
try {
open();
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
success = false;
} catch (...) {
utils::error::handle_exception(function_name);
success = false;
}
}
return ec.value() == 0;
return success;
}
auto file::write(const unsigned char *data, std::size_t to_write,
std::size_t offset, std::size_t *total_written) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
#endif // defined(_WIN32)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (total_written != nullptr) {
(*total_written) = 0U;
}
@ -374,14 +429,14 @@ auto file::write(const unsigned char *data, std::size_t to_write,
}
auto file::size() const -> std::uint64_t {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
#endif // defined(_WIN32)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
try {
if (file_) {
if (fseeko(file_.get(), 0, SEEK_END) == -1) {
@ -395,6 +450,13 @@ auto file::size() const -> std::uint64_t {
return static_cast<std::uint64_t>(size);
}
std::uint64_t size{};
if (not get_file_size(path_, size)) {
throw std::runtime_error("failed to get file size");
}
return size;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {

View File

@ -0,0 +1,64 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/file.hpp"
namespace repertory::utils::file {
auto thread_file::attach_file(native_handle handle,
bool read_only) -> std::unique_ptr<i_file> {}
auto thread_file::open_file(std::string_view path,
bool read_only) -> std::unique_ptr<i_file> {}
auto thread_file::open_or_create_file(std::string_view path, bool read_only)
-> std::unique_ptr<i_file> {}
thread_file::thread_file(std::unique_ptr<i_file> file)
: file_(std::move(file)) {}
void thread_file::close() {}
void thread_file::flush() const {}
auto thread_file::move_to(std::string_view path) -> bool {}
auto thread_file::read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {}
auto thread_file::read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {}
auto thread_file::read(unsigned char *data, std::size_t to_read,
std::uint64_t offset, std::size_t *total_read) -> bool {}
auto thread_file::remove() -> bool {}
auto thread_file::truncate(std::size_t size) -> bool {}
auto thread_file::write(const unsigned char *data, std::size_t to_write,
std::size_t offset,
std::size_t *total_written) -> bool {}
auto thread_file::size() const -> std::uint64_t {}
auto thread_file::write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written) -> bool {}
} // namespace repertory::utils::file

View File

@ -23,18 +23,11 @@
#include "utils/common.hpp"
#include "utils/error.hpp"
#include "utils/file.hpp"
#include "utils/string.hpp"
#include "utils/unix.hpp"
namespace {
static const std::string directory_seperator_str{
repertory::utils::path::directory_seperator,
};
static const std::wstring directory_seperator_str_w{
repertory::utils::path::directory_seperator_w,
};
[[nodiscard]] auto resolve(std::string path) -> std::string {
#if defined(_WIN32)
if (repertory::utils::string::contains(path, "~") ||
@ -52,12 +45,17 @@ static const std::wstring directory_seperator_str_w{
#else // !defined (_WIN32)
if (repertory::utils::string::contains(path, "~")) {
std::string home{};
auto res =
repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) {
home = (pw->pw_dir ? pw->pw_dir : "");
if (home.empty() || ((home == "/") && (getuid() != 0))) {
if (home.empty() ||
((home == repertory::utils::path::slash) && (getuid() != 0))) {
home = repertory::utils::path::combine("/home", {pw->pw_name});
}
});
if (res) {
throw std::runtime_error("failed to getpwuid: " + res.reason);
}
return repertory::utils::string::replace(path, "~", home);
}
@ -70,36 +68,44 @@ static const std::wstring directory_seperator_str_w{
namespace repertory::utils::path {
auto absolute(std::string_view path) -> std::string {
std::string abs_path{path};
abs_path = resolve(abs_path);
format_path(abs_path, directory_seperator, not_directory_seperator);
#if defined(_WIN32)
if (not abs_path.empty() && ::PathIsRelativeA(abs_path.c_str())) {
std::string temp;
temp.resize(MAX_PATH + 1);
abs_path = _fullpath(temp.data(), abs_path.c_str(), MAX_PATH);
if (abs_path.empty()) {
return abs_path;
}
abs_path = finalize(resolve(abs_path));
#if defined(_WIN32)
if (not utils::string::contains(abs_path, dot)) {
return abs_path;
}
std::string temp;
temp.resize(repertory::max_path_length + 1);
::GetFullPathNameA(abs_path.c_str(), static_cast<DWORD>(temp.size()),
temp.data(), nullptr);
#else // !defined(_WIN32)
if (not abs_path.empty() && (abs_path.at(0U) != '/')) {
if (not utils::string::contains(abs_path, dot) ||
utils::string::begins_with(abs_path, slash)) {
return abs_path;
}
auto found{false};
std::string tmp{abs_path};
do {
auto *res = realpath(tmp.c_str(), nullptr);
if (res != nullptr) {
abs_path = res + std::string{directory_seperator} +
abs_path.substr(tmp.size());
abs_path =
res + std::string{directory_seperator} + abs_path.substr(tmp.size());
free(res);
found = true;
} else if (tmp == ".") {
} else if (tmp == dot) {
found = true;
} else {
tmp = dirname(tmp.data());
}
} while (not found);
}
#endif // defined(_WIN32)
return format_path(abs_path, directory_seperator, not_directory_seperator);
return finalize(abs_path);
}
auto absolute(std::wstring_view path) -> std::wstring {
@ -142,7 +148,7 @@ auto find_program_in_path(const std::string &name_without_extension)
for (auto &&extension : extension_list) {
auto exec_path = combine(
search_path, {name_without_extension + std::string{extension}});
if (std::filesystem::exists(exec_path)) {
if (utils::file::is_file(exec_path)) {
found_items[name_without_extension] = exec_path;
return exec_path;
}
@ -159,14 +165,16 @@ find_program_in_path(std::wstring_view name_without_extension) -> std::wstring {
}
auto get_parent_directory(std::string_view path) -> std::string {
auto ret = std::filesystem::path{path}.parent_path().string();
#if !defined(_WIN32)
if (ret == ".") {
ret = "/";
}
#endif // !defined(_WIN32)
auto abs_path = absolute(path);
return absolute(ret);
#if defined(_WIN32)
::PathRemoveFileSpecA(abs_path.data());
abs_path = abs_path.c_str();
#else // !defined(_WIN32)
abs_path = std::filesystem::path{abs_path}.parent_path().string();
#endif // defined(_WIN32)
return finalize(abs_path);
}
auto get_parent_directory(std::wstring_view path) -> std::wstring {
@ -175,13 +183,12 @@ auto get_parent_directory(std::wstring_view path) -> std::wstring {
}
auto is_trash_directory(std::string_view path) -> bool {
std::string dir_sep_t{get_directory_seperator<char>()};
auto trash_path = utils::string::to_lower(absolute(path));
return utils::string::begins_with(trash_path,
directory_seperator_str + ".trash-") ||
utils::string::begins_with(trash_path,
directory_seperator_str + ".trashes") ||
utils::string::begins_with(trash_path,
directory_seperator_str + "$recycle.bin");
return utils::string::begins_with(trash_path, dir_sep_t + ".trash-") ||
utils::string::begins_with(trash_path, dir_sep_t + ".trashes") ||
utils::string::begins_with(trash_path, dir_sep_t + "$recycle.bin");
}
auto is_trash_directory(std::wstring_view path) -> bool {
@ -191,8 +198,8 @@ auto is_trash_directory(std::wstring_view path) -> bool {
auto make_file_uri(std::string_view path) -> std::string {
auto abs_path = absolute(path);
#if defined(_WIN32)
utils::string::replace(abs_path, '\\', '/');
abs_path = '/' + abs_path;
utils::string::replace(abs_path, backslash, slash);
abs_path = std::string{slash} + abs_path;
#endif // defined(_WIN32)
return "file://" + abs_path;
}
@ -201,31 +208,11 @@ auto make_file_uri(std::wstring_view path) -> std::wstring {
return utils::string::from_utf8(make_file_uri(utils::string::to_utf8(path)));
}
auto remove_file_name(std::string_view path) -> std::string {
auto abs_path = absolute(path);
#if defined(_WIN32)
::PathRemoveFileSpecA(abs_path.data());
abs_path = abs_path.c_str();
#else // !defined(_WIN32)
if (abs_path != "/") {
auto idx{abs_path.size() - 1U};
while ((idx != 0U) && (abs_path.at(idx) != '/')) {
idx--;
}
abs_path = (idx > 0U) ? absolute(abs_path.substr(0U, idx)) : "/";
}
#endif // defined(_WIN32)
return abs_path;
}
auto strip_to_file_name(std::string path) -> std::string {
#if defined(_WIN32)
return ::PathFindFileNameA(path.c_str());
#else // !defined(_WIN32)
return utils::string::contains(path, "/") ? basename(path.data()) : path;
return utils::string::contains(path, slash) ? basename(path.data()) : path;
#endif // defined(_WIN32)
}

View File

@ -76,7 +76,7 @@ auto run_process_elevated(std::vector<const char *> args) -> int {
}
std::string full_path;
full_path.resize(MAX_PATH + 1);
full_path.resize(repertory::max_path_length + 1);
if (::GetModuleFileNameA(nullptr, full_path.data(), MAX_PATH)) {
SHELLEXECUTEINFOA sei{};

View File

@ -38,7 +38,8 @@ using namespace ::testing;
namespace repertory::test {
#if defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto create_random_file(std::size_t size) -> utils::file::file;
[[nodiscard]] auto
create_random_file(std::size_t size) -> utils::file::i_file &;
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto

View File

@ -24,24 +24,24 @@
namespace {
static std::recursive_mutex file_mtx{};
static std::vector<std::string> generated_files;
static std::vector<std::unique_ptr<repertory::utils::file::i_file>>
generated_files{};
static void delete_generated_files() {
repertory::recur_mutex_lock lock{file_mtx};
std::optional<std::string> parent_path;
for (auto &&path : generated_files) {
if (parent_path->empty()) {
parent_path = std::filesystem::path(path).parent_path().string();
parent_path =
repertory::utils::path::get_parent_directory(path->get_path());
}
std::error_code ec{};
std::filesystem::remove(path, ec);
[[maybe_unused]] auto removed = path->remove();
}
generated_files.clear();
if (parent_path.has_value()) {
std::error_code ec{};
std::filesystem::remove_all(*parent_path, ec);
EXPECT_TRUE(repertory::utils::file::remove_directory(*parent_path, true));
}
}
@ -54,26 +54,25 @@ static auto deleter{std::make_unique<file_deleter>()};
namespace repertory::test {
#if defined(PROJECT_ENABLE_LIBSODIUM)
auto create_random_file(std::size_t size) -> utils::file::file {
auto create_random_file(std::size_t size) -> utils::file::i_file & {
recur_mutex_lock lock{file_mtx};
auto path = generate_test_file_name("random");
auto file = utils::file::file::open_or_create_file(path);
EXPECT_TRUE(file);
if (file) {
EXPECT_TRUE(*file);
if (*file) {
data_buffer buf(size);
randombytes_buf(buf.data(), buf.size());
std::size_t bytes_written{};
EXPECT_TRUE(file.write(buf, 0U, &bytes_written));
EXPECT_TRUE(file->write(buf, 0U, &bytes_written));
EXPECT_EQ(size, bytes_written);
EXPECT_EQ(size, file.size());
generated_files.emplace_back(path);
EXPECT_EQ(size, file->size());
}
return file;
generated_files.emplace_back(std::move(file));
return *generated_files.back();
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
@ -86,8 +85,9 @@ auto generate_test_file_name(std::string_view file_name_no_extension)
std::string{file_name_no_extension} +
std::to_string(generated_files.size()),
});
generated_files.emplace_back(path);
return path;
generated_files.emplace_back(
std::unique_ptr<utils::file::i_file>(new utils::file::file{path}));
return generated_files.back()->get_path();
}
auto get_test_input_dir() -> std::string {
@ -111,7 +111,7 @@ auto get_test_output_dir() -> std::string {
#endif // defined(_WIN32)
if (not utils::file::is_directory(path)) {
std::filesystem::create_directories(path);
EXPECT_TRUE(utils::file::create_directories(path));
}
return path;

View File

@ -273,7 +273,7 @@ TEST(utils_common, get_environment_variable) {
std::string path;
#if defined(_WIN32)
path.resize(MAX_PATH + 1U);
path.resize(repertory::max_path_length + 1U);
auto size = ::GetEnvironmentVariableA(path_env.c_str(), path.data(), 0U);
path.resize(size);

View File

@ -25,13 +25,13 @@
namespace repertory {
TEST(utils_encrypting_reader, read_file_data) {
const auto token = std::string("moose");
auto source_file = test::create_random_file(
auto &source_file = test::create_random_file(
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file);
if (source_file) {
stop_type stop_requested{false};
utils::encryption::encrypting_reader reader(
"test.dat", source_file.get_path().string(), stop_requested, token);
"test.dat", source_file.get_path(), stop_requested, token);
for (std::uint8_t i = 0U; i < 8U; i++) {
data_buffer buffer(
@ -65,13 +65,13 @@ TEST(utils_encrypting_reader, read_file_data) {
TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks) {
const auto token = std::string("moose");
auto source_file = test::create_random_file(
auto &source_file = test::create_random_file(
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file);
if (source_file) {
stop_type stop_requested{false};
utils::encryption::encrypting_reader reader(
"test.dat", source_file.get_path().string(), stop_requested, token);
"test.dat", source_file.get_path(), stop_requested, token);
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
data_buffer buffer(
@ -113,13 +113,13 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks) {
TEST(utils_encrypting_reader, read_file_data_as_stream) {
const auto token = std::string("moose");
auto source_file = test::create_random_file(
auto &source_file = test::create_random_file(
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file);
if (source_file) {
stop_type stop_requested{false};
utils::encryption::encrypting_reader reader(
"test.dat", source_file.get_path().string(), stop_requested, token);
"test.dat", source_file.get_path(), stop_requested, token);
auto io_stream = reader.create_iostream();
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail());
EXPECT_TRUE(io_stream->good());
@ -166,13 +166,13 @@ TEST(utils_encrypting_reader, read_file_data_as_stream) {
TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks_as_stream) {
const auto token = std::string("moose");
auto source_file = test::create_random_file(
auto &source_file = test::create_random_file(
8u * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file);
if (source_file) {
stop_type stop_requested{false};
utils::encryption::encrypting_reader reader(
"test.dat", source_file.get_path().string(), stop_requested, token);
"test.dat", source_file.get_path(), stop_requested, token);
auto io_stream = reader.create_iostream();
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail());
EXPECT_TRUE(io_stream->good());

View File

@ -21,57 +21,81 @@
*/
#include "test.hpp"
namespace {
static constexpr const auto file_type_count{1U};
}
namespace repertory {
TEST(utils_file, can_create_file) {
for (auto idx = 0U; idx < file_type_count; ++idx) {
auto path = test::generate_test_file_name("utils_file");
EXPECT_FALSE(utils::file::is_file(path) || utils::file::is_directory(path));
auto file = utils::file::file::open_or_create_file(path);
EXPECT_TRUE(file);
auto file = idx == 0U ? utils::file::file::open_or_create_file(path)
: utils::file::thread_file::open_or_create_file(path);
EXPECT_TRUE(*file);
EXPECT_TRUE(utils::file::is_file(path));
}
}
TEST(utils_file, can_open_file) {
for (auto idx = 0U; idx < file_type_count; ++idx) {
auto path = test::generate_test_file_name("utils_file");
{
auto file = utils::file::file::open_or_create_file(path);
EXPECT_TRUE(file);
auto file = idx == 0U
? utils::file::file::open_or_create_file(path)
: utils::file::thread_file::open_or_create_file(path);
EXPECT_TRUE(*file);
}
{
auto file = utils::file::file::open_file(path);
EXPECT_TRUE(file);
auto file = idx == 0U ? utils::file::file::open_file(path)
: utils::file::thread_file::open_file(path);
EXPECT_TRUE(*file);
}
}
}
TEST(utils_file, open_file_fails_if_not_found) {
for (auto idx = 0U; idx < file_type_count; ++idx) {
auto path = test::generate_test_file_name("utils_file");
auto file = utils::file::file::open_file(path);
EXPECT_FALSE(file);
auto file = idx == 0U ? utils::file::file::open_file(path)
: utils::file::thread_file::open_file(path);
EXPECT_FALSE(*file);
}
}
TEST(utils_file, write_fails_for_read_only_file) {
for (auto idx = 0U; idx < file_type_count; ++idx) {
auto path = test::generate_test_file_name("utils_file");
auto file = utils::file::file::open_or_create_file(path, true);
auto file = idx == 0U
? utils::file::file::open_or_create_file(path, true)
: utils::file::thread_file::open_or_create_file(path, true);
EXPECT_TRUE(utils::file::is_file(path));
EXPECT_TRUE(file);
EXPECT_TRUE(*file);
std::size_t bytes_written{};
EXPECT_FALSE(file.write(reinterpret_cast<const unsigned char *>("0"), 1U, 0U,
&bytes_written));
EXPECT_FALSE(file->write(reinterpret_cast<const unsigned char *>("0"), 1U,
0U, &bytes_written));
EXPECT_EQ(0U, bytes_written);
}
}
TEST(utils_file, can_attach_file) {
for (auto idx = 0U; idx < file_type_count; ++idx) {
auto path = test::generate_test_file_name("utils_file");
auto file = utils::file::file::open_or_create_file(path);
auto file2 = utils::file::file::attach_file(file.get_handle());
EXPECT_TRUE(file);
EXPECT_TRUE(file2);
EXPECT_EQ(file.get_path(), file2.get_path());
auto file = idx == 0U ? utils::file::file::open_or_create_file(path)
: utils::file::thread_file::open_or_create_file(path);
auto file2 =
idx == 0U ? utils::file::file::attach_file(file->get_handle())
: utils::file::thread_file::attach_file(file->get_handle());
EXPECT_TRUE(*file);
EXPECT_TRUE(*file2);
EXPECT_EQ(file->get_path(), file2->get_path());
}
}
#if defined(PROJECT_ENABLE_JSON)
@ -100,14 +124,14 @@ TEST(utils_file, read_and_write_json_file_encrypted) {
{
auto file = utils::file::file::open_file(path);
data_buffer encrypted_data{};
EXPECT_TRUE(file.read_all(encrypted_data, 0U));
EXPECT_TRUE(file->read_all(encrypted_data, 0U));
data_buffer decrypted_data{};
EXPECT_TRUE(utils::encryption::decrypt_data("moose", encrypted_data,
decrypted_data));
EXPECT_STREQ(data.dump().c_str(),
nlohmann::json::parse(
std::string{decrypted_data.begin(), decrypted_data.end()})
std::string(decrypted_data.begin(), decrypted_data.end()))
.dump()
.c_str());
}

View File

@ -21,12 +21,38 @@
*/
#include "test.hpp"
#if defined(_WIN32)
namespace {
static const auto test_path = [](std::string str) -> std::string {
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
if (repertory::utils::string::begins_with(str, "\\")) {
str = repertory::utils::string::to_lower(
std::filesystem::current_path().string().substr(0U, 2U)) +
str;
}
str = std::string{repertory::utils::path::long_notation} + str;
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
if (repertory::utils::string::begins_with(str, "\\")) {
str = repertory::utils::string::to_lower(
std::filesystem::current_path().string().substr(0U, 2U)) +
str;
}
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return repertory::utils::string::right_trim(str, '\\');
};
} // namespace
#endif // defined(_WIN32)
namespace repertory {
TEST(utils_path, constants) {
EXPECT_EQ(std::string_view{"\\"}, utils::path::backslash);
EXPECT_EQ(std::wstring_view{L"\\"}, utils::path::backslash_w);
EXPECT_EQ(std::string_view{"."}, utils::path::dot);
EXPECT_EQ(std::wstring_view{L"."}, utils::path::dot_w);
EXPECT_EQ(std::string_view{".\\"}, utils::path::dot_backslash);
EXPECT_EQ(std::wstring_view{L".\\"}, utils::path::dot_backslash_w);
EXPECT_EQ(std::string_view{"./"}, utils::path::dot_slash);
EXPECT_EQ(std::wstring_view{L"./"}, utils::path::dot_slash_w);
EXPECT_EQ(std::string_view{"/"}, utils::path::slash);
@ -82,6 +108,12 @@ TEST(utils_path, get_dot) {
EXPECT_EQ(utils::path::dot_w, utils::path::get_dot<wchar_t>());
}
TEST(utils_path, get_dot_backslash) {
EXPECT_EQ(utils::path::dot_backslash, utils::path::get_dot_backslash<char>());
EXPECT_EQ(utils::path::dot_backslash_w,
utils::path::get_dot_backslash<wchar_t>());
}
TEST(utils_path, get_dot_slash) {
EXPECT_EQ(utils::path::dot_slash, utils::path::get_dot_slash<char>());
EXPECT_EQ(utils::path::dot_slash_w, utils::path::get_dot_slash<wchar_t>());
@ -92,47 +124,53 @@ TEST(utils_path, get_slash) {
EXPECT_EQ(utils::path::slash_w, utils::path::get_slash<wchar_t>());
}
TEST(utils_path, get_long_notation) {
EXPECT_EQ(utils::path::long_notation, utils::path::get_long_notation<char>());
EXPECT_EQ(utils::path::long_notation_w,
utils::path::get_long_notation<wchar_t>());
}
TEST(utils_path, combine) {
auto s = utils::path::combine(R"(\test\path)", {});
#if defined(_WIN32)
EXPECT_STREQ(R"(\test\path)", s.c_str());
EXPECT_STREQ(test_path(R"(\test\path)").c_str(), s.c_str());
#else
EXPECT_STREQ("/test/path", s.c_str());
#endif
s = utils::path::combine(R"(\test)", {R"(\path)"});
#if defined(_WIN32)
EXPECT_STREQ(R"(\test\path)", s.c_str());
EXPECT_STREQ(test_path(R"(\test\path)").c_str(), s.c_str());
#else
EXPECT_STREQ("/test/path", s.c_str());
#endif
s = utils::path::combine(R"(\test)", {R"(\path)", R"(\again\)"});
#if defined(_WIN32)
EXPECT_STREQ(R"(\test\path\again)", s.c_str());
EXPECT_STREQ(test_path(R"(\test\path\again)").c_str(), s.c_str());
#else
EXPECT_STREQ("/test/path/again", s.c_str());
#endif
s = utils::path::combine("/home/test/.dest", {".state"});
#if defined(_WIN32)
EXPECT_STREQ("\\home\\test\\.dest\\.state", s.c_str());
EXPECT_STREQ(test_path(R"(\home\test\.dest\.state)").c_str(), s.c_str());
#else
EXPECT_STREQ("/home/test/.dest/.state", s.c_str());
#endif
#if defined(_WIN32)
s = utils::path::combine(R"(R:\test)", {R"(\path)", R"(\again\)"});
EXPECT_STREQ(R"(r:\test\path\again)", s.c_str());
EXPECT_STREQ(test_path(R"(r:\test\path\again)").c_str(), s.c_str());
s = utils::path::combine("R:", {R"(\path)", R"(\again\)"});
EXPECT_STREQ(R"(r:\path\again)", s.c_str());
EXPECT_STREQ(test_path(R"(r:\path\again)").c_str(), s.c_str());
s = utils::path::combine("R:", {});
EXPECT_STREQ("r:", s.c_str());
EXPECT_STREQ(test_path("r:").c_str(), s.c_str());
s = utils::path::combine("R:", {"\\"});
EXPECT_STREQ("r:", s.c_str());
EXPECT_STREQ(test_path("r:").c_str(), s.c_str());
#endif
}
@ -224,104 +262,116 @@ TEST(utils_path, finalize) {
s = utils::path::finalize(R"(\)");
#if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str());
EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else
EXPECT_STREQ("/", s.c_str());
#endif
s = utils::path::finalize("/");
#if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str());
EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else
EXPECT_STREQ("/", s.c_str());
#endif
s = utils::path::finalize(R"(\\)");
#if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str());
EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else
EXPECT_STREQ("/", s.c_str());
#endif
s = utils::path::finalize("//");
#if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str());
EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else
EXPECT_STREQ("/", s.c_str());
#endif
s = utils::path::finalize("/cow///moose/////dog/chicken");
#if defined(_WIN32)
EXPECT_STREQ(R"(\cow\moose\dog\chicken)", s.c_str());
EXPECT_STREQ(test_path(R"(\cow\moose\dog\chicken)").c_str(), s.c_str());
#else
EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str());
#endif
s = utils::path::finalize("\\cow\\\\\\moose\\\\\\\\dog\\chicken/");
#if defined(_WIN32)
EXPECT_STREQ(R"(\cow\moose\dog\chicken)", s.c_str());
EXPECT_STREQ(test_path(R"(\cow\moose\dog\chicken)").c_str(), s.c_str());
#else
EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str());
#endif
s = utils::path::finalize("/cow\\\\/moose\\\\/\\dog\\chicken\\");
#if defined(_WIN32)
EXPECT_STREQ(R"(\cow\moose\dog\chicken)", s.c_str());
EXPECT_STREQ(test_path(R"(\cow\moose\dog\chicken)").c_str(), s.c_str());
#else
EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str());
#endif
#if defined(_WIN32)
s = utils::path::finalize("D:");
EXPECT_STREQ("d:", s.c_str());
EXPECT_STREQ(test_path("d:").c_str(), s.c_str());
s = utils::path::finalize("D:\\");
EXPECT_STREQ("d:", s.c_str());
EXPECT_STREQ(test_path("d:").c_str(), s.c_str());
s = utils::path::finalize("D:\\moose");
EXPECT_STREQ("d:\\moose", s.c_str());
EXPECT_STREQ(test_path("d:\\moose").c_str(), s.c_str());
s = utils::path::finalize("D:\\moose\\");
EXPECT_STREQ("d:\\moose", s.c_str());
EXPECT_STREQ(test_path("d:\\moose").c_str(), s.c_str());
s = utils::path::finalize("D:/");
EXPECT_STREQ("d:", s.c_str());
EXPECT_STREQ(test_path("d:").c_str(), s.c_str());
s = utils::path::finalize("D:/moose");
EXPECT_STREQ("d:\\moose", s.c_str());
EXPECT_STREQ(test_path("d:\\moose").c_str(), s.c_str());
s = utils::path::finalize("D:/moose/");
EXPECT_STREQ("d:\\moose", s.c_str());
EXPECT_STREQ(test_path("d:\\moose").c_str(), s.c_str());
#endif // defined(_WIN32)
}
TEST(utils_path, absolute) {
auto dir = utils::path::absolute(std::filesystem::current_path().string());
auto dir = utils::path::get_current_path<std::string>();
auto path = utils::path::absolute(".");
EXPECT_STREQ(dir.c_str(), path.c_str());
path = utils::path::absolute("./");
EXPECT_STREQ(dir.c_str(), path.c_str());
path = utils::path::absolute(R"(.\)");
EXPECT_STREQ(dir.c_str(), path.c_str());
#if defined(_WIN32)
path = utils::path::absolute(R"(.\moose)");
EXPECT_STREQ((dir + R"(\moose)").c_str(), path.c_str());
path = utils::path::absolute(R"(./moose)");
EXPECT_STREQ((dir + R"(\moose)").c_str(), path.c_str());
auto home_env = utils::get_environment_variable("USERPROFILE");
#else // !defined(_WIN32)
path = utils::path::absolute(R"(.\moose)");
EXPECT_STREQ((dir + R"(/moose)").c_str(), path.c_str());
path = utils::path::absolute(R"(./moose)");
EXPECT_STREQ((dir + R"(/moose)").c_str(), path.c_str());
auto home_env = utils::get_environment_variable("HOME");
#endif // defined(_WIN32)
auto home = utils::path::absolute(home_env);
path = utils::path::absolute("~");
EXPECT_STREQ(home.c_str(), path.c_str());
// path = utils::path::absolute("~/.local");
}
TEST(utils_path, absolute_can_resolve_path_variables) {
std::string home{};
#if defined(_WIN32)
home.resize(MAX_PATH + 1U);
home.resize(repertory::max_path_length + 1U);
auto size = ::GetEnvironmentVariableA("USERPROFILE", home.data(), 0U);
home.resize(size);