diff --git a/platform/platform.cpp b/platform/platform.cpp index 480007728c..e9c2841a2b 100644 --- a/platform/platform.cpp +++ b/platform/platform.cpp @@ -7,6 +7,23 @@ #include "base/logging.hpp" +#include + +// static +Platform::EError Platform::ErrnoToError() +{ + switch (errno) + { + case ENOENT: + return ERR_FILE_DOES_NOT_EXIST; + case EACCES: + return ERR_ACCESS_FAILED; + case ENOTEMPTY: + return ERR_DIRECTORY_NOT_EMPTY; + default: + return ERR_UNKNOWN; + } +} string Platform::ReadPathForFile(string const & file, string searchScope) const { @@ -91,6 +108,21 @@ void Platform::GetFilesByExt(string const & directory, string const & ext, Files GetFilesByRegExp(directory, '\\' + ext + '$', outFiles); } +// static +void Platform::GetFilesByType(string const & directory, unsigned typeMask, FilesList & outFiles) +{ + FilesList allFiles; + GetFilesByRegExp(directory, ".*", allFiles); + for (string const & file : allFiles) + { + EFileType type; + if (GetFileType(my::JoinFoldersToPath(directory, file), type) != ERR_OK) + continue; + if (typeMask & type) + outFiles.push_back(file); + } +} + string Platform::DeviceName() const { return OMIM_OS_NAME; diff --git a/platform/platform.hpp b/platform/platform.hpp index c54f04e1e9..28698ed1c2 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -22,7 +22,10 @@ public: enum EError { ERR_OK = 0, - ERR_UNKNOWN = 1 + ERR_FILE_DOES_NOT_EXIST, + ERR_ACCESS_FAILED, + ERR_DIRECTORY_NOT_EMPTY, + ERR_UNKNOWN }; enum EFileType @@ -63,6 +66,9 @@ protected: /// Hash some unique string into uniform format. static string HashUniqueID(string const & s); + /// Returns last system call error as EError. + static EError ErrnoToError(); + public: Platform(); @@ -120,7 +126,7 @@ public: static void GetFilesByRegExp(string const & directory, string const & regexp, FilesList & outFiles); //@} - static EError GetFilesByType(string const & directory, unsigned typeMask, FilesList & outFiles); + static void GetFilesByType(string const & directory, unsigned typeMask, FilesList & outFiles); static EError GetFileType(string const & path, EFileType & type); diff --git a/platform/platform_tests/platform_test.cpp b/platform/platform_tests/platform_test.cpp index f2d04ff973..c620f0f48b 100644 --- a/platform/platform_tests/platform_test.cpp +++ b/platform/platform_tests/platform_test.cpp @@ -23,13 +23,10 @@ void CheckFilesPresence(string const & baseDir, unsigned typeMask, initializer_list> const & files) { Platform::FilesList filesList; - TEST_EQUAL(Platform::GetFilesByType(baseDir, typeMask, filesList), Platform::ERR_OK, - ("Can't get files from", baseDir)); + Platform::GetFilesByType(baseDir, typeMask, filesList); multiset filesSet(filesList.begin(), filesList.end()); for (auto const & file : files) TEST_EQUAL(filesSet.count(file.first), file.second, (file.first, file.second)); - TEST_EQUAL(0, filesSet.count("."), ()); - TEST_EQUAL(0, filesSet.count(".."), ()); } } // namespace diff --git a/platform/platform_unix_impl.cpp b/platform/platform_unix_impl.cpp index 9dc5c0c1c5..f421129514 100644 --- a/platform/platform_unix_impl.cpp +++ b/platform/platform_unix_impl.cpp @@ -8,10 +8,9 @@ #include "base/scope_guard.hpp" #include "std/algorithm.hpp" -#include "std/bind.hpp" -#include "std/cstring.hpp" #include +#include #include #include @@ -108,27 +107,10 @@ void Platform::GetSystemFontNames(FilesList & res) const } // static -Platform::EError Platform::GetFilesByType(string const & directory, unsigned typeMask, - FilesList & outFiles) +Platform::EError Platform::RmDir(string const & dirName) { - DIR * dir = opendir(directory.c_str()); - if (!dir) - return ERR_UNKNOWN; - MY_SCOPE_GUARD(closeDirGuard, bind(&closedir, dir)); - while (struct dirent * entry = readdir(dir)) - { - char const * const name = entry->d_name; - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) - continue; - - string const path = my::JoinFoldersToPath(directory, name); - - EFileType type; - if (GetFileType(path, type) != ERR_OK) - continue; - if (typeMask & type) - outFiles.push_back(name); - } + if (rmdir(dirName.c_str()) != 0) + return ErrnoToError(); return ERR_OK; } @@ -137,7 +119,7 @@ Platform::EError Platform::GetFileType(string const & path, EFileType & type) { struct stat stats; if (stat(path.c_str(), &stats) != 0) - return ERR_UNKNOWN; + return ErrnoToError(); if (S_ISREG(stats.st_mode)) type = FILE_TYPE_REGULAR; else if (S_ISDIR(stats.st_mode)) @@ -153,12 +135,6 @@ bool Platform::IsFileExistsByFullPath(string const & filePath) return stat(filePath.c_str(), &s) == 0; } -// static -Platform::EError Platform::RmDir(string const & dirName) -{ - return rmdir(dirName.c_str()) == 0 ? ERR_OK : ERR_UNKNOWN; -} - bool Platform::GetFileSizeByFullPath(string const & filePath, uint64_t & size) { struct stat s; diff --git a/platform/platform_win.cpp b/platform/platform_win.cpp index 1025f80e20..5e48ea360e 100644 --- a/platform/platform_win.cpp +++ b/platform/platform_win.cpp @@ -8,7 +8,10 @@ #include "std/windows.hpp" #include "std/bind.hpp" +#include #include +#include +#include static bool GetUserWritableDir(string & outDir) { @@ -91,6 +94,29 @@ bool Platform::IsFileExistsByFullPath(string const & filePath) return ::GetFileAttributesA(filePath.c_str()) != INVALID_FILE_ATTRIBUTES; } +// static +Platform::EError Platform::RmDir(string const & dirName) +{ + if (_rmdir(dirName.c_str()) != 0) + return ErrnoToError(); + return ERR_OK; +} + +// static +Platform::EError Platform::GetFileType(string const & path, EFileType & type) +{ + struct _stat32 stats; + if (_stat32(path.c_str(), &stats) != 0) + return ErrnoToError(); + if (stats.st_mode & _S_IFREG) + type = FILE_TYPE_REGULAR; + else if (stats.st_mode & _S_IFDIR) + type = FILE_TYPE_DIRECTORY; + else + type = FILE_TYPE_UNKNOWN; + return ERR_OK; +} + int Platform::CpuCores() const { SYSTEM_INFO sysinfo;