updated build system
This commit is contained in:
@ -178,7 +178,7 @@ encrypting_reader::encrypting_reader(
|
||||
stop_requested_(stop_requested),
|
||||
error_return_(error_return),
|
||||
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||
if (not source_file_) {
|
||||
if (not *source_file_) {
|
||||
throw std::runtime_error("file open failed|src|" +
|
||||
std::string{source_path});
|
||||
}
|
||||
@ -190,16 +190,18 @@ encrypting_reader::encrypting_reader(
|
||||
encrypted_file_name_ = utils::collection::to_hex_string(result);
|
||||
|
||||
if (relative_parent_path.has_value()) {
|
||||
for (auto &&part : std::filesystem::path(relative_parent_path.value())) {
|
||||
for (auto &&part :
|
||||
utils::string::split(relative_parent_path.value(),
|
||||
utils::path::directory_seperator, false)) {
|
||||
utils::encryption::encrypt_data(
|
||||
key_, reinterpret_cast<const unsigned char *>(part.string().c_str()),
|
||||
strnlen(part.string().c_str(), part.string().size()), result);
|
||||
key_, reinterpret_cast<const unsigned char *>(part.c_str()),
|
||||
strnlen(part.c_str(), part.size()), result);
|
||||
encrypted_file_path_ += '/' + utils::collection::to_hex_string(result);
|
||||
}
|
||||
encrypted_file_path_ += '/' + encrypted_file_name_;
|
||||
}
|
||||
|
||||
auto file_size = source_file_.size();
|
||||
auto file_size = source_file_->size();
|
||||
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
@ -225,16 +227,15 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
|
||||
stop_requested_(stop_requested),
|
||||
error_return_(error_return),
|
||||
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||
if (not source_file_) {
|
||||
if (not *source_file_) {
|
||||
throw std::runtime_error("file open failed|src|" +
|
||||
std::string{source_path});
|
||||
}
|
||||
|
||||
encrypted_file_path_ = encrypted_file_path;
|
||||
encrypted_file_name_ =
|
||||
std::filesystem::path(encrypted_file_path_).filename().string();
|
||||
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
|
||||
|
||||
auto file_size = source_file_.size();
|
||||
auto file_size = source_file_->size();
|
||||
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
@ -262,16 +263,15 @@ encrypting_reader::encrypting_reader(
|
||||
stop_requested_(stop_requested),
|
||||
error_return_(error_return),
|
||||
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||
if (not source_file_) {
|
||||
if (not *source_file_) {
|
||||
throw std::runtime_error("file open failed|src|" +
|
||||
std::string{source_path});
|
||||
}
|
||||
|
||||
encrypted_file_path_ = encrypted_file_path;
|
||||
encrypted_file_name_ =
|
||||
std::filesystem::path(encrypted_file_path_).filename().string();
|
||||
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
|
||||
|
||||
auto file_size = source_file_.size();
|
||||
auto file_size = source_file_->size();
|
||||
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
@ -289,7 +289,7 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
|
||||
stop_requested_(reader.stop_requested_),
|
||||
error_return_(reader.error_return_),
|
||||
source_file_(
|
||||
utils::file::file::open_file(reader.source_file_.get_path(), true)),
|
||||
utils::file::file::open_file(reader.source_file_->get_path(), true)),
|
||||
chunk_buffers_(reader.chunk_buffers_),
|
||||
encrypted_file_name_(reader.encrypted_file_name_),
|
||||
encrypted_file_path_(reader.encrypted_file_path_),
|
||||
@ -298,9 +298,9 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
|
||||
last_data_chunk_size_(reader.last_data_chunk_size_),
|
||||
read_offset_(reader.read_offset_),
|
||||
total_size_(reader.total_size_) {
|
||||
if (not source_file_) {
|
||||
if (not *source_file_) {
|
||||
throw std::runtime_error("file open failed|src|" +
|
||||
source_file_.get_path().string());
|
||||
source_file_->get_path());
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,8 +359,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
|
||||
chunk_buffer.resize(file_data.size() + encryption_header_size);
|
||||
|
||||
std::size_t bytes_read{};
|
||||
if ((ret = source_file_.read(file_data, chunk * data_chunk_size_,
|
||||
&bytes_read))) {
|
||||
if ((ret = source_file_->read(file_data, chunk * data_chunk_size_,
|
||||
&bytes_read))) {
|
||||
utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data,
|
||||
chunk_buffer);
|
||||
}
|
||||
|
@ -26,13 +26,129 @@
|
||||
#include "utils/path.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace {
|
||||
[[nodiscard]] auto remove_directory_recursively(std::string_view path) -> bool {
|
||||
#if defined(_WIN32)
|
||||
WIN32_FIND_DATA fd{};
|
||||
auto search = repertory::utils::path::combine(path, {"*.*"});
|
||||
auto find = ::FindFirstFileA(search.c_str(), &fd);
|
||||
if (find != INVALID_HANDLE_VALUE) {
|
||||
auto res{true};
|
||||
do {
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
if ((std::string(fd.cFileName) != ".") &&
|
||||
(std::string(fd.cFileName) != "..")) {
|
||||
res = remove_directory_recursively(
|
||||
repertory::utils::path::combine(path, {fd.cFileName}));
|
||||
}
|
||||
} else {
|
||||
res = repertory::utils::file::file(
|
||||
repertory::utils::path::combine(path, {fd.cFileName}))
|
||||
.remove();
|
||||
}
|
||||
} while (res && (::FindNextFileA(find, &fd) != 0));
|
||||
|
||||
::FindClose(find);
|
||||
}
|
||||
#else
|
||||
auto *root = opendir(std::string{path}.c_str());
|
||||
if (root != nullptr) {
|
||||
auto res{true};
|
||||
struct dirent *de{};
|
||||
while (res && (de = readdir(root))) {
|
||||
if (de->d_type == DT_DIR) {
|
||||
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
|
||||
res = remove_directory_recursively(
|
||||
repertory::utils::path::combine(path, {de->d_name}));
|
||||
}
|
||||
} else {
|
||||
res = repertory::utils::file::file(
|
||||
repertory::utils::path::combine(path, {de->d_name}))
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
|
||||
closedir(root);
|
||||
}
|
||||
#endif
|
||||
|
||||
return repertory::utils::file::remove_directory(path, false);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace repertory::utils::file {
|
||||
auto create_directories(std::string_view path) -> bool {
|
||||
#if defined(_WIN32)
|
||||
return is_directory(path) ||
|
||||
(::SHCreateDirectory(
|
||||
nullptr,
|
||||
utils::string::from_utf8(utils::path::absolute(path)).c_str()) ==
|
||||
ERROR_SUCCESS);
|
||||
#else // !defined(_WIN32)
|
||||
auto ret{true};
|
||||
auto paths = utils::string::split(utils::path::absolute(path),
|
||||
utils::path::directory_seperator, false);
|
||||
|
||||
std::string current_path;
|
||||
for (std::size_t idx = 0U; ret && (idx < paths.size()); idx++) {
|
||||
if (paths.at(idx).empty()) {
|
||||
current_path = utils::path::directory_seperator;
|
||||
continue;
|
||||
}
|
||||
|
||||
current_path = utils::path::combine(current_path, {paths.at(idx)});
|
||||
auto status = mkdir(current_path.c_str(), S_IRWXU);
|
||||
ret = ((status == 0) || (errno == EEXIST));
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
auto create_directories(std::wstring_view path) -> bool {
|
||||
return create_directories(utils::string::to_utf8(path));
|
||||
}
|
||||
|
||||
auto directory_exists_in_path(std::string_view path,
|
||||
std::string_view sub_directory) -> bool {
|
||||
return directory_exists_in_path_t<std::string>(path, sub_directory);
|
||||
}
|
||||
|
||||
auto directory_exists_in_path(std::wstring_view path,
|
||||
std::wstring_view sub_directory) -> bool {
|
||||
return directory_exists_in_path_t<std::wstring>(path, sub_directory);
|
||||
}
|
||||
|
||||
auto file_exists_in_path(std::string_view path,
|
||||
std::string_view file_name) -> bool {
|
||||
return file_exists_in_path_t<std::string>(path, file_name);
|
||||
}
|
||||
|
||||
auto file_exists_in_path(std::wstring_view path,
|
||||
std::wstring_view file_name) -> bool {
|
||||
return file_exists_in_path_t<std::wstring>(path, file_name);
|
||||
}
|
||||
|
||||
auto get_file_size(std::string_view path, std::uint64_t &file_size) -> bool {
|
||||
auto abs_path = utils::path::absolute(path);
|
||||
file_size = 0U;
|
||||
|
||||
#if defined(_WIN32)
|
||||
struct _stat64 st {};
|
||||
auto res = _stat64(std::string{path}.c_str(), &st);
|
||||
if (res != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file_size = static_cast<std::uint64_t>(st.st_size);
|
||||
#else // !defined(_WIN32)
|
||||
std::error_code ec{};
|
||||
file_size = std::filesystem::file_size(abs_path, ec);
|
||||
return ec.value() == 0;
|
||||
if (not ec) {
|
||||
return false;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto get_file_size(std::wstring_view path, std::uint64_t &file_size) -> bool {
|
||||
@ -70,6 +186,23 @@ auto is_file(std::wstring_view path) -> bool {
|
||||
return is_file(utils::string::to_utf8(path));
|
||||
}
|
||||
|
||||
auto remove_directory(std::string_view path, bool recursive) -> bool {
|
||||
auto abs_path = utils::path::absolute(path);
|
||||
if (recursive) {
|
||||
return remove_directory_recursively(abs_path);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
return (not is_directory(abs_path) || ::RemoveDirectoryA(abs_path.c_str()));
|
||||
#else // !defined(_WIN32)
|
||||
return not is_directory(abs_path) || (rmdir(abs_path.c_str()) == 0);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
auto remove_directory(std::wstring_view path, bool recursive) -> bool {
|
||||
return remove_directory(utils::string::to_utf8(path), recursive);
|
||||
}
|
||||
|
||||
#if defined(PROJECT_ENABLE_JSON)
|
||||
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||
auto read_json_file(std::string_view path, nlohmann::json &data,
|
||||
@ -84,13 +217,13 @@ auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
|
||||
try {
|
||||
auto abs_path = utils::path::absolute(path);
|
||||
auto file = file::open_file(abs_path);
|
||||
if (not file) {
|
||||
if (not *file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
data_buffer buffer{};
|
||||
if (not file.read_all(buffer, 0U)) {
|
||||
if (not file->read_all(buffer, 0U)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,7 +274,7 @@ auto write_json_file(std::string_view path,
|
||||
|
||||
try {
|
||||
auto file = file::open_or_create_file(path);
|
||||
if (not file.truncate()) {
|
||||
if (not file->truncate()) {
|
||||
throw std::runtime_error("failed to truncate file");
|
||||
}
|
||||
|
||||
@ -153,13 +286,14 @@ auto write_json_file(std::string_view path,
|
||||
utils::encryption::encrypt_data(
|
||||
*password, reinterpret_cast<const unsigned char *>(str_data.c_str()),
|
||||
str_data.size(), encrypted_data);
|
||||
return file.write(encrypted_data, 0U);
|
||||
return file->write(encrypted_data, 0U);
|
||||
}
|
||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||
|
||||
auto json_str = data.dump();
|
||||
return file.write(reinterpret_cast<const unsigned char *>(json_str.c_str()),
|
||||
json_str.size(), 0U);
|
||||
return file->write(
|
||||
reinterpret_cast<const unsigned char *>(json_str.c_str()),
|
||||
json_str.size(), 0U);
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
} catch (...) {
|
||||
|
@ -27,7 +27,8 @@
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace repertory::utils::file {
|
||||
auto file::attach_file(native_handle handle, bool read_only) -> file {
|
||||
auto file::attach_file(native_handle handle,
|
||||
bool read_only) -> std::unique_ptr<i_file> {
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
@ -36,13 +37,12 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
|
||||
std::string path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
path.resize(MAX_PATH + 1);
|
||||
|
||||
path.resize(repertory::max_path_length + 1);
|
||||
::GetFinalPathNameByHandleA(handle, path.data(),
|
||||
static_cast<DWORD>(path.size()),
|
||||
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
|
||||
#else // !defined(_WIN32)
|
||||
path.resize(PATH_MAX + 1);
|
||||
path.resize(repertory::max_path_length + 1);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
fcntl(handle, F_GETPATH, source_path.data());
|
||||
@ -63,54 +63,60 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
|
||||
auto *ptr = fdopen(handle, read_only ? "rb" : "rb+");
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return file{
|
||||
return std::unique_ptr<i_file>(new file{
|
||||
file_t{ptr},
|
||||
utils::path::absolute(path),
|
||||
};
|
||||
read_only,
|
||||
});
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
} catch (...) {
|
||||
utils::error::handle_exception(function_name);
|
||||
}
|
||||
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto file::open_file(std::filesystem::path path, bool read_only) -> file {
|
||||
void file::open() {
|
||||
if (not is_file(path_)) {
|
||||
throw std::runtime_error("file not found: " + path_);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
file_.reset(_fsopen(path_.c_str(), read_only_ ? "rb" : "rb+", _SH_DENYNO));
|
||||
#else // !defined(_WIN32)
|
||||
file_.reset(fopen(path_.c_str(), read_only_ ? "rb" : "rb+"));
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
auto file::open_file(std::string_view path,
|
||||
bool read_only) -> std::unique_ptr<i_file> {
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
|
||||
auto *ptr = new file{
|
||||
nullptr,
|
||||
utils::path::absolute(path),
|
||||
read_only,
|
||||
};
|
||||
auto new_file = std::unique_ptr<i_file>(ptr);
|
||||
|
||||
try {
|
||||
path = utils::path::absolute(path.string());
|
||||
if (not is_file(path.string())) {
|
||||
throw std::runtime_error("file not found: " + path.string());
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
auto *ptr =
|
||||
_fsopen(path.string().c_str(), read_only ? "rb" : "rb+", _SH_DENYNO);
|
||||
#else // !defined(_WIN32)
|
||||
auto *ptr = fopen(path.string().c_str(), read_only ? "rb" : "rb+");
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return file{
|
||||
file_t{ptr},
|
||||
path,
|
||||
};
|
||||
ptr->open();
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
} catch (...) {
|
||||
utils::error::handle_exception(function_name);
|
||||
}
|
||||
|
||||
return {};
|
||||
return new_file;
|
||||
}
|
||||
|
||||
auto file::open_or_create_file(std::filesystem::path path,
|
||||
bool read_only) -> file {
|
||||
path = utils::path::absolute(path.string());
|
||||
if (not utils::file::is_file(path.string())) {
|
||||
auto file::open_or_create_file(std::string_view path,
|
||||
bool read_only) -> std::unique_ptr<i_file> {
|
||||
auto abs_path = utils::path::absolute(path);
|
||||
if (not is_file(abs_path)) {
|
||||
#if defined(_WIN32)
|
||||
int old_mode{};
|
||||
_umask_s(077, &old_mode);
|
||||
@ -119,36 +125,44 @@ auto file::open_or_create_file(std::filesystem::path path,
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#if defined(_WIN32)
|
||||
auto *ptr = _fsopen(path.string().c_str(), "ab+", _SH_DENYNO);
|
||||
auto *ptr = _fsopen(abs_path.c_str(), "ab+", _SH_DENYNO);
|
||||
#else // !defined(_WIN32)
|
||||
auto *ptr = fopen(path.string().c_str(), "ab+");
|
||||
auto *ptr = fopen(abs_path.c_str(), "ab+");
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
if (ptr != nullptr) {
|
||||
fclose(ptr);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
_umask_s(old_mode, nullptr);
|
||||
#else // !defined(_WIN32)
|
||||
umask(old_mode);
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
if (ptr != nullptr) {
|
||||
fclose(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return open_file(path, read_only);
|
||||
return open_file(abs_path, read_only);
|
||||
}
|
||||
|
||||
void file::close() {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
file_.reset();
|
||||
}
|
||||
|
||||
void file::flush() {
|
||||
auto file::exists() const -> bool {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return is_file(path_);
|
||||
}
|
||||
|
||||
void file::flush() const {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
if (file_) {
|
||||
@ -157,6 +171,10 @@ void file::flush() {
|
||||
}
|
||||
|
||||
auto file::get_handle() const -> native_handle {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
if (file_) {
|
||||
#if defined(_WIN32)
|
||||
return reinterpret_cast<native_handle>(
|
||||
@ -169,12 +187,16 @@ auto file::get_handle() const -> native_handle {
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
auto file::move_to(std::filesystem::path new_path) -> bool {
|
||||
auto file::move_to(std::string_view path) -> bool {
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
new_path = utils::path::absolute(new_path.string());
|
||||
auto abs_path = utils::path::absolute(path);
|
||||
|
||||
auto reopen{false};
|
||||
if (file_) {
|
||||
@ -182,19 +204,29 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
|
||||
close();
|
||||
}
|
||||
|
||||
auto success{false};
|
||||
#if defined(_WIN32)
|
||||
success = !!::MoveFileExA(path_.c_str(), abs_path.c_str(),
|
||||
MOVEFILE_REPLACE_EXISTING);
|
||||
#else // !// defined(_WIN32)
|
||||
std::error_code ec{};
|
||||
std::filesystem::rename(path_, new_path, ec);
|
||||
if (not ec) {
|
||||
path_ = new_path;
|
||||
if (reopen) {
|
||||
*this = open_file(path_);
|
||||
}
|
||||
std::filesystem::rename(path_, abs_path, ec);
|
||||
success = ec.value() == 0;
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return true;
|
||||
if (success) {
|
||||
path_ = abs_path;
|
||||
}
|
||||
|
||||
if (reopen) {
|
||||
*this = open_file(path_);
|
||||
try {
|
||||
open();
|
||||
return success;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
} catch (...) {
|
||||
utils::error::handle_exception(function_name);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -203,11 +235,11 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
|
||||
auto file::read_all(data_buffer &data, std::uint64_t offset,
|
||||
std::size_t *total_read) -> bool {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
data_buffer buffer;
|
||||
buffer.resize(65536U);
|
||||
buffer.resize(read_buffer_size);
|
||||
|
||||
std::size_t current_read{};
|
||||
while (read(reinterpret_cast<unsigned char *>(buffer.data()),
|
||||
@ -237,7 +269,7 @@ auto file::read_all(data_buffer &data, std::uint64_t offset,
|
||||
auto file::read(data_buffer &data, std::uint64_t offset,
|
||||
std::size_t *total_read) -> bool {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
std::size_t bytes_read{};
|
||||
@ -255,14 +287,14 @@ auto file::read(data_buffer &data, std::uint64_t offset,
|
||||
|
||||
auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
|
||||
std::size_t *total_read) -> bool {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
if (total_read != nullptr) {
|
||||
(*total_read) = 0U;
|
||||
}
|
||||
@ -298,18 +330,30 @@ auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
|
||||
|
||||
auto file::remove() -> bool {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
close();
|
||||
|
||||
if (not exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
return !!::DeleteFileA(path_.c_str());
|
||||
#else // !defined(_WIN32)
|
||||
std::error_code ec{};
|
||||
return std::filesystem::remove(path_, ec);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
auto file::truncate(std::size_t size) -> bool {
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
auto reopen{false};
|
||||
@ -320,23 +364,34 @@ auto file::truncate(std::size_t size) -> bool {
|
||||
|
||||
std::error_code ec{};
|
||||
std::filesystem::resize_file(path_, size, ec);
|
||||
|
||||
auto success{ec.value() == 0};
|
||||
|
||||
if (reopen) {
|
||||
*this = open_file(path_);
|
||||
try {
|
||||
open();
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
success = false;
|
||||
} catch (...) {
|
||||
utils::error::handle_exception(function_name);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ec.value() == 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
auto file::write(const unsigned char *data, std::size_t to_write,
|
||||
std::size_t offset, std::size_t *total_written) -> bool {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
if (total_written != nullptr) {
|
||||
(*total_written) = 0U;
|
||||
}
|
||||
@ -374,14 +429,14 @@ auto file::write(const unsigned char *data, std::size_t to_write,
|
||||
}
|
||||
|
||||
auto file::size() const -> std::uint64_t {
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
static constexpr const std::string_view function_name{
|
||||
static_cast<const char *>(__FUNCTION__),
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
recur_mutex_lock lock{*mtx_};
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
try {
|
||||
if (file_) {
|
||||
if (fseeko(file_.get(), 0, SEEK_END) == -1) {
|
||||
@ -395,6 +450,13 @@ auto file::size() const -> std::uint64_t {
|
||||
|
||||
return static_cast<std::uint64_t>(size);
|
||||
}
|
||||
|
||||
std::uint64_t size{};
|
||||
if (not get_file_size(path_, size)) {
|
||||
throw std::runtime_error("failed to get file size");
|
||||
}
|
||||
|
||||
return size;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
} catch (...) {
|
||||
|
64
support/src/utils/file_thread_file.cpp
Normal file
64
support/src/utils/file_thread_file.cpp
Normal 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
|
@ -23,18 +23,11 @@
|
||||
|
||||
#include "utils/common.hpp"
|
||||
#include "utils/error.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/string.hpp"
|
||||
#include "utils/unix.hpp"
|
||||
|
||||
namespace {
|
||||
static const std::string directory_seperator_str{
|
||||
repertory::utils::path::directory_seperator,
|
||||
};
|
||||
|
||||
static const std::wstring directory_seperator_str_w{
|
||||
repertory::utils::path::directory_seperator_w,
|
||||
};
|
||||
|
||||
[[nodiscard]] auto resolve(std::string path) -> std::string {
|
||||
#if defined(_WIN32)
|
||||
if (repertory::utils::string::contains(path, "~") ||
|
||||
@ -52,12 +45,17 @@ static const std::wstring directory_seperator_str_w{
|
||||
#else // !defined (_WIN32)
|
||||
if (repertory::utils::string::contains(path, "~")) {
|
||||
std::string home{};
|
||||
repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) {
|
||||
home = (pw->pw_dir ? pw->pw_dir : "");
|
||||
if (home.empty() || ((home == "/") && (getuid() != 0))) {
|
||||
home = repertory::utils::path::combine("/home", {pw->pw_name});
|
||||
}
|
||||
});
|
||||
auto res =
|
||||
repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) {
|
||||
home = (pw->pw_dir ? pw->pw_dir : "");
|
||||
if (home.empty() ||
|
||||
((home == repertory::utils::path::slash) && (getuid() != 0))) {
|
||||
home = repertory::utils::path::combine("/home", {pw->pw_name});
|
||||
}
|
||||
});
|
||||
if (res) {
|
||||
throw std::runtime_error("failed to getpwuid: " + res.reason);
|
||||
}
|
||||
|
||||
return repertory::utils::string::replace(path, "~", home);
|
||||
}
|
||||
@ -70,36 +68,44 @@ static const std::wstring directory_seperator_str_w{
|
||||
namespace repertory::utils::path {
|
||||
auto absolute(std::string_view path) -> std::string {
|
||||
std::string abs_path{path};
|
||||
abs_path = resolve(abs_path);
|
||||
format_path(abs_path, directory_seperator, not_directory_seperator);
|
||||
if (abs_path.empty()) {
|
||||
return abs_path;
|
||||
}
|
||||
|
||||
abs_path = finalize(resolve(abs_path));
|
||||
#if defined(_WIN32)
|
||||
if (not abs_path.empty() && ::PathIsRelativeA(abs_path.c_str())) {
|
||||
std::string temp;
|
||||
temp.resize(MAX_PATH + 1);
|
||||
abs_path = _fullpath(temp.data(), abs_path.c_str(), MAX_PATH);
|
||||
if (not utils::string::contains(abs_path, dot)) {
|
||||
return abs_path;
|
||||
}
|
||||
|
||||
std::string temp;
|
||||
temp.resize(repertory::max_path_length + 1);
|
||||
::GetFullPathNameA(abs_path.c_str(), static_cast<DWORD>(temp.size()),
|
||||
temp.data(), nullptr);
|
||||
#else // !defined(_WIN32)
|
||||
if (not abs_path.empty() && (abs_path.at(0U) != '/')) {
|
||||
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 == ".") {
|
||||
found = true;
|
||||
} else {
|
||||
tmp = dirname(tmp.data());
|
||||
}
|
||||
} while (not found);
|
||||
if (not utils::string::contains(abs_path, dot) ||
|
||||
utils::string::begins_with(abs_path, slash)) {
|
||||
return abs_path;
|
||||
}
|
||||
|
||||
auto found{false};
|
||||
std::string tmp{abs_path};
|
||||
do {
|
||||
auto *res = realpath(tmp.c_str(), nullptr);
|
||||
if (res != nullptr) {
|
||||
abs_path =
|
||||
res + std::string{directory_seperator} + abs_path.substr(tmp.size());
|
||||
free(res);
|
||||
found = true;
|
||||
} else if (tmp == dot) {
|
||||
found = true;
|
||||
} else {
|
||||
tmp = dirname(tmp.data());
|
||||
}
|
||||
} while (not found);
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return format_path(abs_path, directory_seperator, not_directory_seperator);
|
||||
return finalize(abs_path);
|
||||
}
|
||||
|
||||
auto absolute(std::wstring_view path) -> std::wstring {
|
||||
@ -142,7 +148,7 @@ auto find_program_in_path(const std::string &name_without_extension)
|
||||
for (auto &&extension : extension_list) {
|
||||
auto exec_path = combine(
|
||||
search_path, {name_without_extension + std::string{extension}});
|
||||
if (std::filesystem::exists(exec_path)) {
|
||||
if (utils::file::is_file(exec_path)) {
|
||||
found_items[name_without_extension] = exec_path;
|
||||
return exec_path;
|
||||
}
|
||||
@ -159,14 +165,16 @@ find_program_in_path(std::wstring_view name_without_extension) -> std::wstring {
|
||||
}
|
||||
|
||||
auto get_parent_directory(std::string_view path) -> std::string {
|
||||
auto ret = std::filesystem::path{path}.parent_path().string();
|
||||
#if !defined(_WIN32)
|
||||
if (ret == ".") {
|
||||
ret = "/";
|
||||
}
|
||||
#endif // !defined(_WIN32)
|
||||
auto abs_path = absolute(path);
|
||||
|
||||
return absolute(ret);
|
||||
#if defined(_WIN32)
|
||||
::PathRemoveFileSpecA(abs_path.data());
|
||||
abs_path = abs_path.c_str();
|
||||
#else // !defined(_WIN32)
|
||||
abs_path = std::filesystem::path{abs_path}.parent_path().string();
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return finalize(abs_path);
|
||||
}
|
||||
|
||||
auto get_parent_directory(std::wstring_view path) -> std::wstring {
|
||||
@ -175,13 +183,12 @@ auto get_parent_directory(std::wstring_view path) -> std::wstring {
|
||||
}
|
||||
|
||||
auto is_trash_directory(std::string_view path) -> bool {
|
||||
std::string dir_sep_t{get_directory_seperator<char>()};
|
||||
|
||||
auto trash_path = utils::string::to_lower(absolute(path));
|
||||
return utils::string::begins_with(trash_path,
|
||||
directory_seperator_str + ".trash-") ||
|
||||
utils::string::begins_with(trash_path,
|
||||
directory_seperator_str + ".trashes") ||
|
||||
utils::string::begins_with(trash_path,
|
||||
directory_seperator_str + "$recycle.bin");
|
||||
return utils::string::begins_with(trash_path, dir_sep_t + ".trash-") ||
|
||||
utils::string::begins_with(trash_path, dir_sep_t + ".trashes") ||
|
||||
utils::string::begins_with(trash_path, dir_sep_t + "$recycle.bin");
|
||||
}
|
||||
|
||||
auto is_trash_directory(std::wstring_view path) -> bool {
|
||||
@ -191,8 +198,8 @@ auto is_trash_directory(std::wstring_view path) -> bool {
|
||||
auto make_file_uri(std::string_view path) -> std::string {
|
||||
auto abs_path = absolute(path);
|
||||
#if defined(_WIN32)
|
||||
utils::string::replace(abs_path, '\\', '/');
|
||||
abs_path = '/' + abs_path;
|
||||
utils::string::replace(abs_path, backslash, slash);
|
||||
abs_path = std::string{slash} + abs_path;
|
||||
#endif // defined(_WIN32)
|
||||
return "file://" + abs_path;
|
||||
}
|
||||
@ -201,31 +208,11 @@ auto make_file_uri(std::wstring_view path) -> std::wstring {
|
||||
return utils::string::from_utf8(make_file_uri(utils::string::to_utf8(path)));
|
||||
}
|
||||
|
||||
auto remove_file_name(std::string_view path) -> std::string {
|
||||
auto abs_path = absolute(path);
|
||||
|
||||
#if defined(_WIN32)
|
||||
::PathRemoveFileSpecA(abs_path.data());
|
||||
abs_path = abs_path.c_str();
|
||||
#else // !defined(_WIN32)
|
||||
if (abs_path != "/") {
|
||||
auto idx{abs_path.size() - 1U};
|
||||
while ((idx != 0U) && (abs_path.at(idx) != '/')) {
|
||||
idx--;
|
||||
}
|
||||
|
||||
abs_path = (idx > 0U) ? absolute(abs_path.substr(0U, idx)) : "/";
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return abs_path;
|
||||
}
|
||||
|
||||
auto strip_to_file_name(std::string path) -> std::string {
|
||||
#if defined(_WIN32)
|
||||
return ::PathFindFileNameA(path.c_str());
|
||||
#else // !defined(_WIN32)
|
||||
return utils::string::contains(path, "/") ? basename(path.data()) : path;
|
||||
return utils::string::contains(path, slash) ? basename(path.data()) : path;
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ auto run_process_elevated(std::vector<const char *> args) -> int {
|
||||
}
|
||||
|
||||
std::string full_path;
|
||||
full_path.resize(MAX_PATH + 1);
|
||||
full_path.resize(repertory::max_path_length + 1);
|
||||
|
||||
if (::GetModuleFileNameA(nullptr, full_path.data(), MAX_PATH)) {
|
||||
SHELLEXECUTEINFOA sei{};
|
||||
|
Reference in New Issue
Block a user