1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
// SPDX-License-Identifier: LGPL-3.0-or-later
// Author: Kristian Lytje
#include <io/File.h>
#include <utility/Exceptions.h>
#include <filesystem>
#include <fstream>
#include <iostream>
using namespace ausaxs;
using namespace ausaxs::io;
File::File(const io::Folder& folder, std::string_view name, std::string_view extension) : dir(folder), name(name), ext(extension) {}
File::File(std::string_view name, std::string_view extension) : File(Folder(), name, extension) {}
File::File(std::string_view path) {
auto[dir, file, ext] = split(path);
this->dir = std::move(dir);
this->name = std::move(file);
this->ext = std::move(ext);
}
std::tuple<std::string, std::string, std::string> File::split(std::string_view path) {
auto p = std::filesystem::path(path);
return std::make_tuple(p.parent_path().string(), p.stem().string(), p.extension().string());
}
File::operator std::string() const {
return dir.path() + "/" + name + ext;
}
File& File::replace_extension(std::string_view extension) noexcept {
if (extension.front() == '.') {
ext = extension.substr(1);
} else {
ext = extension;
}
return *this;
}
File& File::append(std::string_view name) noexcept {
this->name += name;
return *this;
}
io::File File::append(std::string_view name) const noexcept {
auto file = *this;
file.append(name);
return file;
}
Folder& File::directory() noexcept {return dir;}
const Folder& File::directory() const noexcept {return dir;}
std::string& File::extension() noexcept {return ext;}
const std::string& File::extension() const noexcept {return ext;}
std::string File::stem() const noexcept {return name;}
std::string& File::stem() noexcept {return name;}
void File::create(std::string_view contents) const {
if (!dir.exists()) {dir.create();}
std::ofstream file(*this);
if (!file.is_open()) {throw except::io_error("File::create: Could not create file " + path());}
file << contents;
}
io::File File::rename(std::string_view name) const {
io::File new_file(dir, name, ext);
std::filesystem::rename(path(), new_file.path());
return new_file;
}
io::File File::move(const io::Folder& folder) const {
if (folder == dir) {return *this;}
if (!folder.exists()) {folder.create();}
io::File new_file(folder, name, ext);
if (new_file.exists()) {new_file.remove();}
std::filesystem::rename(path(), new_file.path());
return new_file;
}
io::File File::copy(const io::Folder& folder) const {
if (folder == dir) {return *this;}
if (!folder.exists()) {folder.create();}
io::File new_file(folder, name, ext);
if (new_file.exists()) {new_file.remove();}
std::filesystem::copy(path(), new_file.path());
return new_file;
}
void File::remove() const {
if (exists()) {std::filesystem::remove(path());}
}
std::string File::path() const {return std::string(*this);}
std::string File::str() const {return path();}
std::string File::absolute_path() const {return std::filesystem::absolute(path()).string();}
std::string File::relative_path(const File& other) const {
if (name.empty() || other.name.empty()) {throw except::io_error("File::relative_path: Cannot get relative path of empty path.");}
return std::filesystem::relative(other.absolute_path(), directory().path()).string();
}
std::string File::filename() const noexcept {
return name + ext;
}
bool File::empty() const noexcept {
return name.empty() && ext.empty();
}
bool File::exists() const noexcept {
return std::filesystem::is_regular_file(path());
}
std::ostream& operator<<(std::ostream& os, const io::File& file) {
os << file.path();
return os;
}
|