diff --git a/.idea/misc.xml b/.idea/misc.xml index 79b3c94..ef70700 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d4dd02..273737d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.18) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_subdirectory(change_detectors) diff --git a/src/change_detectors/srcs/ComparableFile.cpp b/src/change_detectors/srcs/ComparableFile.cpp index 3ff0a70..9e21965 100644 --- a/src/change_detectors/srcs/ComparableFile.cpp +++ b/src/change_detectors/srcs/ComparableFile.cpp @@ -16,13 +16,13 @@ ComparableFile::ComparableFile(const File &file, const Repository *repo) contents([file, repo]() { return std::make_unique(repo, file.id); }) {} ComparableFile::ComparableFile(const std::filesystem::path &p, const std::filesystem::path &base) - : path(p.lexically_relative(base).u8string()), type(File::getFileType(p)), bytes(File::getFileSize(p)), + : path(p.lexically_relative(base).string()), type(File::getFileType(p)), bytes(File::getFileSize(p)), mtime(File::getFileMtime(p)), contents([p, path = this->path, type = this->type]() -> std::unique_ptr { if (type == File::Type::Normal) { auto fb = std::make_unique(); fb->open(p, std::ios::in | std::ios::binary); - if (!fb->is_open()) throw Exception("Can't open " + p.u8string() + " for reading!"); + if (!fb->is_open()) throw Exception("Can't open " + p.string() + " for reading!"); return fb; } diff --git a/src/commands/srcs/CommandDiff.cpp b/src/commands/srcs/CommandDiff.cpp index ab789d5..85d6e36 100644 --- a/src/commands/srcs/CommandDiff.cpp +++ b/src/commands/srcs/CommandDiff.cpp @@ -43,7 +43,7 @@ void CommandDiff::run(Context ctx) { std::map files;///< Files in the first archive for (auto id: archiveO1.files) { auto file = Serialize::deserialize(ctx.repo->getObject(id)); - auto path = std::filesystem::u8path(file.name); + auto path = std::filesystem::path(file.name); if (isSubpath(ctx.repo->getConfig().getStr("prefix"), path)) files.emplace(file.getKey(), std::move(file)); } @@ -83,7 +83,7 @@ void CommandDiff::run(Context ctx) { /// Exit when asked to if (Signals::shouldQuit) throw Exception("Quitting"); auto file = Serialize::deserialize(ctx.repo->getObject(id)); - if (isSubpath(ctx.repo->getConfig().getStr("prefix"), std::filesystem::u8path(file.name))) + if (isSubpath(ctx.repo->getConfig().getStr("prefix"), std::filesystem::path(file.name))) threadPool.push([&, file]() { processFile(ComparableFile{file, ctx.repo}); }); if (Signals::shouldQuit) break; } @@ -115,7 +115,7 @@ void CommandDiff::run(Context ctx) { std::map files2;///< Files in the first archive for (auto id: archiveO2->files) { auto file = Serialize::deserialize(ctx.repo->getObject(id)); - auto path = std::filesystem::u8path(file.name); + auto path = std::filesystem::path(file.name); if (isSubpath(ctx.repo->getConfig().getStr("prefix"), path)) files2.emplace(file.getKey(), std::move(file)); } @@ -144,5 +144,5 @@ void CommandDiff::run(Context ctx) { std::unique_lock finishedLock(threadPool.finishedLock); threadPool.finished.wait(finishedLock, [&threadPool] { return threadPool.empty(); }); if (diffMode == "normal") - for (auto const &s: files) { ctx.logger->write(s.first.u8string() + " is removed\n", 0); } + for (auto const &s: files) { ctx.logger->write(s.first.string() + " is removed\n", 0); } } diff --git a/src/commands/srcs/CommandRestore.cpp b/src/commands/srcs/CommandRestore.cpp index 38cfc08..5b64b1c 100644 --- a/src/commands/srcs/CommandRestore.cpp +++ b/src/commands/srcs/CommandRestore.cpp @@ -24,7 +24,7 @@ CommandRestore::CommandRestore() : Command() {} void CommandRestore::run(Context ctx) { Object::idType archive = ctx.repo->getConfig().getInt("aid"); - std::filesystem::path to = std::filesystem::u8path(ctx.repo->getConfig().getStr("to")); + std::filesystem::path to = std::filesystem::path(ctx.repo->getConfig().getStr("to")); std::atomic filesToRestoreCount = 0; std::atomic bytesToRestore = 0; @@ -95,21 +95,21 @@ void CommandRestore::run(Context ctx) { std::string CommandRestore::backupRestoreFile(const File &file, const std::filesystem::path &baseDir, workerStatsFunction &callback, Context ctx) { - auto fullpath = baseDir / std::filesystem::u8path(file.name); + auto fullpath = baseDir / std::filesystem::path(file.name); std::filesystem::create_directories(fullpath.parent_path()); if (file.fileType == File::Type::Directory) { std::filesystem::create_directory(fullpath); callback(0, 0, 1); - return fullpath.u8string(); + return fullpath.string(); } if (file.fileType == File::Type::Symlink) { auto dest = Serialize::deserialize(ctx.repo->getObject(file.chunks.at(0))); - std::filesystem::create_symlink(std::filesystem::u8path(std::string{dest.data.begin(), dest.data.end()}), + std::filesystem::create_symlink(std::filesystem::path(std::string{dest.data.begin(), dest.data.end()}), fullpath); callback(0, 0, 1); - return fullpath.u8string(); + return fullpath.string(); } std::ofstream ostream(fullpath, std::ios::binary | std::ios::out | std::ios::trunc); @@ -124,5 +124,5 @@ std::string CommandRestore::backupRestoreFile(const File &file, const std::files } callback(0, 0, 1); - return fullpath.u8string(); + return fullpath.string(); } diff --git a/src/commands/srcs/CommandRun.cpp b/src/commands/srcs/CommandRun.cpp index 285e69b..7ee8967 100644 --- a/src/commands/srcs/CommandRun.cpp +++ b/src/commands/srcs/CommandRun.cpp @@ -79,14 +79,14 @@ void CommandRun::run(Context ctx) { File::getFileType(absPath) == File::Type::Normal ? std::filesystem::file_size(absPath) : 0; runnerStats.filesToSaveCount++; threadPool.push([&, relPath, absPath]() { - addFile(backupChunkFile(absPath, relPath.u8string(), workerCallback, ctx)); - progress.print("Copied: " + relPath.u8string(), 1); + addFile(backupChunkFile(absPath, relPath.string(), workerCallback, ctx)); + progress.print("Copied: " + relPath.string(), 1); }); }; /// Task to process an individual file in the backup std::function processFile = [&, this](const std::filesystem::path &p) { - auto relPath = p.lexically_relative(from).u8string(); + auto relPath = p.lexically_relative(from).string(); if (ctx.repo->exists(Object::ObjectType::File, relPath) != 0) { File repoFile = Serialize::deserialize(ctx.repo->getObject(Object::ObjectType::File, relPath)); @@ -144,10 +144,10 @@ Object::idType CommandRun::backupChunkFile(const std::filesystem::path &orig, co ctx.repo->putObject(f); return f.id; } - if (!std::filesystem::is_regular_file(orig)) throw Exception(orig.u8string() + "is a special file, not saving"); + if (!std::filesystem::is_regular_file(orig)) throw Exception(orig.string() + "is a special file, not saving"); std::ifstream ifstream(orig, std::ios::in | std::ios::binary); - if (!ifstream) throw Exception("Couldn't open " + orig.u8string() + " for reading"); + if (!ifstream) throw Exception("Couldn't open " + orig.string() + " for reading"); std::unique_ptr chunker = ChunkerFactory::getChunker(ctx.repo->getConfig(), ifstream.rdbuf()); SHA fileHash; @@ -179,7 +179,7 @@ Object::idType CommandRun::backupChunkFile(const std::filesystem::path &orig, co /// We might have exited in the loop before, so we don't save an incomplete file if (Signals::shouldQuit) throw Exception("Quitting!"); if (size != File::getFileSize(orig)) { - throw Exception("Something really bad happened or file " + orig.u8string() + " changed during backup"); + throw Exception("Something really bad happened or file " + orig.string() + " changed during backup"); } File f(ctx.repo->getId(), saveAs, size, File::getFileMtime(orig), fileHash.getHash(), fileChunks, File::getFileType(orig)); diff --git a/src/commands/srcs/CommandsCommon.cpp b/src/commands/srcs/CommandsCommon.cpp index bf6fcb2..ab68a89 100644 --- a/src/commands/srcs/CommandsCommon.cpp +++ b/src/commands/srcs/CommandsCommon.cpp @@ -18,16 +18,16 @@ void CommandsCommon::workerCallback(unsigned long long int bytesWritten, unsigne } bool CommandsCommon::isSubpath(const std::filesystem::path &prefix, const std::filesystem::path &p) { - if (prefix.u8string().size() > p.u8string().size()) return false; - for (int i = 0; i < prefix.u8string().size(); i++) - if (p.u8string()[i] != prefix.u8string()[i]) return false; + if (prefix.string().size() > p.string().size()) return false; + for (int i = 0; i < prefix.string().size(); i++) + if (p.string()[i] != prefix.string()[i]) return false; return true; } void CommandsCommon::processDirWithIgnore(const std::filesystem::path &dir, std::vector ignore, const std::function)> &spawner, std::function processFile) { - if (!std::filesystem::is_directory(dir)) throw Exception(dir.u8string() + " is not a directory!"); + if (!std::filesystem::is_directory(dir)) throw Exception(dir.string() + " is not a directory!"); /// Don't process the directory if it has a ".nobackup" file if (std::filesystem::exists(dir / ".nobackup")) return; @@ -47,7 +47,7 @@ void CommandsCommon::processDirWithIgnore(const std::filesystem::path &dir, std: /// Don't process the entry if it matches any of the ignore rules if (std::any_of(ignore.begin(), ignore.end(), [dirEntry](auto pred) { std::smatch m; - auto s = dirEntry.path().filename().u8string(); + auto s = dirEntry.path().filename().string(); return std::regex_match(s, m, std::regex(pred)); })) continue; diff --git a/src/fuse/srcs/RepoFS.cpp b/src/fuse/srcs/RepoFS.cpp index 2409835..b6b69a6 100644 --- a/src/fuse/srcs/RepoFS.cpp +++ b/src/fuse/srcs/RepoFS.cpp @@ -15,7 +15,7 @@ #include "objects/Chunk.h" DirEntry *getf(std::string path) { - auto p = std::filesystem::relative(std::filesystem::u8path(path), "/"); + auto p = std::filesystem::relative(std::filesystem::path(path), "/"); DirEntry *entry = RepoFS::root.get(); if (p != ".") for (auto const &subp: p) { entry = entry->children.at(subp).get(); } @@ -142,7 +142,7 @@ void RepoFS::start(Repository *repo, std::string path) { auto a = Serialize::deserialize(repo->getObject(r.second)); for (auto const &f: a.files) { auto file = Serialize::deserialize(repo->getObject(f)); - auto path = std::filesystem::u8path(file.name); + auto path = std::filesystem::path(file.name); DirEntry *entry = root->children[std::to_string(a.id)].get() ? root->children[std::to_string(a.id)].get() : (root->children[std::to_string(a.id)] = std::make_unique()).get(); @@ -153,7 +153,7 @@ void RepoFS::start(Repository *repo, std::string path) { : (entry->children[subp] = std::make_unique()).get(); } entry->file.emplace(file); - entry->name = std::filesystem::u8path(file.name).filename().u8string(); + entry->name = std::filesystem::path(file.name).filename().string(); } } diff --git a/src/repo/srcs/FileRepository.cpp b/src/repo/srcs/FileRepository.cpp index 957e7a4..f48f6ef 100644 --- a/src/repo/srcs/FileRepository.cpp +++ b/src/repo/srcs/FileRepository.cpp @@ -58,7 +58,7 @@ bool FileRepository::init() { if (exists()) throw Exception("Trying to initialize already existing repository!"); if (!std::filesystem::is_directory(root) && !std::filesystem::create_directories(root)) - throw Exception("Can't create directory " + root.u8string()); + throw Exception("Can't create directory " + root.string()); writeFile(root / "info", CheckFilter::filterWriteStatic(Serialize::serialize(config))); @@ -157,23 +157,23 @@ bool FileRepository::deleteObject(const Object &obj) { std::vector FileRepository::readFile(const std::filesystem::path &file, unsigned long long offset, unsigned long long size) const { if (size > absoluteMaxFileLimit) - throw Exception("Tried to read " + std::to_string(size) + " bytes from " + file.u8string() + + throw Exception("Tried to read " + std::to_string(size) + " bytes from " + file.string() + " which is more than absoluteMaxFileLimit"); std::ifstream ifstream(file, std::ios::binary | std::ios::in); - if (!ifstream.is_open()) throw Exception("Can't open file " + file.u8string() + " for reading!"); + if (!ifstream.is_open()) throw Exception("Can't open file " + file.string() + " for reading!"); std::vector buf(size); if (ifstream.rdbuf()->pubseekpos(offset) == std::streampos(std::streamoff(-1))) - throw Exception("Unexpected end of file " + file.u8string()); - if (ifstream.rdbuf()->sgetn(buf.data(), size) != size) throw Exception("Unexpected end of file " + file.u8string()); + throw Exception("Unexpected end of file " + file.string()); + if (ifstream.rdbuf()->sgetn(buf.data(), size) != size) throw Exception("Unexpected end of file " + file.string()); return buf; } std::vector FileRepository::readFile(const std::filesystem::path &file) const { - if (!std::filesystem::is_regular_file(file)) throw Exception("File " + file.u8string() + " is not a regular file!"); + if (!std::filesystem::is_regular_file(file)) throw Exception("File " + file.string() + " is not a regular file!"); auto fileSize = std::filesystem::file_size(file); if (fileSize == 0) return {}; return readFile(file, 0, fileSize); @@ -181,10 +181,10 @@ std::vector FileRepository::readFile(const std::filesystem::path &file) co bool FileRepository::writeFile(const std::filesystem::path &file, const std::vector &data) { std::ofstream ofstream(file, std::ios::binary | std::ios::trunc | std::ios::out); - if (!ofstream.is_open()) throw Exception("Can't open file " + file.u8string() + " for writing!"); + if (!ofstream.is_open()) throw Exception("Can't open file " + file.string() + " for writing!"); if (ofstream.rdbuf()->sputn(data.data(), data.size()) != data.size()) - throw Exception("Couldn't write all the data for " + file.u8string()); + throw Exception("Couldn't write all the data for " + file.string()); return true; } diff --git a/src/repo/srcs/objects/File.cpp b/src/repo/srcs/objects/File.cpp index b1ae714..9ddf7af 100644 --- a/src/repo/srcs/objects/File.cpp +++ b/src/repo/srcs/objects/File.cpp @@ -42,20 +42,20 @@ File::Type File::getFileType(const std::filesystem::path &p) { if (std::filesystem::is_symlink(p)) return Type::Symlink; if (std::filesystem::is_directory(p)) return Type::Directory; if (std::filesystem::is_regular_file(p)) return Type::Normal; - throw Exception("Unsupported file type! " + p.u8string()); + throw Exception("Unsupported file type! " + p.string()); } std::vector File::getFileContents(const std::filesystem::path &p) { auto type = getFileType(p); - if (type == Type::Normal) throw Exception(p.u8string() + " is a normal file!"); + if (type == Type::Normal) throw Exception(p.string() + " is a normal file!"); if (type == Type::Directory) { return {}; } if (type == Type::Symlink) { - auto target = std::filesystem::read_symlink(p).u8string(); + auto target = std::filesystem::read_symlink(p).string(); std::vector target_null_term = {target.begin(), target.end()}; target_null_term.emplace_back('\0'); return target_null_term; } - throw Exception("Error with file " + p.u8string()); + throw Exception("Error with file " + p.string()); } unsigned long long File::getFileMtime(const std::filesystem::path &p) { @@ -65,16 +65,16 @@ unsigned long long File::getFileMtime(const std::filesystem::path &p) { std::chrono::duration_cast(std::filesystem::last_write_time(p).time_since_epoch()) .count()); else if (type == Type::Symlink) { - auto path = p.u8string(); + auto path = p.string(); struct stat sb; - if (lstat(path.c_str(), &sb) != 0) throw Exception("Error reading mtime for " + p.u8string()); + if (lstat(path.c_str(), &sb) != 0) throw Exception("Error reading mtime for " + p.string()); #ifdef __APPLE__ return sb.st_mtimespec.tv_sec; #else return sb.st_mtime; #endif } - throw Exception("Error with file " + p.u8string()); + throw Exception("Error with file " + p.string()); } unsigned long long File::getFileSize(const std::filesystem::path &p) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 40372ae..0bfb5f8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.18) # GoogleTest requires at least C++14 -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")