Merge pull request #23351 from 3x380V/fileinfo
Core: Modernize Fileinfo
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
@@ -29,38 +28,20 @@
|
||||
#include <codecvt>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#if defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(FC_OS_WIN32)
|
||||
#include <io.h>
|
||||
#include <system_error>
|
||||
#ifdef FC_OS_WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "Exception.h"
|
||||
#include "Stream.h"
|
||||
#include "TimeInfo.h"
|
||||
#include "Tools.h"
|
||||
|
||||
|
||||
using namespace Base;
|
||||
|
||||
#ifndef R_OK
|
||||
#define R_OK 4 /* Test for read permission */
|
||||
#endif
|
||||
#ifndef W_OK
|
||||
#define W_OK 2 /* Test for write permission */
|
||||
#endif
|
||||
#ifndef X_OK
|
||||
#define X_OK 1 /* Test for execute permission */
|
||||
#endif
|
||||
#ifndef F_OK
|
||||
#define F_OK 0 /* Test for existence */
|
||||
#endif
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
//**********************************************************************************
|
||||
// helper
|
||||
@@ -109,30 +90,9 @@ const std::string& FileInfo::getTempPath()
|
||||
static std::string tempPath;
|
||||
|
||||
if (tempPath.empty()) {
|
||||
#ifdef FC_OS_WIN32
|
||||
wchar_t buf[MAX_PATH + 2];
|
||||
GetTempPathW(MAX_PATH + 1, buf);
|
||||
int neededSize = WideCharToMultiByte(CP_UTF8, 0, buf, -1, 0, 0, 0, 0);
|
||||
char* dest = new char[static_cast<size_t>(neededSize)];
|
||||
WideCharToMultiByte(CP_UTF8, 0, buf, -1, dest, neededSize, 0, 0);
|
||||
tempPath = dest;
|
||||
delete[] dest;
|
||||
#else
|
||||
const char* tmp = getenv("TMPDIR");
|
||||
if (!Base::Tools::isNullOrEmpty(tmp)) {
|
||||
tempPath = tmp;
|
||||
FileInfo fi(tempPath);
|
||||
if (tempPath.empty() || !fi.isDir()) { // still empty or non-existent
|
||||
tempPath = "/tmp/";
|
||||
}
|
||||
else if (tempPath.at(tempPath.size() - 1) != '/') {
|
||||
tempPath.append("/");
|
||||
}
|
||||
}
|
||||
else {
|
||||
tempPath = "/tmp/";
|
||||
}
|
||||
#endif
|
||||
fs::path tmp = fs::temp_directory_path();
|
||||
tmp += fs::path::preferred_separator;
|
||||
tempPath = pathToString(tmp);
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
@@ -208,20 +168,20 @@ std::string FileInfo::getTempFileName(const char* FileName, const char* Path)
|
||||
#endif
|
||||
}
|
||||
|
||||
std::filesystem::path FileInfo::stringToPath(const std::string& str)
|
||||
fs::path FileInfo::stringToPath(const std::string& str)
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
#ifdef FC_OS_WIN32
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
std::filesystem::path path(converter.from_bytes(str));
|
||||
fs::path path(converter.from_bytes(str));
|
||||
#else
|
||||
std::filesystem::path path(str);
|
||||
fs::path path(str);
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string FileInfo::pathToString(const std::filesystem::path& path)
|
||||
std::string FileInfo::pathToString(const fs::path& path)
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
#ifdef FC_OS_WIN32
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.to_bytes(path.wstring());
|
||||
#else
|
||||
@@ -266,15 +226,7 @@ std::string FileInfo::dirPath() const
|
||||
retval = FileName.substr(0, last_pos);
|
||||
}
|
||||
else {
|
||||
#ifdef FC_OS_WIN32
|
||||
wchar_t buf[MAX_PATH + 1];
|
||||
GetCurrentDirectoryW(MAX_PATH, buf);
|
||||
retval = std::string(ConvertFromWideString(std::wstring(buf)));
|
||||
#else
|
||||
char buf[PATH_MAX + 1];
|
||||
const char* cwd = getcwd(buf, PATH_MAX);
|
||||
retval = std::string(cwd ? cwd : ".");
|
||||
#endif
|
||||
retval = pathToString(fs::current_path());
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -323,9 +275,9 @@ std::string FileInfo::completeExtension() const
|
||||
|
||||
bool FileInfo::hasExtension(const char* Ext) const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
#ifdef FC_OS_WIN32
|
||||
return _stricmp(Ext, extension().c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#else
|
||||
return strcasecmp(Ext, extension().c_str()) == 0;
|
||||
#endif
|
||||
}
|
||||
@@ -339,77 +291,62 @@ bool FileInfo::hasExtension(std::initializer_list<const char*> Exts) const
|
||||
|
||||
bool FileInfo::exists() const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _waccess(wstr.c_str(), F_OK) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return access(FileName.c_str(), F_OK) == 0;
|
||||
#endif
|
||||
fs::path path(stringToPath(FileName));
|
||||
return fs::exists(path);
|
||||
}
|
||||
|
||||
bool FileInfo::isReadable() const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _waccess(wstr.c_str(), R_OK) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return access(FileName.c_str(), R_OK) == 0;
|
||||
#endif
|
||||
fs::path path = stringToPath(FileName);
|
||||
if (!fs::exists(path)) {
|
||||
return false;
|
||||
}
|
||||
fs::file_status stat = fs::status(path);
|
||||
fs::perms perms = stat.permissions();
|
||||
return (perms & fs::perms::owner_read) == fs::perms::owner_read;
|
||||
}
|
||||
|
||||
bool FileInfo::isWritable() const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _waccess(wstr.c_str(), W_OK) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return access(FileName.c_str(), W_OK) == 0;
|
||||
#endif
|
||||
fs::path path = stringToPath(FileName);
|
||||
if (!fs::exists(path)) {
|
||||
return false;
|
||||
}
|
||||
fs::file_status stat = fs::status(path);
|
||||
fs::perms perms = stat.permissions();
|
||||
return (perms & fs::perms::owner_write) == fs::perms::owner_write;
|
||||
}
|
||||
|
||||
bool FileInfo::setPermissions(Permissions perms)
|
||||
{
|
||||
int mode = 0;
|
||||
fs::perms mode = fs::perms::none;
|
||||
|
||||
if (perms & FileInfo::ReadOnly) {
|
||||
mode |= S_IREAD;
|
||||
mode |= fs::perms::owner_read;
|
||||
}
|
||||
if (perms & FileInfo::WriteOnly) {
|
||||
mode |= S_IWRITE;
|
||||
mode |= fs::perms::owner_write;
|
||||
}
|
||||
|
||||
if (mode == 0) { // bad argument
|
||||
if (mode == fs::perms::none) { // bad argument
|
||||
return false;
|
||||
}
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _wchmod(wstr.c_str(), mode) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return chmod(FileName.c_str(), mode) == 0;
|
||||
#endif
|
||||
|
||||
fs::path file_path = stringToPath(FileName);
|
||||
if (!fs::exists(file_path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::permissions(file_path, mode);
|
||||
fs::file_status stat = fs::status(file_path);
|
||||
return stat.permissions() == mode;
|
||||
}
|
||||
|
||||
bool FileInfo::isFile() const
|
||||
{
|
||||
if (exists()) {
|
||||
#ifdef FC_OS_WIN32
|
||||
|
||||
std::wstring wstr = toStdWString();
|
||||
FILE* fd = _wfopen(wstr.c_str(), L"rb");
|
||||
bool ok = (fd != 0);
|
||||
if (fd) {
|
||||
fclose(fd);
|
||||
}
|
||||
return ok;
|
||||
#else
|
||||
// clang-format off
|
||||
struct stat st {};
|
||||
// clang-format on
|
||||
if (stat(FileName.c_str(), &st) != 0) {
|
||||
return false;
|
||||
}
|
||||
return S_ISREG(st.st_mode);
|
||||
#endif
|
||||
fs::path path = stringToPath(FileName);
|
||||
if (fs::exists(path)) {
|
||||
return fs::is_regular_file(path);
|
||||
}
|
||||
|
||||
// TODO: Check for valid file name
|
||||
@@ -418,179 +355,108 @@ bool FileInfo::isFile() const
|
||||
|
||||
bool FileInfo::isDir() const
|
||||
{
|
||||
if (exists()) {
|
||||
// if we can chdir then it must be a directory, otherwise we assume it
|
||||
// is a file (which doesn't need to be true for any cases)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
|
||||
if (_wstat(wstr.c_str(), &st) != 0) {
|
||||
return false;
|
||||
}
|
||||
return ((st.st_mode & _S_IFDIR) != 0);
|
||||
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st {};
|
||||
if (stat(FileName.c_str(), &st) != 0) {
|
||||
return false;
|
||||
}
|
||||
return S_ISDIR(st.st_mode);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
fs::path path = stringToPath(FileName);
|
||||
if (fs::exists(path)) {
|
||||
return fs::is_directory(path);
|
||||
}
|
||||
|
||||
// TODO: Check for valid path name
|
||||
// return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int FileInfo::size() const
|
||||
{
|
||||
unsigned int bytes {};
|
||||
if (exists()) {
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
if (_wstat(wstr.c_str(), &st) == 0) {
|
||||
bytes = st.st_size;
|
||||
fs::path path = stringToPath(FileName);
|
||||
if (fs::exists(path)) {
|
||||
bytes = fs::file_size(path);
|
||||
}
|
||||
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st {};
|
||||
if (stat(FileName.c_str(), &st) == 0) {
|
||||
bytes = st.st_size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
template<typename TP>
|
||||
std::time_t to_time_t(TP tp)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto sctp =
|
||||
time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
|
||||
return system_clock::to_time_t(sctp);
|
||||
}
|
||||
|
||||
TimeInfo FileInfo::lastModified() const
|
||||
{
|
||||
TimeInfo ti = TimeInfo::null();
|
||||
|
||||
if (exists()) {
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
if (_wstat(wstr.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_mtime);
|
||||
fs::path path = stringToPath(FileName);
|
||||
ti.setTime_t(to_time_t(fs::last_write_time(path)));
|
||||
}
|
||||
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st {};
|
||||
if (stat(FileName.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_mtime);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
TimeInfo FileInfo::lastRead() const
|
||||
{
|
||||
TimeInfo ti = TimeInfo::null();
|
||||
if (exists()) {
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
if (_wstat(wstr.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_atime);
|
||||
}
|
||||
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st {};
|
||||
if (stat(FileName.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_atime);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
bool FileInfo::deleteFile() const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return ::_wremove(wstr.c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return (::remove(FileName.c_str()) == 0);
|
||||
#else
|
||||
#error "FileInfo::deleteFile() not implemented for this platform!"
|
||||
#endif
|
||||
try {
|
||||
fs::path path = stringToPath(FileName);
|
||||
return fs::remove(path);
|
||||
}
|
||||
catch (const fs::filesystem_error& e) {
|
||||
std::clog << e.what() << '\n';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileInfo::renameFile(const char* NewName)
|
||||
{
|
||||
bool res {};
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring oldname = toStdWString();
|
||||
std::wstring newname = ConvertToWideString(NewName);
|
||||
res = ::_wrename(oldname.c_str(), newname.c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
res = ::rename(FileName.c_str(), NewName) == 0;
|
||||
#else
|
||||
#error "FileInfo::renameFile() not implemented for this platform!"
|
||||
#endif
|
||||
if (!res) {
|
||||
int code = errno;
|
||||
std::clog << "Error in renameFile: " << strerror(code) << " (" << code << ")" << std::endl;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
fs::path old_path = stringToPath(FileName);
|
||||
fs::path new_path = stringToPath(NewName);
|
||||
fs::rename(old_path, new_path);
|
||||
FileName = NewName;
|
||||
return true;
|
||||
}
|
||||
catch (const fs::filesystem_error& e) {
|
||||
std::clog << "Error in renameFile: " << e.what() << '\n';
|
||||
return false;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool FileInfo::copyTo(const char* NewName) const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring oldname = toStdWString();
|
||||
std::wstring newname = ConvertToWideString(NewName);
|
||||
return CopyFileW(oldname.c_str(), newname.c_str(), true) != 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
FileInfo fi1(FileName);
|
||||
FileInfo fi2(NewName);
|
||||
Base::ifstream file(fi1, std::ios::in | std::ios::binary);
|
||||
file.unsetf(std::ios_base::skipws);
|
||||
Base::ofstream copy(fi2, std::ios::out | std::ios::binary);
|
||||
file >> copy.rdbuf();
|
||||
return file.is_open() && copy.is_open();
|
||||
#else
|
||||
#error "FileInfo::copyTo() not implemented for this platform!"
|
||||
#endif
|
||||
try {
|
||||
fs::path old_path = stringToPath(FileName);
|
||||
fs::path new_path = stringToPath(NewName);
|
||||
fs::copy(old_path, new_path);
|
||||
return true;
|
||||
}
|
||||
catch (const fs::filesystem_error&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileInfo::createDirectory() const
|
||||
{
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _wmkdir(wstr.c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return mkdir(FileName.c_str(), 0777) == 0;
|
||||
#else
|
||||
#error "FileInfo::createDirectory() not implemented for this platform!"
|
||||
#endif
|
||||
try {
|
||||
fs::path path(stringToPath(FileName));
|
||||
return fs::create_directory(path);
|
||||
}
|
||||
catch (const fs::filesystem_error&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileInfo::createDirectories() const
|
||||
{
|
||||
try {
|
||||
std::filesystem::path path(stringToPath(FileName));
|
||||
if (std::filesystem::exists(path)) {
|
||||
fs::path path(stringToPath(FileName));
|
||||
if (fs::exists(path)) {
|
||||
return true;
|
||||
}
|
||||
std::filesystem::create_directories(path);
|
||||
return true;
|
||||
|
||||
return fs::create_directories(path);
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error&) {
|
||||
catch (const fs::filesystem_error&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -600,14 +466,15 @@ bool FileInfo::deleteDirectory() const
|
||||
if (!isDir()) {
|
||||
return false;
|
||||
}
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _wrmdir(wstr.c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return rmdir(FileName.c_str()) == 0;
|
||||
#else
|
||||
#error "FileInfo::rmdir() not implemented for this platform!"
|
||||
#endif
|
||||
|
||||
try {
|
||||
fs::path path = stringToPath(FileName);
|
||||
return fs::remove(path);
|
||||
}
|
||||
catch (const fs::filesystem_error& e) {
|
||||
std::clog << e.what() << '\n';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileInfo::deleteDirectoryRecursive() const
|
||||
@@ -615,71 +482,26 @@ bool FileInfo::deleteDirectoryRecursive() const
|
||||
if (!isDir()) {
|
||||
return false;
|
||||
}
|
||||
std::vector<Base::FileInfo> List = getDirectoryContent();
|
||||
|
||||
for (Base::FileInfo& fi : List) {
|
||||
if (fi.isDir()) {
|
||||
// At least on Linux, directory needs execute permission to be
|
||||
// deleted. We don't really need to set permission for directory
|
||||
// anyway, since FC code does not touch directory permission.
|
||||
//
|
||||
// It->setPermissions(FileInfo::ReadWrite);
|
||||
|
||||
fi.deleteDirectoryRecursive();
|
||||
try {
|
||||
fs::path path = stringToPath(FileName);
|
||||
return fs::remove_all(path) > 0;
|
||||
}
|
||||
else if (fi.isFile()) {
|
||||
fi.setPermissions(FileInfo::ReadWrite);
|
||||
fi.deleteFile();
|
||||
catch (const fs::filesystem_error& e) {
|
||||
std::clog << e.what() << '\n';
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw Base::FileException(
|
||||
"FileInfo::deleteDirectoryRecursive(): Unknown object Type in directory!");
|
||||
}
|
||||
}
|
||||
return deleteDirectory();
|
||||
}
|
||||
|
||||
std::vector<Base::FileInfo> FileInfo::getDirectoryContent() const
|
||||
{
|
||||
std::vector<Base::FileInfo> List;
|
||||
#if defined(FC_OS_WIN32)
|
||||
struct _wfinddata_t dentry;
|
||||
std::error_code ec;
|
||||
std::vector<Base::FileInfo> list;
|
||||
fs::path path = stringToPath(FileName);
|
||||
|
||||
intptr_t hFile;
|
||||
|
||||
// Find first directory entry
|
||||
std::wstring wstr = toStdWString();
|
||||
wstr += L"/*";
|
||||
|
||||
if ((hFile = _wfindfirst(wstr.c_str(), &dentry)) == -1L) {
|
||||
return List;
|
||||
for (const fs::directory_entry& f : fs::directory_iterator {path, ec}) {
|
||||
list.emplace_back(pathToString(f.path()));
|
||||
}
|
||||
|
||||
while (_wfindnext(hFile, &dentry) == 0) {
|
||||
if (wcscmp(dentry.name, L"..") != 0) {
|
||||
List.push_back(
|
||||
FileInfo(FileName + "/" + ConvertFromWideString(std::wstring(dentry.name))));
|
||||
}
|
||||
}
|
||||
|
||||
_findclose(hFile);
|
||||
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
DIR* dp(nullptr);
|
||||
struct dirent* dentry(nullptr);
|
||||
if (!(dp = opendir(FileName.c_str()))) {
|
||||
return List;
|
||||
}
|
||||
|
||||
while ((dentry = readdir(dp))) {
|
||||
std::string dir = dentry->d_name;
|
||||
if (dir != "." && dir != "..") {
|
||||
List.emplace_back(FileName + "/" + dir);
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
#else
|
||||
#error "FileInfo::getDirectoryContent() not implemented for this platform!"
|
||||
#endif
|
||||
return List;
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -127,8 +127,6 @@ public:
|
||||
unsigned int size() const;
|
||||
/// Returns the time when the file was last modified.
|
||||
TimeInfo lastModified() const;
|
||||
/// Returns the time when the file was last read (accessed).
|
||||
TimeInfo lastRead() const;
|
||||
//@}
|
||||
|
||||
/** @name Directory management*/
|
||||
|
||||
@@ -8,6 +8,7 @@ add_executable(Base_tests_run
|
||||
CoordinateSystem.cpp
|
||||
DualNumber.cpp
|
||||
DualQuaternion.cpp
|
||||
FileInfo.cpp
|
||||
Handle.cpp
|
||||
Matrix.cpp
|
||||
Parameter.cpp
|
||||
|
||||
149
tests/src/Base/FileInfo.cpp
Normal file
149
tests/src/Base/FileInfo.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Stream.h>
|
||||
#include <Base/TimeInfo.h>
|
||||
|
||||
class FileInfoTest: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
FileInfoTest()
|
||||
{
|
||||
tmp.setFile(Base::FileInfo::getTempPath() + "fctest");
|
||||
tmp.createDirectory();
|
||||
|
||||
file.setFile(tmp.filePath() + "/test.txt");
|
||||
dir.setFile(tmp.filePath() + "/subdir");
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
Base::ofstream str(file, std::ios::out);
|
||||
str << "Test\n";
|
||||
str.close();
|
||||
dir.createDirectory();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
EXPECT_TRUE(file.deleteFile());
|
||||
EXPECT_TRUE(dir.deleteDirectory());
|
||||
}
|
||||
|
||||
protected:
|
||||
Base::FileInfo tmp;
|
||||
Base::FileInfo file;
|
||||
Base::FileInfo dir;
|
||||
};
|
||||
|
||||
TEST_F(FileInfoTest, TestDirectoryPath)
|
||||
{
|
||||
Base::FileInfo relfile("nofile.txt");
|
||||
relfile.setFile(relfile.dirPath());
|
||||
EXPECT_TRUE(relfile.exists());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestExistsDirectory)
|
||||
{
|
||||
EXPECT_TRUE(tmp.exists());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestCreateDirectory)
|
||||
{
|
||||
Base::FileInfo path;
|
||||
path.setFile(tmp.filePath() + "/subdir1/subdir2");
|
||||
EXPECT_FALSE(path.createDirectory());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestDirectoryContent)
|
||||
{
|
||||
auto content = tmp.getDirectoryContent();
|
||||
EXPECT_EQ(content.size(), 2);
|
||||
EXPECT_TRUE(content[0].exists());
|
||||
EXPECT_TRUE(content[1].exists());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestCheckPermission)
|
||||
{
|
||||
EXPECT_TRUE(file.isReadable());
|
||||
EXPECT_TRUE(file.isWritable());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestCheckNoPermission)
|
||||
{
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo nofile(path + "/nofile");
|
||||
EXPECT_FALSE(nofile.isReadable());
|
||||
EXPECT_FALSE(nofile.isWritable());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestSetPermission)
|
||||
{
|
||||
file.setPermissions(Base::FileInfo::ReadOnly);
|
||||
EXPECT_TRUE(file.isReadable());
|
||||
EXPECT_FALSE(file.isWritable());
|
||||
|
||||
file.setPermissions(Base::FileInfo::WriteOnly);
|
||||
EXPECT_FALSE(file.isReadable());
|
||||
EXPECT_TRUE(file.isWritable());
|
||||
|
||||
file.setPermissions(Base::FileInfo::ReadWrite);
|
||||
EXPECT_TRUE(file.isReadable());
|
||||
EXPECT_TRUE(file.isWritable());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestCheckFile)
|
||||
{
|
||||
EXPECT_TRUE(file.isFile());
|
||||
EXPECT_FALSE(dir.isFile());
|
||||
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo file2(path + "/file2");
|
||||
EXPECT_TRUE(file2.isFile());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestCheckDirectory)
|
||||
{
|
||||
EXPECT_FALSE(file.isDir());
|
||||
EXPECT_TRUE(dir.isDir());
|
||||
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo file2(path + "/file2");
|
||||
EXPECT_FALSE(file2.isDir());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestSize)
|
||||
{
|
||||
EXPECT_EQ(file.size(), 5);
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestLastModified)
|
||||
{
|
||||
EXPECT_FALSE(file.lastModified().isNull());
|
||||
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo nofile(path + "/nofile.txt");
|
||||
EXPECT_TRUE(nofile.lastModified().isNull());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestDeleteFile)
|
||||
{
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo file2(path + "/nofile.txt");
|
||||
EXPECT_FALSE(file2.deleteFile());
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestRenameFile)
|
||||
{
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo file2(path + "/file2");
|
||||
EXPECT_FALSE(file2.renameFile((path + "/file3").c_str()));
|
||||
EXPECT_TRUE(file.renameFile((path + "/file2").c_str()));
|
||||
}
|
||||
|
||||
TEST_F(FileInfoTest, TestCopyFile)
|
||||
{
|
||||
std::string path = tmp.filePath();
|
||||
Base::FileInfo copy(path + "/copy.txt");
|
||||
EXPECT_TRUE(file.copyTo(copy.filePath().c_str()));
|
||||
EXPECT_TRUE(copy.deleteFile());
|
||||
}
|
||||
Reference in New Issue
Block a user