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) add_definitions(-DPROJECT_IS_ARM64)
endif() 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/settings.cmake)
include(cmake/flags.cmake) include(cmake/flags.cmake)
@ -127,6 +134,7 @@ endif()
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT} -DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
-DPROJECT_DESC=${PROJECT_DESC} -DPROJECT_DESC=${PROJECT_DESC}
-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR} -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_BACKWARD_CPP=${PROJECT_ENABLE_BACKWARD_CPP}
-DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST} -DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST}
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB} -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_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY}
PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY} PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_ENABLE_BACKWARD_CPP=ON PROJECT_ENABLE_BACKWARD_CPP=ON
PROJECT_ENABLE_BOOST=ON PROJECT_ENABLE_BOOST=ON
PROJECT_ENABLE_CPP_HTTPLIB=ON PROJECT_ENABLE_CPP_HTTPLIB=ON

View File

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

View File

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

View File

@ -131,7 +131,7 @@ public:
std::atomic<std::chrono::system_clock::time_point> last_access_{ std::atomic<std::chrono::system_clock::time_point> last_access_{
std::chrono::system_clock::now()}; std::chrono::system_clock::now()};
bool modified_{false}; bool modified_{false};
utils::file::file nf_; std::unique_ptr<utils::file::i_file> nf_;
mutable std::mutex io_thread_mtx_; mutable std::mutex io_thread_mtx_;
std::condition_variable io_thread_notify_; std::condition_variable io_thread_notify_;
std::deque<std::shared_ptr<io_item>> io_thread_queue_; 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, [[nodiscard]] auto copy_file(std::string from_path,
std::string to_path) -> bool; 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 generate_sha256(const std::string &file_path) -> std::string;
[[nodiscard]] auto get_accessed_time(const std::string &path, [[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_password = get_provider_api_password(prov_);
hc_.api_port = default_api_port(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_); 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_); 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_); throw startup_exception("unable to create: " + log_directory_);
} }
@ -715,7 +715,7 @@ void app_config::save() {
recur_mutex_lock lock(read_write_mutex_); recur_mutex_lock lock(read_write_mutex_);
if (config_changed_ || not utils::file::is_file(file_path)) { if (config_changed_ || not utils::file::is_file(file_path)) {
if (not utils::file::is_directory(data_directory_)) { 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( utils::error::raise_error(
function_name, "failed to create directory|sp|" + data_directory_ + function_name, "failed to create directory|sp|" + data_directory_ +
"|err|" + "|err|" +

View File

@ -49,11 +49,11 @@ auto http_put_file::set_method(CURL *curl,
utils::file::file::open_or_create_file(source_path), utils::file::file::open_or_create_file(source_path),
}); });
if (not read_info->file) { if (not *read_info->file) {
return false; 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_READDATA, read_info.get());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data); 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 { auto packet::decode(std::string &data) -> packet::error_type {
const auto *str = reinterpret_cast<const char *>(&buffer_[decode_offset_]); const auto *str = reinterpret_cast<const char *>(&buffer_[decode_offset_]);
const auto length = strnlen(str, buffer_.size() - 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); decode_offset_ += (length + 1);
return utils::from_api_error(api_error::success); return utils::from_api_error(api_error::success);

View File

@ -68,7 +68,7 @@ file_manager::open_file::open_file(
if (not fsi.directory) { if (not fsi.directory) {
nf_ = utils::file::file::open_or_create_file(fsi.source_path, nf_ = utils::file::file::open_or_create_file(fsi.source_path,
provider_.is_direct_only()); 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 (get_api_error() == api_error::success) {
if (read_state.has_value()) { if (read_state.has_value()) {
read_state_ = read_state.value(); read_state_ = read_state.value();
@ -78,16 +78,16 @@ file_manager::open_file::open_file(
fsi_.size, chunk_size)), fsi_.size, chunk_size)),
false); false);
auto file_size = nf_.size(); auto file_size = nf_->size();
if (provider_.is_direct_only() || file_size == fsi.size) { if (provider_.is_direct_only() || file_size == fsi.size) {
read_state_.set(0U, read_state_.size(), true); 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); set_api_error(api_error::os_error);
} }
} }
if (get_api_error() != api_error::success && nf_) { if (get_api_error() != api_error::success && *nf_) {
nf_.close(); nf_->close();
} }
} }
} }
@ -182,7 +182,7 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
res = do_io([&]() -> api_error { res = do_io([&]() -> api_error {
std::size_t bytes_written{}; 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; return api_error::os_error;
} }
@ -242,7 +242,7 @@ auto file_manager::open_file::native_operation(
} }
file_lock.unlock(); 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( 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(); 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) { if (res != api_error::success) {
utils::error::raise_api_path_error(function_name, get_api_path(), utils::error::raise_api_path_error(function_name, get_api_path(),
utils::get_last_error_code(), 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) { if (file_size != new_file_size) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, get_api_path(), api_error::file_size_mismatch, 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); data.resize(read_size);
std::size_t bytes_read{}; 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::success
: api_error::os_error; : api_error::os_error;
}); });
@ -412,8 +412,8 @@ auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error {
return native_operation( return native_operation(
new_file_size, [this, &new_file_size](native_handle) -> api_error { 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; : 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)) { if (modified_ && (get_api_error() == api_error::success)) {
mgr_.queue_upload(*this); mgr_.queue_upload(*this);
@ -464,7 +464,7 @@ auto file_manager::open_file::close() -> bool {
utils::get_last_error_code(), "failed to delete file"); 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 = fsi_.source_path =
utils::path::combine(parent, {utils::create_uuid_string()}); utils::path::combine(parent, {utils::create_uuid_string()});
const auto res = provider_.set_item_meta(fsi_.api_path, META_SOURCE, 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 { 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; 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); ring_state_.set(0U, ring_state_.size(), true);
buffer_directory = utils::path::absolute(buffer_directory); 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|" + throw std::runtime_error("failed to create buffer directory|path|" +
buffer_directory + "|err|" + buffer_directory + "|err|" +
std::to_string(utils::get_last_error_code())); 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 = fsi_.source_path =
utils::path::combine(buffer_directory, {utils::create_uuid_string()}); utils::path::combine(buffer_directory, {utils::create_uuid_string()});
nf_ = utils::file::file::open_or_create_file(fsi_.source_path); 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|" + throw std::runtime_error("failed to create buffer file|err|" +
std::to_string(utils::get_last_error_code())); std::to_string(utils::get_last_error_code()));
} }
if (not nf_.truncate(ring_state_.size() * chunk_size)) { if (not nf_->truncate(ring_state_.size() * chunk_size)) {
nf_.close(); nf_->close();
throw std::runtime_error("failed to resize buffer file|err|" + throw std::runtime_error("failed to resize buffer file|err|" +
std::to_string(utils::get_last_error_code())); std::to_string(utils::get_last_error_code()));
} }
@ -92,7 +92,7 @@ file_manager::ring_buffer_open_file::~ring_buffer_open_file() {
close(); close();
nf_.close(); nf_->close();
if (not utils::file::retry_delete_file(fsi_.source_path)) { if (not utils::file::retry_delete_file(fsi_.source_path)) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, fsi_.api_path, fsi_.source_path, function_name, fsi_.api_path, fsi_.source_path,
@ -128,8 +128,8 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk(
if (res == api_error::success) { if (res == api_error::success) {
res = do_io([&]() -> api_error { res = do_io([&]() -> api_error {
std::size_t bytes_written{}; 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)) { &bytes_written)) {
return api_error::os_error; 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( auto file_manager::ring_buffer_open_file::native_operation(
i_open_file::native_operation_callback callback) -> api_error { 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) { void file_manager::ring_buffer_open_file::reverse(std::size_t count) {
@ -270,8 +270,8 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
&to_read]() -> api_error { &to_read]() -> api_error {
std::size_t bytes_read{}; std::size_t bytes_read{};
auto ret = auto ret =
nf_.read(buffer, ((chunk % ring_state_.size()) * chunk_size_), nf_->read(buffer, ((chunk % ring_state_.size()) * chunk_size_),
&bytes_read) &bytes_read)
? api_error::success ? api_error::success
: api_error::os_error; : api_error::os_error;
if (ret == api_error::success) { if (ret == api_error::success) {

View File

@ -57,7 +57,7 @@ lock_data::~lock_data() {
auto lock_data::get_lock_data_file() -> std::string { auto lock_data::get_lock_data_file() -> std::string {
const auto dir = get_state_directory(); 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|" + throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code())); 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 { auto lock_data::get_lock_file() -> std::string {
const auto dir = get_state_directory(); 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|" + throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code())); 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)) { if (utils::file::is_file(item.source_path)) {
const auto orphaned_directory = const auto orphaned_directory =
utils::path::combine(config_.get_data_directory(), {"orphaned"}); 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 parts = utils::string::split(item.api_path, '/', false);
const auto orphaned_file = utils::path::combine( const auto orphaned_file = utils::path::combine(
orphaned_directory, orphaned_directory,

View File

@ -117,7 +117,7 @@ auto copy_directory_recursively(std::string from_path,
std::string to_path) -> bool { std::string to_path) -> bool {
from_path = utils::path::absolute(from_path); from_path = utils::path::absolute(from_path);
to_path = utils::path::absolute(to_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 (ret) {
#if defined(_WIN32) #if defined(_WIN32)
WIN32_FIND_DATA fd{}; WIN32_FIND_DATA fd{};
@ -167,108 +167,6 @@ auto copy_directory_recursively(std::string from_path,
return ret; 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 { auto generate_sha256(const std::string &file_path) -> std::string {
crypto_hash_sha256_state state{}; crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&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)); std::to_string(res));
} }
auto nf = utils::file::file::open_file(file_path);
if (not nf) {
throw std::runtime_error("failed to open file|" + file_path);
}
{ {
data_buffer buffer(1048576u); auto input_file = utils::file::file::open_file(file_path);
std::uint64_t read_offset = 0U; if (not *input_file) {
std::size_t bytes_read = 0U; throw std::runtime_error("failed to open file|" + file_path);
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) { if (not bytes_read) {
break; break;
} }
@ -506,8 +404,8 @@ auto move_file(std::string from, std::string to) -> bool {
from = utils::path::absolute(from); from = utils::path::absolute(from);
to = utils::path::absolute(to); to = utils::path::absolute(to);
const auto directory = utils::path::remove_file_name(to); const auto directory = utils::path::get_parent_directory(to);
if (not create_full_directory_path(directory)) { if (not create_directories(directory)) {
return false; 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 retry_delete_directory(const std::string &dir) -> bool {
auto deleted = false; 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++) { i++) {
std::this_thread::sleep_for(10ms); 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 retry_delete_file(const std::string &file) -> bool {
auto deleted = false; auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_file(file)) && (i < 200U); for (std::uint8_t i = 0U;
i++) { not(deleted = utils::file::file{file}.remove()) && (i < 200U); i++) {
std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(10ms);
} }

View File

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

View File

@ -32,7 +32,7 @@ namespace repertory {
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name)); ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose"); 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); EXPECT_TRUE(source_file != nullptr);
if (source_file) { if (source_file) {
stop_type stop_requested = false; 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, TEST(open_file,
will_not_change_source_path_if_file_size_matches_existing_source) { will_not_change_source_path_if_file_size_matches_existing_source) {
auto rf = test::create_random_file(test_chunk_size); auto &rf = test::create_random_file(test_chunk_size);
const auto source_path = rf.get_path().string(); const auto source_path = rf.get_path();
rf.close(); rf.close();
mock_provider mp; mock_provider mp;
@ -197,7 +197,7 @@ TEST(open_file,
TEST(open_file, write_with_incomplete_download) { TEST(open_file, write_with_incomplete_download) {
const auto source_path = test::generate_test_file_name("test"); 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_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -449,8 +449,8 @@ TEST(open_file, write_new_file_multiple_chunks) {
} }
TEST(open_file, resize_file_to_0_bytes) { TEST(open_file, resize_file_to_0_bytes) {
auto rf = test::create_random_file(test_chunk_size * 4u); auto &rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path().string(); const auto source_path = rf.get_path();
rf.close(); rf.close();
mock_provider mp; mock_provider mp;
@ -499,8 +499,8 @@ TEST(open_file, resize_file_to_0_bytes) {
} }
TEST(open_file, resize_file_by_full_chunk) { TEST(open_file, resize_file_by_full_chunk) {
auto rf = test::create_random_file(test_chunk_size * 4u); auto &rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path().string(); const auto source_path = rf.get_path();
rf.close(); rf.close();
mock_provider mp; 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, 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) { 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) { 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_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) { 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, 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) { 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) { 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) { 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) { TEST(ring_buffer_open_file, read_full_file) {
auto nf = test::create_random_file(test_chunk_size * 32u); auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string(); const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file"); 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, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 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_TRUE(nf2);
auto to_read = fsi.size; 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()); 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) { TEST(ring_buffer_open_file, read_full_file_in_reverse) {
auto nf = test::create_random_file(test_chunk_size * 32u); auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string(); const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file"); 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, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 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_TRUE(nf2);
auto to_read = fsi.size; 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()); 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) { TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
auto nf = test::create_random_file(test_chunk_size * 32u); auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string(); const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("test"); 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, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 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_TRUE(nf2);
// EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, // EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path,
// nf2)); // nf2));
@ -491,12 +494,12 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
utils::file::generate_sha256(dest_path).c_str()); 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) { TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
auto nf = test::create_random_file(test_chunk_size * 32u); auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path().string(); const auto download_source_path = nf.get_path();
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file"); 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, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 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_TRUE(nf2);
std::uint64_t total_read{0U}; 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()); 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 } // namespace repertory

View File

@ -84,7 +84,7 @@ TEST(file_manager, can_start_and_stop) {
} }
event_system::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_create_and_close_file) { TEST(file_manager, can_create_and_close_file) {
@ -201,7 +201,7 @@ TEST(file_manager, can_create_and_close_file) {
polling::instance().stop(); polling::instance().stop();
event_system::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) { TEST(file_manager, can_open_and_close_file) {
@ -317,7 +317,7 @@ TEST(file_manager, can_open_and_close_file) {
polling::instance().stop(); polling::instance().stop();
event_system::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) { 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(); polling::instance().stop();
event_system::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) { 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, false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u, utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u); source_path, 10, now + 4u);
auto nf = auto &nf =
test::create_random_file(utils::string::to_uint64(meta[META_SIZE])); test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item) 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(); 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) { 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, false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u, utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u); source_path, 10, now + 4u);
auto nf = auto &nf =
test::create_random_file(utils::string::to_uint64(meta[META_SIZE])); test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item) EXPECT_CALL(mp, get_filesystem_item)
@ -660,11 +660,11 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
polling::instance().stop(); polling::instance().stop();
event_system::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) { 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; console_consumer c;
event_system::instance().start(); event_system::instance().start();
@ -765,11 +765,11 @@ TEST(file_manager, can_evict_file) {
} }
event_system::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, evict_file_fails_if_file_is_pinned) { 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); app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false); 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(); 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) { 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); 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_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) { 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); 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); 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, TEST(file_manager,
evict_file_fails_if_unable_to_get_source_path_from_item_meta) { 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); 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_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) { 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); 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_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) { 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; console_consumer c;
event_system::instance().start(); event_system::instance().start();
@ -1021,11 +1021,11 @@ TEST(file_manager, evict_file_fails_if_file_is_uploading) {
} }
event_system::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, evict_file_fails_if_file_is_in_upload_queue) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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, TEST(file_manager,
get_open_file_promotes_non_writeable_file_if_writeable_is_specified) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); 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_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) { 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); app_config cfg(provider_type::sia, file_manager_dir);
@ -1596,9 +1596,10 @@ TEST(file_manager, can_remove_file) {
file_manager fm(cfg, mp); file_manager fm(cfg, mp);
auto file = utils::file::file::open_or_create_file("./test_remove.txt"); {
EXPECT_TRUE(file); auto file = utils::file::file::open_or_create_file("./test_remove.txt");
file.close(); EXPECT_TRUE(*file);
}
EXPECT_TRUE(utils::file::is_file("./test_remove.txt")); EXPECT_TRUE(utils::file::is_file("./test_remove.txt"));
EXPECT_CALL(mp, get_filesystem_item) 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_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) { 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; console_consumer c;
event_system::instance().start(); event_system::instance().start();
@ -1656,11 +1657,11 @@ TEST(file_manager, can_queue_and_remove_upload) {
} }
event_system::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, remove_file_fails_if_open_file_is_modified) { 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); 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_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) { 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(); 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) { 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); app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false); 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_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) { 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); 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_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 } // namespace repertory

View File

@ -516,12 +516,12 @@ TEST(fuse_drive, all_tests) {
const auto test_directory = utils::path::combine( const auto test_directory = utils::path::combine(
test::get_test_output_dir(), {"fuse_drive" + std::to_string(idx)}); 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 = const auto mount_location =
utils::path::combine(test_directory, {"mount", std::to_string(idx)}); 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<app_config> config_ptr{};
std::unique_ptr<curl_comm> comm_ptr{}; std::unique_ptr<curl_comm> comm_ptr{};
@ -529,7 +529,7 @@ TEST(fuse_drive, all_tests) {
const auto cfg_directory = const auto cfg_directory =
utils::path::combine(test_directory, {"cfg", std::to_string(idx)}); 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{}; 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_EQ(repertory::api_error::success, provider.is_file(api_path, exists));
EXPECT_TRUE(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{}; repertory::api_meta_map meta2{};
EXPECT_EQ(repertory::api_error::success, 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) { TEST(providers, encrypt_provider) {
const auto config_path = const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"encrypt_provider"}); 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{}; console_consumer consumer{};
event_system::instance().start(); event_system::instance().start();
@ -673,7 +673,7 @@ TEST(providers, encrypt_provider) {
TEST(providers, s3_provider) { TEST(providers, s3_provider) {
const auto config_path = const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"s3_provider"}); 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{}; console_consumer consumer{};
event_system::instance().start(); event_system::instance().start();
@ -712,7 +712,7 @@ TEST(providers, s3_provider) {
TEST(providers, sia_provider) { TEST(providers, sia_provider) {
const auto config_path = const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"sia_provider"}); 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{}; console_consumer consumer{};
event_system::instance().start(); event_system::instance().start();

View File

@ -434,7 +434,7 @@ static void mkdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory = const auto test_directory =
utils::path::combine(fuse_remote_dir, {"mkdir_test"}); utils::path::combine(fuse_remote_dir, {"mkdir_test"});
const auto api_path = test_directory.substr(mount_location_.size()); 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) #if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0)); 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 #endif
EXPECT_TRUE(utils::file::is_directory(test_directory)); 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) { 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 = const auto test_directory =
utils::path::combine(fuse_remote_dir, {"opendir_and_release_dir"}); utils::path::combine(fuse_remote_dir, {"opendir_and_release_dir"});
const auto api_path = test_directory.substr(mount_location_.size()); 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) #if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0)); 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_opendir(api_path.c_str(), handle));
EXPECT_EQ(0, client.fuse_releasedir(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) { 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 = const auto test_directory =
utils::path::combine(fuse_remote_dir, {"readdir_test"}); utils::path::combine(fuse_remote_dir, {"readdir_test"});
const auto api_path = test_directory.substr(mount_location_.size()); 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) #if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0)); 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_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) { /*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 = const auto test_directory =
utils::path::combine(fuse_remote_dir, {"rmdir_test"}); utils::path::combine(fuse_remote_dir, {"rmdir_test"});
const auto api_path = test_directory.substr(mount_location_.size()); 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) #if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0)); 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_EQ(0, client.fuse_rmdir(api_path.c_str()));
EXPECT_FALSE(utils::file::is_directory(test_directory)); 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) { static void setattr_x_test(repertory::remote_fuse::remote_client &client) {
@ -934,11 +934,11 @@ TEST(remote_fuse, all_tests) {
event_system::instance().start(); event_system::instance().start();
#if defined(_WIN32) #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_); mock_winfsp_drive drive(mount_location_);
remote_server server(config, drive, mount_location_); remote_server server(config, drive, mount_location_);
#else #else
mount_location_ = utils::path::absolute("."); mount_location_ = fuse_remote_dir;
mock_fuse_drive drive(mount_location_); mock_fuse_drive drive(mount_location_);
remote_server server(config, drive, mount_location_); remote_server server(config, drive, mount_location_);
#endif #endif
@ -990,6 +990,6 @@ TEST(remote_fuse, all_tests) {
} }
event_system::instance().stop(); 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 } // namespace fuse_test

View File

@ -49,7 +49,8 @@ static void can_delete_test(remote_client &client) {
auto api_path = auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size()); 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); EXPECT_TRUE(nf);
if (nf) { if (nf) {
EXPECT_EQ(STATUS_INVALID_HANDLE, 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) { static void create_and_read_directory_test(remote_client &client) {
const auto test_directory = const auto test_directory =
utils::path::combine(win_remote_dir, {"read_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 = auto api_path =
utils::string::from_utf8(test_directory).substr(mount_location_.size()); 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_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) { static void open_and_read_directory_test(remote_client &client) {
const auto test_directory = const auto test_directory =
utils::path::combine(win_remote_dir, {"open_and_read_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 = auto api_path =
utils::string::from_utf8(test_directory).substr(mount_location_.size()); 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_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) { static void read_and_write_test(remote_client &client) {
@ -500,11 +501,11 @@ TEST(remote_winfsp, all_tests) {
event_system::instance().start(); event_system::instance().start();
#if defined(_WIN32) #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_); mock_winfsp_drive drive(mount_location_);
remote_server server(config, drive, mount_location_); remote_server server(config, drive, mount_location_);
#else #else
mount_location_ = utils::path::absolute("."); mount_location_ = win_remote_dir;
mock_fuse_drive drive(mount_location_); mock_fuse_drive drive(mount_location_);
remote_fuse::remote_server server(config, drive, mount_location_); remote_fuse::remote_server server(config, drive, mount_location_);
#endif #endif
@ -534,6 +535,6 @@ TEST(remote_winfsp, all_tests) {
} }
event_system::instance().stop(); 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 } // namespace winfsp_test

View File

@ -40,6 +40,7 @@ done
PROJECT_APP_LIST=() PROJECT_APP_LIST=()
PROJECT_CMAKE_OPTS="" PROJECT_CMAKE_OPTS=""
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_IS_ALPINE=0 PROJECT_IS_ALPINE=0
PROJECT_IS_ARM64=0 PROJECT_IS_ARM64=0
PROJECT_MINGW64_COPY_DEPENDENCIES=() PROJECT_MINGW64_COPY_DEPENDENCIES=()
@ -73,6 +74,10 @@ fi
. "${PROJECT_SOURCE_DIR}/config.sh" . "${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 if [ "${PROJECT_ENABLE_SFML}" == "ON" ]; then
PROJECT_ENABLE_FLAC=ON PROJECT_ENABLE_FLAC=ON
PROJECT_ENABLE_FONTCONFIG=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_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_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_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_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_GIT_REV=${PROJECT_GIT_REV} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE} ${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_COPYRIGHT
export PROJECT_DESC export PROJECT_DESC
export PROJECT_DIST_DIR export PROJECT_DIST_DIR
export PROJECT_ENABLE_WIN32_LONG_PATH_NAMES
export PROJECT_FILE_PART export PROJECT_FILE_PART
export PROJECT_GIT_REV export PROJECT_GIT_REV
export PROJECT_IS_ALPINE export PROJECT_IS_ALPINE
@ -346,6 +353,9 @@ echo " Is MINGW on Unix: ${PROJECT_IS_MINGW_UNIX}"
echo " Is MINGW: ${PROJECT_IS_MINGW}" echo " Is MINGW: ${PROJECT_IS_MINGW}"
echo " Job count: ${NUM_JOBS}" echo " Job count: ${NUM_JOBS}"
echo " Link type: ${PROJECT_LINK_TYPE}" 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}" echo " Meson toolchain file: ${PROJECT_TOOLCHAIN_FILE_MESON}"
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then
echo " MinGW docker build args: ${PROJECT_MINGW64_DOCKER_BUILD_ARGS}" 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>; using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
#if defined(_WIN32) #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; using native_handle = HANDLE;
#else // !defined(_WIN32) #else // !defined(_WIN32)
inline constexpr const auto max_path_length = std::size_t{PATH_MAX};
using native_handle = int; using native_handle = int;
#if !defined(INVALID_HANDLE_VALUE) #if !defined(INVALID_HANDLE_VALUE)
#define INVALID_HANDLE_VALUE (-1) #define INVALID_HANDLE_VALUE (-1)

View File

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

View File

@ -24,104 +24,362 @@
#include "utils/config.hpp" #include "utils/config.hpp"
#include "utils/path.hpp"
#include <memory>
namespace repertory::utils::file { 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: public:
[[nodiscard]] static auto attach_file(native_handle handle, [[nodiscard]] virtual operator bool() const = 0;
bool read_only = false) -> file;
[[nodiscard]] static auto open_file(std::filesystem::path path, protected:
bool read_only = false) -> file; i_file() noexcept = default;
[[nodiscard]] static auto open_or_create_file(std::filesystem::path path, i_file(const i_file &) noexcept = delete;
bool read_only = false) -> file;
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: public:
file() noexcept = default; file() noexcept = default;
protected: file(std::string_view path)
file(file_t file_ptr, std::filesystem::path path) : file_(nullptr), path_(utils::path::absolute(path)) {}
: file_(std::move(file_ptr)), path_(std::move(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: public:
file(const file &) = delete; file(const file &) = delete;
file(file &&move_file) noexcept file(file &&move_file) noexcept
: file_(std::move(move_file.file_)), : 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) #if defined(_WIN32)
, ,
mtx_() mtx_(std::move(move_file.mtx_))
#endif // defined(_WIN32) #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=(const file &) noexcept -> file & = delete;
auto operator=(file &&move_file) noexcept -> file & { auto operator=(file &&move_file) noexcept -> file & {
if (&move_file != this) { if (&move_file != this) {
file_ = std::move(move_file.file_); 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_ = std::move(move_file.mtx_);
#endif // defined(_WIN32)
} }
return *this; return *this;
} }
private: [[nodiscard]] operator bool() const override { return file_ != nullptr; }
file_t file_{nullptr}; };
std::filesystem::path path_;
#if defined(_WIN32) class thread_file final : public i_file {
mutable std::recursive_mutex mtx_{}; public:
#endif // defined(_WIN32) [[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: 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, [[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, [[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset, 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, [[nodiscard]] auto
std::size_t *total_read = nullptr) -> bool; 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, [[nodiscard]] auto truncate(std::size_t size) -> bool override;
std::size_t *total_written = nullptr) -> bool;
[[nodiscard]] auto write(const unsigned char *data, std::size_t to_write, [[nodiscard]] auto
std::size_t offset, write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool; 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: 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, [[nodiscard]] auto get_file_size(std::string_view path,
std::uint64_t &file_size) -> bool; std::uint64_t &file_size) -> bool;
[[nodiscard]] auto get_file_size(std::wstring_view path, [[nodiscard]] auto get_file_size(std::wstring_view path,
std::uint64_t &file_size) -> bool; 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::string_view path) -> bool;
[[nodiscard]] auto is_directory(std::wstring_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 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_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto [[nodiscard]] auto
@ -161,6 +425,21 @@ read_json_file(std::string_view path, nlohmann::json &data,
const nlohmann::json &data) -> bool; const nlohmann::json &data) -> bool;
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#endif // defined(PROJECT_ENABLE_JSON) #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 } // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_HPP_ #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::wstring_view backslash_w{L"\\"};
inline constexpr const std::string_view dot{"."}; inline constexpr const std::string_view dot{"."};
inline constexpr const std::wstring_view dot_w{L"."}; 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::string_view dot_slash{"./"};
inline constexpr const std::wstring_view dot_slash_w{L"./"}; 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::string_view slash{"/"};
inline constexpr const std::wstring_view slash_w{L"/"}; inline constexpr const std::wstring_view slash_w{L"/"};
#if defined(_WIN32) #if defined(_WIN32)
@ -62,53 +66,6 @@ get_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
return backslash_w; 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> template <typename char_t>
[[nodiscard]] inline constexpr auto [[nodiscard]] inline constexpr auto
get_directory_seperator() -> std::basic_string_view<char_t>; 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; 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::string_view path) -> std::string;
[[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring; [[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto [[nodiscard]] inline auto
combine(std::string path, combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string; const std::vector<std::string_view> &paths) -> std::string;
[[nodiscard]] inline auto [[nodiscard]] inline auto
combine(std::wstring path, combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring; const std::vector<std::wstring_view> &paths) -> std::wstring;
[[nodiscard]] auto inline create_api_path(std::string_view path) -> std::string; [[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) [[nodiscard]] auto inline create_api_path(std::wstring_view path)
-> std::wstring; -> 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::string_view path) -> std::string;
[[nodiscard]] inline auto finalize(std::wstring_view path) -> std::wstring; [[nodiscard]] inline auto finalize(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto [[nodiscard]] auto find_program_in_path(
find_program_in_path(const std::string &name_without_extension) -> std::string; const std::string_view &name_without_extension) -> std::string;
[[nodiscard]] auto [[nodiscard]] auto
find_program_in_path(std::wstring_view name_without_extension) -> std::wstring; 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 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::string path) -> std::string;
[[nodiscard]] auto strip_to_file_name(std::wstring path) -> std::wstring; [[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> template <typename string_t>
[[nodiscard]] inline auto combine_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>> const std::vector<std::basic_string_view<typename string_t::value_type>>
&paths) -> string_t { &paths) -> string_t {
path = std::accumulate( auto dir_sep_t =
paths.begin(), paths.end(), path, [](auto next_path, auto &&path_part) { string_t{get_directory_seperator<typename string_t::value_type>()};
if (next_path.empty()) { return absolute(
return string_t{path_part}; 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 + return next_path + dir_sep_t + string_t{path_part};
string_t{ }));
get_directory_seperator<typename string_t::value_type>()} +
string_t{path_part};
});
return absolute(path);
} }
inline auto combine(std::string path, inline auto combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string { const std::vector<std::string_view> &paths) -> std::string {
return combine_t<std::string>(path, paths); return combine_t<std::string>(path, paths);
} }
inline auto inline auto
combine(std::wstring path, combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring { const std::vector<std::wstring_view> &paths) -> std::wstring {
return combine_t<std::wstring>(path, paths); return combine_t<std::wstring>(path, paths);
} }
@ -255,12 +274,20 @@ template <typename string_t>
[[nodiscard]] inline auto create_api_path_t( [[nodiscard]] inline auto create_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t { std::basic_string_view<typename string_t::value_type> path) -> string_t {
auto backslash_t = get_backslash<typename string_t::value_type>(); 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_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>(); 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 || 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}; 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); 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> template <typename string_t>
[[nodiscard]] inline auto finalize_t( [[nodiscard]] inline auto finalize_t(
std::basic_string_view<typename string_t::value_type> path) -> string_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}; string_t fmt_path{path};
format_path(fmt_path, if (fmt_path.empty()) {
get_directory_seperator<typename string_t::value_type>(), return fmt_path;
}
format_path(fmt_path, dir_sep_t,
get_not_directory_seperator<typename string_t::value_type>()); 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; return fmt_path;
} }
@ -355,6 +384,13 @@ format_path(string_t &path,
-> string_t & { -> string_t & {
utils::string::replace(path, not_sep, sep); 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)); string_t double_sep(2U, sep.at(0U));
while (utils::string::contains(path, double_sep)) { while (utils::string::contains(path, double_sep)) {
utils::string::replace(path, double_sep, sep); utils::string::replace(path, double_sep, sep);
@ -373,6 +409,24 @@ format_path(string_t &path,
return 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> template <typename string_t>
[[nodiscard]] inline auto get_parent_api_path_t( [[nodiscard]] inline auto get_parent_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t { std::basic_string_view<typename string_t::value_type> path) -> string_t {
@ -383,12 +437,12 @@ template <typename string_t>
return ret; return ret;
} }
ret = path.substr(0, path.rfind('/') + 1); ret = path.substr(0, path.rfind(slash_t) + 1);
if (ret == slash_t) { if (ret == slash_t) {
return ret; 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 { 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), stop_requested_(stop_requested),
error_return_(error_return), error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) { 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|" + throw std::runtime_error("file open failed|src|" +
std::string{source_path}); std::string{source_path});
} }
@ -190,16 +190,18 @@ encrypting_reader::encrypting_reader(
encrypted_file_name_ = utils::collection::to_hex_string(result); encrypted_file_name_ = utils::collection::to_hex_string(result);
if (relative_parent_path.has_value()) { 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( utils::encryption::encrypt_data(
key_, reinterpret_cast<const unsigned char *>(part.string().c_str()), key_, reinterpret_cast<const unsigned char *>(part.c_str()),
strnlen(part.string().c_str(), part.string().size()), result); strnlen(part.c_str(), part.size()), result);
encrypted_file_path_ += '/' + utils::collection::to_hex_string(result); encrypted_file_path_ += '/' + utils::collection::to_hex_string(result);
} }
encrypted_file_path_ += '/' + encrypted_file_name_; 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( const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)); 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), stop_requested_(stop_requested),
error_return_(error_return), error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) { 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|" + throw std::runtime_error("file open failed|src|" +
std::string{source_path}); std::string{source_path});
} }
encrypted_file_path_ = encrypted_file_path; encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ = encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
std::filesystem::path(encrypted_file_path_).filename().string();
auto file_size = source_file_.size(); auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling( const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)); file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -262,16 +263,15 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested), stop_requested_(stop_requested),
error_return_(error_return), error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) { 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|" + throw std::runtime_error("file open failed|src|" +
std::string{source_path}); std::string{source_path});
} }
encrypted_file_path_ = encrypted_file_path; encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ = encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
std::filesystem::path(encrypted_file_path_).filename().string();
auto file_size = source_file_.size(); auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling( const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)); 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_), stop_requested_(reader.stop_requested_),
error_return_(reader.error_return_), error_return_(reader.error_return_),
source_file_( 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_), chunk_buffers_(reader.chunk_buffers_),
encrypted_file_name_(reader.encrypted_file_name_), encrypted_file_name_(reader.encrypted_file_name_),
encrypted_file_path_(reader.encrypted_file_path_), 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_), last_data_chunk_size_(reader.last_data_chunk_size_),
read_offset_(reader.read_offset_), read_offset_(reader.read_offset_),
total_size_(reader.total_size_) { total_size_(reader.total_size_) {
if (not source_file_) { if (not *source_file_) {
throw std::runtime_error("file open failed|src|" + throw std::runtime_error("file open failed|src|" +
source_file_.get_path().string()); source_file_->get_path());
} }
} }
@ -359,8 +359,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
chunk_buffer.resize(file_data.size() + encryption_header_size); chunk_buffer.resize(file_data.size() + encryption_header_size);
std::size_t bytes_read{}; 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))) { &bytes_read))) {
utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data, utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data,
chunk_buffer); chunk_buffer);
} }

View File

@ -26,13 +26,127 @@
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/string.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 { 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 get_file_size(std::string_view path, std::uint64_t &file_size) -> bool {
auto abs_path = utils::path::absolute(path); 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{}; std::error_code ec{};
file_size = std::filesystem::file_size(abs_path, 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 { 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)); 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_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::string_view path, nlohmann::json &data, 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 { try {
auto abs_path = utils::path::absolute(path); auto abs_path = utils::path::absolute(path);
auto file = file::open_file(abs_path); auto file = file::open_file(abs_path);
if (not file) { if (not *file) {
return false; return false;
} }
try { try {
data_buffer buffer{}; data_buffer buffer{};
if (not file.read_all(buffer, 0U)) { if (not file->read_all(buffer, 0U)) {
return false; return false;
} }
@ -141,7 +272,7 @@ auto write_json_file(std::string_view path,
try { try {
auto file = file::open_or_create_file(path); auto file = file::open_or_create_file(path);
if (not file.truncate()) { if (not file->truncate()) {
throw std::runtime_error("failed to truncate file"); throw std::runtime_error("failed to truncate file");
} }
@ -153,13 +284,14 @@ auto write_json_file(std::string_view path,
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
*password, reinterpret_cast<const unsigned char *>(str_data.c_str()), *password, reinterpret_cast<const unsigned char *>(str_data.c_str()),
str_data.size(), encrypted_data); 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) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto json_str = data.dump(); auto json_str = data.dump();
return file.write(reinterpret_cast<const unsigned char *>(json_str.c_str()), return file->write(
json_str.size(), 0U); reinterpret_cast<const unsigned char *>(json_str.c_str()),
json_str.size(), 0U);
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {

View File

@ -27,7 +27,8 @@
#include "utils/string.hpp" #include "utils/string.hpp"
namespace repertory::utils::file { 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 constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
@ -36,13 +37,12 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
std::string path; std::string path;
#if defined(_WIN32) #if defined(_WIN32)
path.resize(MAX_PATH + 1); path.resize(repertory::max_path_length + 1);
::GetFinalPathNameByHandleA(handle, path.data(), ::GetFinalPathNameByHandleA(handle, path.data(),
static_cast<DWORD>(path.size()), static_cast<DWORD>(path.size()),
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
#else // !defined(_WIN32) #else // !defined(_WIN32)
path.resize(PATH_MAX + 1); path.resize(repertory::max_path_length + 1);
#if defined(__APPLE__) #if defined(__APPLE__)
fcntl(handle, F_GETPATH, source_path.data()); 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+"); auto *ptr = fdopen(handle, read_only ? "rb" : "rb+");
#endif // defined(_WIN32) #endif // defined(_WIN32)
return file{ return std::unique_ptr<i_file>(new file{
file_t{ptr}, file_t{ptr},
utils::path::absolute(path), utils::path::absolute(path),
}; read_only,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
utils::error::handle_exception(function_name); 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 constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
auto *ptr = new file{
nullptr,
utils::path::absolute(path),
read_only,
};
auto new_file = std::unique_ptr<i_file>(ptr);
try { try {
path = utils::path::absolute(path.string()); ptr->open();
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,
};
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
utils::error::handle_exception(function_name); utils::error::handle_exception(function_name);
} }
return {}; return new_file;
} }
auto file::open_or_create_file(std::filesystem::path path, auto file::open_or_create_file(std::string_view path,
bool read_only) -> file { bool read_only) -> std::unique_ptr<i_file> {
path = utils::path::absolute(path.string()); auto abs_path = utils::path::absolute(path);
if (not utils::file::is_file(path.string())) { if (not is_file(abs_path)) {
#if defined(_WIN32) #if defined(_WIN32)
int old_mode{}; int old_mode{};
_umask_s(077, &old_mode); _umask_s(077, &old_mode);
@ -119,36 +125,44 @@ auto file::open_or_create_file(std::filesystem::path path,
#endif // defined(_WIN32) #endif // defined(_WIN32)
#if 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) #else // !defined(_WIN32)
auto *ptr = fopen(path.string().c_str(), "ab+"); auto *ptr = fopen(abs_path.c_str(), "ab+");
#endif // defined(_WIN32) #endif // defined(_WIN32)
if (ptr != nullptr) {
fclose(ptr);
}
#if defined(_WIN32) #if defined(_WIN32)
_umask_s(old_mode, nullptr); _umask_s(old_mode, nullptr);
#else // !defined(_WIN32) #else // !defined(_WIN32)
umask(old_mode); umask(old_mode);
#endif // defined(_WIN32) #endif // defined(_WIN32)
if (ptr != nullptr) {
fclose(ptr);
}
} }
return open_file(path, read_only); return open_file(abs_path, read_only);
} }
void file::close() { void file::close() {
#if defined(_WIN32) #if defined(_WIN32)
recur_mutex_lock lock{mtx_}; recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32) #endif // defined(_WIN32)
file_.reset(); file_.reset();
} }
void file::flush() { auto file::exists() const -> bool {
#if defined(_WIN32) #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) #endif // defined(_WIN32)
if (file_) { if (file_) {
@ -157,6 +171,10 @@ void file::flush() {
} }
auto file::get_handle() const -> native_handle { auto file::get_handle() const -> native_handle {
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (file_) { if (file_) {
#if defined(_WIN32) #if defined(_WIN32)
return reinterpret_cast<native_handle>( return reinterpret_cast<native_handle>(
@ -169,12 +187,16 @@ auto file::get_handle() const -> native_handle {
return INVALID_HANDLE_VALUE; 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) #if defined(_WIN32)
recur_mutex_lock lock{mtx_}; recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32) #endif // defined(_WIN32)
new_path = utils::path::absolute(new_path.string()); auto abs_path = utils::path::absolute(path);
auto reopen{false}; auto reopen{false};
if (file_) { if (file_) {
@ -182,19 +204,29 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
close(); 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::error_code ec{};
std::filesystem::rename(path_, new_path, ec); std::filesystem::rename(path_, abs_path, ec);
if (not ec) { success = ec.value() == 0;
path_ = new_path; #endif // defined(_WIN32)
if (reopen) {
*this = open_file(path_);
}
return true; if (success) {
path_ = abs_path;
} }
if (reopen) { 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; 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, auto file::read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool { std::size_t *total_read) -> bool {
#if defined(_WIN32) #if defined(_WIN32)
recur_mutex_lock lock{mtx_}; recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32) #endif // defined(_WIN32)
data_buffer buffer; data_buffer buffer;
buffer.resize(65536U); buffer.resize(read_buffer_size);
std::size_t current_read{}; std::size_t current_read{};
while (read(reinterpret_cast<unsigned char *>(buffer.data()), 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, auto file::read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool { std::size_t *total_read) -> bool {
#if defined(_WIN32) #if defined(_WIN32)
recur_mutex_lock lock{mtx_}; recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32) #endif // defined(_WIN32)
std::size_t bytes_read{}; 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, auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
std::size_t *total_read) -> bool { 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 constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (total_read != nullptr) { if (total_read != nullptr) {
(*total_read) = 0U; (*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 { auto file::remove() -> bool {
#if defined(_WIN32) #if defined(_WIN32)
recur_mutex_lock lock{mtx_}; recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32) #endif // defined(_WIN32)
close(); close();
if (not exists()) {
return true;
}
#if defined(_WIN32)
return !!::DeleteFileA(path_.c_str());
#else // !defined(_WIN32)
std::error_code ec{}; std::error_code ec{};
return std::filesystem::remove(path_, ec); return std::filesystem::remove(path_, ec);
#endif // defined(_WIN32)
} }
auto file::truncate(std::size_t size) -> bool { auto file::truncate(std::size_t size) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32) #if defined(_WIN32)
recur_mutex_lock lock{mtx_}; recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32) #endif // defined(_WIN32)
auto reopen{false}; auto reopen{false};
@ -320,23 +364,34 @@ auto file::truncate(std::size_t size) -> bool {
std::error_code ec{}; std::error_code ec{};
std::filesystem::resize_file(path_, size, ec); std::filesystem::resize_file(path_, size, ec);
auto success{ec.value() == 0};
if (reopen) { 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, auto file::write(const unsigned char *data, std::size_t to_write,
std::size_t offset, std::size_t *total_written) -> bool { 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 constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (total_written != nullptr) { if (total_written != nullptr) {
(*total_written) = 0U; (*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 { 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 constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
try { try {
if (file_) { if (file_) {
if (fseeko(file_.get(), 0, SEEK_END) == -1) { 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); 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) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } 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/common.hpp"
#include "utils/error.hpp" #include "utils/error.hpp"
#include "utils/file.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/unix.hpp" #include "utils/unix.hpp"
namespace { 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 { [[nodiscard]] auto resolve(std::string path) -> std::string {
#if defined(_WIN32) #if defined(_WIN32)
if (repertory::utils::string::contains(path, "~") || if (repertory::utils::string::contains(path, "~") ||
@ -52,12 +45,17 @@ static const std::wstring directory_seperator_str_w{
#else // !defined (_WIN32) #else // !defined (_WIN32)
if (repertory::utils::string::contains(path, "~")) { if (repertory::utils::string::contains(path, "~")) {
std::string home{}; std::string home{};
repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) { auto res =
home = (pw->pw_dir ? pw->pw_dir : ""); repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) {
if (home.empty() || ((home == "/") && (getuid() != 0))) { home = (pw->pw_dir ? pw->pw_dir : "");
home = repertory::utils::path::combine("/home", {pw->pw_name}); 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); return repertory::utils::string::replace(path, "~", home);
} }
@ -70,36 +68,44 @@ static const std::wstring directory_seperator_str_w{
namespace repertory::utils::path { namespace repertory::utils::path {
auto absolute(std::string_view path) -> std::string { auto absolute(std::string_view path) -> std::string {
std::string abs_path{path}; std::string abs_path{path};
abs_path = resolve(abs_path); if (abs_path.empty()) {
format_path(abs_path, directory_seperator, not_directory_seperator); return abs_path;
}
abs_path = finalize(resolve(abs_path));
#if defined(_WIN32) #if defined(_WIN32)
if (not abs_path.empty() && ::PathIsRelativeA(abs_path.c_str())) { if (not utils::string::contains(abs_path, dot)) {
std::string temp; return abs_path;
temp.resize(MAX_PATH + 1);
abs_path = _fullpath(temp.data(), abs_path.c_str(), MAX_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) #else // !defined(_WIN32)
if (not abs_path.empty() && (abs_path.at(0U) != '/')) { if (not utils::string::contains(abs_path, dot) ||
auto found{false}; utils::string::begins_with(abs_path, slash)) {
std::string tmp{abs_path}; return 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());
free(res);
found = true;
} else if (tmp == ".") {
found = true;
} else {
tmp = dirname(tmp.data());
}
} while (not found);
} }
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());
free(res);
found = true;
} else if (tmp == dot) {
found = true;
} else {
tmp = dirname(tmp.data());
}
} while (not found);
#endif // defined(_WIN32) #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 { 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) { for (auto &&extension : extension_list) {
auto exec_path = combine( auto exec_path = combine(
search_path, {name_without_extension + std::string{extension}}); 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; found_items[name_without_extension] = exec_path;
return 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 get_parent_directory(std::string_view path) -> std::string {
auto ret = std::filesystem::path{path}.parent_path().string(); auto abs_path = absolute(path);
#if !defined(_WIN32)
if (ret == ".") {
ret = "/";
}
#endif // !defined(_WIN32)
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 { 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 { 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)); auto trash_path = utils::string::to_lower(absolute(path));
return utils::string::begins_with(trash_path, return utils::string::begins_with(trash_path, dir_sep_t + ".trash-") ||
directory_seperator_str + ".trash-") || utils::string::begins_with(trash_path, dir_sep_t + ".trashes") ||
utils::string::begins_with(trash_path, utils::string::begins_with(trash_path, dir_sep_t + "$recycle.bin");
directory_seperator_str + ".trashes") ||
utils::string::begins_with(trash_path,
directory_seperator_str + "$recycle.bin");
} }
auto is_trash_directory(std::wstring_view path) -> bool { 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 make_file_uri(std::string_view path) -> std::string {
auto abs_path = absolute(path); auto abs_path = absolute(path);
#if defined(_WIN32) #if defined(_WIN32)
utils::string::replace(abs_path, '\\', '/'); utils::string::replace(abs_path, backslash, slash);
abs_path = '/' + abs_path; abs_path = std::string{slash} + abs_path;
#endif // defined(_WIN32) #endif // defined(_WIN32)
return "file://" + abs_path; 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))); 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 { auto strip_to_file_name(std::string path) -> std::string {
#if defined(_WIN32) #if defined(_WIN32)
return ::PathFindFileNameA(path.c_str()); return ::PathFindFileNameA(path.c_str());
#else // !defined(_WIN32) #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) #endif // defined(_WIN32)
} }

View File

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

View File

@ -38,7 +38,8 @@ using namespace ::testing;
namespace repertory::test { namespace repertory::test {
#if defined(PROJECT_ENABLE_LIBSODIUM) #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) #endif // defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto [[nodiscard]] auto

View File

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

View File

@ -273,7 +273,7 @@ TEST(utils_common, get_environment_variable) {
std::string path; std::string path;
#if defined(_WIN32) #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); auto size = ::GetEnvironmentVariableA(path_env.c_str(), path.data(), 0U);
path.resize(size); path.resize(size);

View File

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

View File

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

View File

@ -21,12 +21,38 @@
*/ */
#include "test.hpp" #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 { namespace repertory {
TEST(utils_path, constants) { TEST(utils_path, constants) {
EXPECT_EQ(std::string_view{"\\"}, utils::path::backslash); EXPECT_EQ(std::string_view{"\\"}, utils::path::backslash);
EXPECT_EQ(std::wstring_view{L"\\"}, utils::path::backslash_w); EXPECT_EQ(std::wstring_view{L"\\"}, utils::path::backslash_w);
EXPECT_EQ(std::string_view{"."}, utils::path::dot); EXPECT_EQ(std::string_view{"."}, utils::path::dot);
EXPECT_EQ(std::wstring_view{L"."}, utils::path::dot_w); 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::string_view{"./"}, utils::path::dot_slash);
EXPECT_EQ(std::wstring_view{L"./"}, utils::path::dot_slash_w); EXPECT_EQ(std::wstring_view{L"./"}, utils::path::dot_slash_w);
EXPECT_EQ(std::string_view{"/"}, utils::path::slash); 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>()); 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) { TEST(utils_path, get_dot_slash) {
EXPECT_EQ(utils::path::dot_slash, utils::path::get_dot_slash<char>()); 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>()); 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>()); 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) { TEST(utils_path, combine) {
auto s = utils::path::combine(R"(\test\path)", {}); auto s = utils::path::combine(R"(\test\path)", {});
#if defined(_WIN32) #if defined(_WIN32)
EXPECT_STREQ(R"(\test\path)", s.c_str()); EXPECT_STREQ(test_path(R"(\test\path)").c_str(), s.c_str());
#else #else
EXPECT_STREQ("/test/path", s.c_str()); EXPECT_STREQ("/test/path", s.c_str());
#endif #endif
s = utils::path::combine(R"(\test)", {R"(\path)"}); s = utils::path::combine(R"(\test)", {R"(\path)"});
#if defined(_WIN32) #if defined(_WIN32)
EXPECT_STREQ(R"(\test\path)", s.c_str()); EXPECT_STREQ(test_path(R"(\test\path)").c_str(), s.c_str());
#else #else
EXPECT_STREQ("/test/path", s.c_str()); EXPECT_STREQ("/test/path", s.c_str());
#endif #endif
s = utils::path::combine(R"(\test)", {R"(\path)", R"(\again\)"}); s = utils::path::combine(R"(\test)", {R"(\path)", R"(\again\)"});
#if defined(_WIN32) #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 #else
EXPECT_STREQ("/test/path/again", s.c_str()); EXPECT_STREQ("/test/path/again", s.c_str());
#endif #endif
s = utils::path::combine("/home/test/.dest", {".state"}); s = utils::path::combine("/home/test/.dest", {".state"});
#if defined(_WIN32) #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 #else
EXPECT_STREQ("/home/test/.dest/.state", s.c_str()); EXPECT_STREQ("/home/test/.dest/.state", s.c_str());
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
s = utils::path::combine(R"(R:\test)", {R"(\path)", R"(\again\)"}); 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\)"}); 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:", {}); 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:", {"\\"}); s = utils::path::combine("R:", {"\\"});
EXPECT_STREQ("r:", s.c_str()); EXPECT_STREQ(test_path("r:").c_str(), s.c_str());
#endif #endif
} }
@ -224,104 +262,116 @@ TEST(utils_path, finalize) {
s = utils::path::finalize(R"(\)"); s = utils::path::finalize(R"(\)");
#if defined(_WIN32) #if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str()); EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else #else
EXPECT_STREQ("/", s.c_str()); EXPECT_STREQ("/", s.c_str());
#endif #endif
s = utils::path::finalize("/"); s = utils::path::finalize("/");
#if defined(_WIN32) #if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str()); EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else #else
EXPECT_STREQ("/", s.c_str()); EXPECT_STREQ("/", s.c_str());
#endif #endif
s = utils::path::finalize(R"(\\)"); s = utils::path::finalize(R"(\\)");
#if defined(_WIN32) #if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str()); EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else #else
EXPECT_STREQ("/", s.c_str()); EXPECT_STREQ("/", s.c_str());
#endif #endif
s = utils::path::finalize("//"); s = utils::path::finalize("//");
#if defined(_WIN32) #if defined(_WIN32)
EXPECT_STREQ(R"(\)", s.c_str()); EXPECT_STREQ(test_path(R"(\)").c_str(), s.c_str());
#else #else
EXPECT_STREQ("/", s.c_str()); EXPECT_STREQ("/", s.c_str());
#endif #endif
s = utils::path::finalize("/cow///moose/////dog/chicken"); s = utils::path::finalize("/cow///moose/////dog/chicken");
#if defined(_WIN32) #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 #else
EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str());
#endif #endif
s = utils::path::finalize("\\cow\\\\\\moose\\\\\\\\dog\\chicken/"); s = utils::path::finalize("\\cow\\\\\\moose\\\\\\\\dog\\chicken/");
#if defined(_WIN32) #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 #else
EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str());
#endif #endif
s = utils::path::finalize("/cow\\\\/moose\\\\/\\dog\\chicken\\"); s = utils::path::finalize("/cow\\\\/moose\\\\/\\dog\\chicken\\");
#if defined(_WIN32) #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 #else
EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str());
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
s = utils::path::finalize("D:"); 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:\\"); 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"); 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\\"); 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:/"); 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"); 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/"); 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) #endif // defined(_WIN32)
} }
TEST(utils_path, absolute) { 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("."); auto path = utils::path::absolute(".");
EXPECT_STREQ(dir.c_str(), path.c_str()); EXPECT_STREQ(dir.c_str(), path.c_str());
path = utils::path::absolute("./"); path = utils::path::absolute("./");
EXPECT_STREQ(dir.c_str(), path.c_str()); EXPECT_STREQ(dir.c_str(), path.c_str());
path = utils::path::absolute(R"(.\)");
EXPECT_STREQ(dir.c_str(), path.c_str());
#if defined(_WIN32) #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"); auto home_env = utils::get_environment_variable("USERPROFILE");
#else // !defined(_WIN32) #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"); auto home_env = utils::get_environment_variable("HOME");
#endif // defined(_WIN32) #endif // defined(_WIN32)
auto home = utils::path::absolute(home_env); auto home = utils::path::absolute(home_env);
path = utils::path::absolute("~"); path = utils::path::absolute("~");
EXPECT_STREQ(home.c_str(), path.c_str()); EXPECT_STREQ(home.c_str(), path.c_str());
// path = utils::path::absolute("~/.local");
} }
TEST(utils_path, absolute_can_resolve_path_variables) { TEST(utils_path, absolute_can_resolve_path_variables) {
std::string home{}; std::string home{};
#if defined(_WIN32) #if defined(_WIN32)
home.resize(MAX_PATH + 1U); home.resize(repertory::max_path_length + 1U);
auto size = ::GetEnvironmentVariableA("USERPROFILE", home.data(), 0U); auto size = ::GetEnvironmentVariableA("USERPROFILE", home.data(), 0U);
home.resize(size); home.resize(size);