Add methods to get dir path and entries

This commit is contained in:
Martchus 2016-07-02 02:01:26 +02:00
parent 0cc508dc93
commit cb4246e202
3 changed files with 118 additions and 17 deletions

View File

@ -8,20 +8,21 @@
#include <fstream> #include <fstream>
#include <cstdlib> #include <cstdlib>
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
#include <unistd.h> # include <unistd.h>
#include <sys/types.h> # include <sys/types.h>
#include <sys/stat.h> # include <sys/stat.h>
#include <pwd.h> # include <pwd.h>
# include <dirent.h>
#else #else
#ifdef PLATFORM_WINDOWS # ifdef PLATFORM_WINDOWS
#ifdef UNICODE # ifdef UNICODE
#undef UNICODE # undef UNICODE
#endif # endif
#ifdef _UNICODE # ifdef _UNICODE
#undef _UNICODE # undef _UNICODE
#endif # endif
#include <windows.h> # include <windows.h>
#endif # endif
#endif #endif
using namespace std; using namespace std;
@ -37,17 +38,38 @@ string fileName(const string &path)
size_t lastSlash = path.rfind('/'); size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\'); size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator; size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) if(lastSlash == string::npos && lastBackSlash == string::npos) {
return path; return path;
else if(lastSlash == string::npos) } else if(lastSlash == string::npos) {
lastSeparator = lastBackSlash; lastSeparator = lastBackSlash;
else if(lastBackSlash == string::npos) } else if(lastBackSlash == string::npos) {
lastSeparator = lastSlash; lastSeparator = lastSlash;
else } else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return path.substr(lastSeparator + 1); return path.substr(lastSeparator + 1);
} }
/*!
* \brief Returns the directory of the specified \a path string (including trailing slash).
*/
string directory(const string &path)
{
size_t lastSlash = path.rfind('/');
size_t lastBackSlash = path.rfind('\\');
size_t lastSeparator;
if(lastSlash == string::npos && lastBackSlash == string::npos) {
return string();
} else if(lastSlash == string::npos) {
lastSeparator = lastBackSlash;
} else if(lastBackSlash == string::npos) {
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return path.substr(0, lastSeparator + 1);
}
/*! /*!
* \brief Removes invalid characters from the specified \a fileName. * \brief Removes invalid characters from the specified \a fileName.
* *
@ -158,4 +180,39 @@ bool settingsDirectory(std::string &result, std::string applicationDirectoryName
return true; return true;
} }
/*!
* \brief Returns the names of the directory entries in the specified \a path with the specified \a types.
*/
std::list<std::string> directoryEntries(const char *path, DirectoryEntryType types)
{
#ifdef PLATFORM_UNIX
list<string> entries;
if(auto dir = opendir(path)) {
while(auto dirEntry = readdir(dir)) {
bool filter = false;
switch(dirEntry->d_type) {
case DT_REG:
filter = (types & DirectoryEntryType::File) != DirectoryEntryType::None;
break;
case DT_DIR:
filter = (types & DirectoryEntryType::Directory) != DirectoryEntryType::None;
break;
case DT_LNK:
filter = (types & DirectoryEntryType::Symlink) != DirectoryEntryType::None;
break;
default:
filter = (types & DirectoryEntryType::All) != DirectoryEntryType::None;
}
if(filter) {
entries.emplace_back(dirEntry->d_name);
}
}
closedir(dir);
}
return entries;
#else
return list<string>(); // TODO
#endif
}
} }

View File

@ -7,6 +7,7 @@
#include "../application/global.h" #include "../application/global.h"
#include <string> #include <string>
#include <list>
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# define PATH_SEP_CHAR '\\' # define PATH_SEP_CHAR '\\'
@ -22,9 +23,33 @@
namespace IoUtilities { namespace IoUtilities {
/*!
* \brief The DirectoryEntryType enum specifies the type of a directory entry (file, directory or symlink).
*/
enum class DirectoryEntryType : unsigned char
{
None = 0,
File = 1,
Directory = 2,
Symlink = 4,
All = 0xFF
};
constexpr DirectoryEntryType operator|(DirectoryEntryType lhs, DirectoryEntryType rhs)
{
return static_cast<DirectoryEntryType>(static_cast<unsigned char>(lhs) | static_cast<unsigned char>(rhs));
}
constexpr DirectoryEntryType operator&(DirectoryEntryType lhs, DirectoryEntryType rhs)
{
return static_cast<DirectoryEntryType>(static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs));
}
LIB_EXPORT std::string fileName(const std::string &path); LIB_EXPORT std::string fileName(const std::string &path);
LIB_EXPORT std::string directory(const std::string &path);
LIB_EXPORT void removeInvalidChars(std::string &fileName); LIB_EXPORT void removeInvalidChars(std::string &fileName);
LIB_EXPORT bool settingsDirectory(std::string &result, std::string applicationDirectoryName = std::string(), bool createApplicationDirectory = false); LIB_EXPORT bool settingsDirectory(std::string &result, std::string applicationDirectoryName = std::string(), bool createApplicationDirectory = false);
LIB_EXPORT std::list<std::string> directoryEntries(const char *path, DirectoryEntryType types = DirectoryEntryType::All);
} }

View File

@ -13,6 +13,7 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <algorithm>
using namespace std; using namespace std;
using namespace IoUtilities; using namespace IoUtilities;
@ -224,9 +225,27 @@ void IoTests::testBitReader()
void IoTests::testPathUtilities() void IoTests::testPathUtilities()
{ {
CPPUNIT_ASSERT(fileName("/usr/lib/libc++utilities.so") == "libc++utilities.so"); CPPUNIT_ASSERT(fileName("/usr/lib/libc++utilities.so") == "libc++utilities.so");
CPPUNIT_ASSERT(directory("/usr/lib/libc++utilities.so") == "/usr/lib/");
CPPUNIT_ASSERT(directory("libc++utilities.so").empty());
string invalidPath("lib/c++uti*lities.so?"); string invalidPath("lib/c++uti*lities.so?");
removeInvalidChars(invalidPath); removeInvalidChars(invalidPath);
CPPUNIT_ASSERT(invalidPath == "libc++utilities.so"); CPPUNIT_ASSERT(invalidPath == "libc++utilities.so");
#ifdef PLATFORM_UNIX
const string iniFilePath = TestUtilities::testFilePath("test.ini");
const string testFilesDir = iniFilePath.substr(0, iniFilePath.size() - 9);
auto testFilesDirEntries = directoryEntries(testFilesDir.c_str(), DirectoryEntryType::All);
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), "test.ini") != testFilesDirEntries.cend());
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), ".") != testFilesDirEntries.cend());
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), "..") != testFilesDirEntries.cend());
testFilesDirEntries = directoryEntries(testFilesDir.c_str(), DirectoryEntryType::Directory);
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), "test.ini") == testFilesDirEntries.cend());
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), ".") != testFilesDirEntries.cend());
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), "..") != testFilesDirEntries.cend());
testFilesDirEntries = directoryEntries(testFilesDir.c_str(), DirectoryEntryType::File);
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), "test.ini") != testFilesDirEntries.cend());
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), ".") == testFilesDirEntries.cend());
CPPUNIT_ASSERT(find(testFilesDirEntries.cbegin(), testFilesDirEntries.cend(), "..") == testFilesDirEntries.cend());
#endif
} }
/*! /*!