Program Listing for File FileSystem.h#
↰ Return to documentation for file (src/util/FileSystem.h)
#ifndef ROSE_FileSystem_H
#define ROSE_FileSystem_H
#include <filesystem>
#include <regex>
#include <fstream>
#include <streambuf>
#include <string>
#include <vector>
#include <iterator>
#include "rosedll.h"
#include "mlog.h"
namespace Rose {
namespace FileSystem {
extern const char *tempNamePattern;
typedef std::filesystem::path Path;
typedef std::filesystem::directory_iterator DirectoryIterator;
typedef std::filesystem::recursive_directory_iterator RecursiveDirectoryIterator;
ROSE_UTIL_API bool isExisting(const Path &path);
ROSE_UTIL_API bool isFile(const Path &path);
ROSE_UTIL_API bool isDirectory(const Path &path);
ROSE_UTIL_API bool isSymbolicLink(const Path &path);
ROSE_UTIL_API bool isNotSymbolicLink(const Path &path);
class ROSE_UTIL_API baseNameMatches {
const std::regex &re_;
public:
baseNameMatches(const std::regex &re): re_(re) {}
bool operator()(const Path &path);
};
ROSE_UTIL_API Path createTemporaryDirectory();
ROSE_UTIL_API Path makeNormal(const Path&);
ROSE_UTIL_API Path makeRelative(const Path &path, const Path &root = std::filesystem::current_path());
ROSE_UTIL_API Path makeAbsolute(const Path &path, const Path &root = std::filesystem::current_path());
template<class Select>
std::vector<Path> findNames(const Path &root, Select select) {
std::vector<Path> matching;
if (isDirectory(root)) {
for (DirectoryIterator iter(root); iter!=DirectoryIterator(); ++iter) {
if (select(iter->path()))
matching.push_back(iter->path());
}
}
std::sort(matching.begin(), matching.end());
return matching;
}
ROSE_UTIL_API std::vector<Path> findNames(const Path &root);
template<class Select, class Descend>
std::vector<Path> findNamesRecursively(const Path &root, Select select, Descend descend) {
std::vector<Path> matching;
RecursiveDirectoryIterator end;
for (RecursiveDirectoryIterator dentry(root); dentry!=end; ++dentry) {
if (select(dentry->path()))
matching.push_back(dentry->path());
if (!descend(dentry->path()))
dentry.disable_recursion_pending();
}
std::sort(matching.begin(), matching.end());
return matching;
}
template<class Select>
std::vector<Path> findNamesRecursively(const Path &root, Select select) {
return findNamesRecursively(root, select, isDirectory);
}
ROSE_UTIL_API std::vector<Path> findNamesRecursively(const Path &root);
ROSE_UTIL_API void copyFile(const Path &sourceFileName, const Path &destinationFileName);
ROSE_UTIL_API void copyFiles(const std::vector<Path> &files, const Path &root, const Path &destinationDirectory);
template<class Select, class Descend>
void copyFilesRecursively(const Path &root, const Path &destination, Select select, Descend descend) {
std::vector<Path> files = findNamesRecursively(root, select, descend);
files.erase(files.begin(), std::remove_if(files.begin(), files.end(), isFile)); // keep only isFile names
copyFiles(files, root, destination);
}
ROSE_UTIL_API std::vector<Path> findRoseFilesRecursively(const Path &root);
ROSE_UTIL_API std::string toString(const Path&);
template<class Container>
Container readFile(const std::filesystem::path &fileName,
std::ios_base::openmode openMode = std::ios_base::in | std::ios_base::binary) {
using streamIterator = std::istreambuf_iterator<char>;
std::ifstream stream(fileName.c_str(), openMode);
if (!stream.good())
MLOG_ERROR_CXX("UTIL") << "unable to open file " << fileName.string();
Container container;
std::copy(streamIterator(stream), streamIterator(), std::back_inserter(container));
if (stream.fail())
MLOG_ERROR_CXX("UTIL") << "unable to read from file " << fileName.string();
return container;
}
template<class Container>
void writeFile(const std::filesystem::path &fileName, const Container &data,
std::ios_base::openmode openMode = std::ios_base::out | std::ios_base::binary) {
std::ofstream stream(fileName.c_str(),openMode);
if (!stream.good())
MLOG_ERROR_CXX("UTIL") << "unable to open file " << fileName.string();
std::ostream_iterator<char> streamIterator(stream);
std::copy(data.begin(), data.end(), streamIterator);
stream.close();
if (stream.fail())
MLOG_ERROR_CXX("UTIL") << "unable to write to file " << fileName.string();
}
} // namespace
} // namespace
#endif