Split directory.cpp into unix/win32 parts (#491)
directory.cpp was essentially two implementations in one, separated with ifdefs. It's cleaner to just have two separate files, seeing how CMakeLists.txt for libmediation needs to check the platform it's running on and add the appropriate file implementation anyway. This commit splits this file into two and extracts common code parts to directory_priv.h.
This commit is contained in:
parent
c2de3db345
commit
c483756b42
@ -6,3 +6,4 @@ BreakBeforeBraces: Allman
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
IndentCaseLabels: false
|
||||
ColumnLimit: 120
|
||||
IncludeBlocks: Preserve
|
||||
|
@ -2,17 +2,16 @@ cmake_minimum_required (VERSION 3.1)
|
||||
project(mediation)
|
||||
|
||||
add_library(mediation STATIC
|
||||
fs/directory.cpp
|
||||
types/types.cpp
|
||||
system/terminatablethread.cpp
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
target_compile_definitions(mediation PRIVATE "-DUNICODE")
|
||||
target_sources(mediation PRIVATE fs/osdep/file_win32.cpp)
|
||||
target_sources(mediation PRIVATE fs/osdep/file_win32.cpp fs/osdep/directory_win32.cpp)
|
||||
ELSE()
|
||||
target_compile_definitions(mediation PRIVATE "-D_FILE_OFFSET_BITS=64")
|
||||
target_sources(mediation PRIVATE fs/osdep/file_unix.cpp)
|
||||
target_sources(mediation PRIVATE fs/osdep/file_unix.cpp fs/osdep/directory_unix.cpp)
|
||||
ENDIF()
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
@ -1,272 +0,0 @@
|
||||
|
||||
#include "directory.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "file.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <memory.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
char getDirSeparator()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return '\\';
|
||||
#else
|
||||
return '/';
|
||||
#endif
|
||||
}
|
||||
|
||||
string extractFileDir(const string& fileName)
|
||||
{
|
||||
size_t index = fileName.find_last_of('/');
|
||||
if (index != string::npos)
|
||||
return fileName.substr(0, index + 1);
|
||||
#ifdef _WIN32
|
||||
index = fileName.find_last_of('\\');
|
||||
if (index != string::npos)
|
||||
return fileName.substr(0, index + 1);
|
||||
#endif
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool fileExists(const string& fileName)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
File f;
|
||||
return f.open(fileName.c_str(), File::ofRead | File::ofOpenExisting);
|
||||
#else
|
||||
struct stat buf;
|
||||
return stat(fileName.c_str(), &buf) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t getFileSize(const std::string& fileName)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
File f;
|
||||
if (f.open(fileName.c_str(), File::ofRead | File::ofOpenExisting))
|
||||
{
|
||||
uint64_t rv;
|
||||
return f.size(&rv) ? rv : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
struct stat fileStat;
|
||||
auto res = stat(fileName.c_str(), &fileStat) == 0;
|
||||
return res ? static_cast<uint64_t>(fileStat.st_size) : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool createDir(const std::string& dirName, bool createParentDirs)
|
||||
{
|
||||
if (dirName.empty())
|
||||
return false;
|
||||
|
||||
if (createParentDirs)
|
||||
{
|
||||
for (string::size_type separatorPos = dirName.find_first_not_of(getDirSeparator()), dirEnd = string::npos;
|
||||
separatorPos != string::npos;
|
||||
dirEnd = separatorPos, separatorPos = dirName.find_first_not_of(getDirSeparator(), separatorPos))
|
||||
{
|
||||
separatorPos = dirName.find(getDirSeparator(), separatorPos);
|
||||
if (dirEnd != string::npos)
|
||||
{
|
||||
string parentDir = dirName.substr(0, dirEnd);
|
||||
#if __linux__ == 1 || (defined(__APPLE__) && defined(__MACH__))
|
||||
if (mkdir(parentDir.c_str(), S_IREAD | S_IWRITE | S_IEXEC) == -1)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
return false;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
if (parentDir.size() == 0 || parentDir[parentDir.size() - 1] == ':' || parentDir == string("\\\\.") ||
|
||||
parentDir == string("\\\\.\\") || // UNC patch prefix
|
||||
(strStartWith(parentDir, "\\\\.\\") && parentDir[parentDir.size() - 1] == '}')) // UNC patch prefix
|
||||
continue;
|
||||
if (CreateDirectory(toWide(parentDir).data(), 0) == 0)
|
||||
{
|
||||
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if __linux__ == 1 || (defined(__APPLE__) && defined(__MACH__))
|
||||
return mkdir(dirName.c_str(), S_IREAD | S_IWRITE | S_IEXEC) == 0;
|
||||
#elif defined(_WIN32)
|
||||
return CreateDirectory(toWide(dirName).data(), 0) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool deleteFile(const string& fileName)
|
||||
{
|
||||
#if __linux__ == 1 || (defined(__APPLE__) && defined(__MACH__))
|
||||
return unlink(fileName.c_str()) == 0;
|
||||
#else
|
||||
if (DeleteFile(toWide(fileName).data()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
return false;
|
||||
}
|
||||
|
||||
return DeleteFile(toWide(fileName).data()) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(_WIN32)
|
||||
/** windows implementation */
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <windows.h>
|
||||
|
||||
bool findFiles(const string& path, const string& fileMask, vector<string>* fileList, bool savePaths)
|
||||
{
|
||||
WIN32_FIND_DATA fileData; // Data structure describes the file found
|
||||
HANDLE hSearch; // Search handle returned by FindFirstFile
|
||||
|
||||
auto searchStr = toWide(path + '/' + fileMask);
|
||||
hSearch = FindFirstFile(searchStr.data(), &fileData);
|
||||
if (hSearch == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
auto fileName = toUtf8(fileData.cFileName);
|
||||
fileList->push_back(savePaths ? (path + '/' + fileName) : fileName);
|
||||
}
|
||||
} while (FindNextFile(hSearch, &fileData));
|
||||
|
||||
FindClose(hSearch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findDirs(const string& path, vector<string>* dirsList)
|
||||
{
|
||||
WIN32_FIND_DATA fileData; // Data structure describes the file found
|
||||
HANDLE hSearch; // Search handle returned by FindFirstFile
|
||||
|
||||
auto searchStr = toWide(path + "*");
|
||||
hSearch = FindFirstFile(searchStr.data(), &fileData);
|
||||
if (hSearch == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(fileData.dwFileAttributes ^ FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
auto dirName = toUtf8(fileData.cFileName);
|
||||
|
||||
if ("." != dirName && ".." != dirName)
|
||||
dirsList->push_back(path + dirName + "/");
|
||||
}
|
||||
|
||||
} while (FindNextFile(hSearch, &fileData));
|
||||
|
||||
FindClose(hSearch);
|
||||
|
||||
return true;
|
||||
}
|
||||
#elif __linux__ == 1 || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <fnmatch.h>
|
||||
|
||||
bool findFiles(const string& path, const string& fileMask, vector<string>* fileList, bool savePaths)
|
||||
{
|
||||
dirent** namelist;
|
||||
|
||||
int n = scandir(path.c_str(), &namelist, 0, 0); // alphasort);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
if (namelist[n]->d_type == DT_REG)
|
||||
{
|
||||
string fileName(namelist[n]->d_name);
|
||||
|
||||
if (0 == fnmatch(fileMask.c_str(), fileName.c_str(), 0))
|
||||
fileList->push_back(savePaths ? path + fileName : fileName);
|
||||
}
|
||||
free(namelist[n]);
|
||||
}
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findDirs(const string& path, vector<string>* dirsList)
|
||||
{
|
||||
dirent** namelist;
|
||||
|
||||
int n = scandir(path.c_str(), &namelist, 0, 0); // alphasort);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
if (namelist[n]->d_type == DT_DIR)
|
||||
{
|
||||
string dirName(namelist[n]->d_name);
|
||||
|
||||
// we save only normal ones
|
||||
if ("." != dirName && ".." != dirName)
|
||||
dirsList->push_back(path + dirName + "/");
|
||||
}
|
||||
free(namelist[n]);
|
||||
}
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool findFilesRecursive(const string& path, const string& mask, vector<string>* const fileList)
|
||||
{
|
||||
// finding files
|
||||
findFiles(path, mask, fileList, true);
|
||||
|
||||
vector<string> dirList;
|
||||
findDirs(path, &dirList);
|
||||
|
||||
for (unsigned int d_idx = 0; d_idx != dirList.size(); d_idx++) findFilesRecursive(dirList[d_idx], mask, fileList);
|
||||
|
||||
return true;
|
||||
}
|
55
libmediation/fs/directory_priv.h
Normal file
55
libmediation/fs/directory_priv.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef libmediation_directory_priv_h
|
||||
#define libmediation_directory_priv_h
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
template <typename F, typename D>
|
||||
void recurseDirectorySearch(F&& findFilesFn, D&& findDirsFn, const std::string& path, const std::string& mask,
|
||||
std::vector<std::string>* const fileList)
|
||||
{
|
||||
// finding files
|
||||
findFilesFn(path, mask, fileList, true);
|
||||
|
||||
std::vector<std::string> dirList;
|
||||
findDirsFn(path, &dirList);
|
||||
|
||||
for (auto&& dir : dirList)
|
||||
{
|
||||
recurseDirectorySearch(findFilesFn, findDirsFn, dir, mask, fileList);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SkipParentDirFn, typename CreateParentDirFn>
|
||||
bool preCreateDir(SkipParentDirFn&& skipParentFn, CreateParentDirFn&& createParentFn, char dirSeparator,
|
||||
const std::string& dirName, bool createParentDirs)
|
||||
{
|
||||
if (dirName.empty())
|
||||
return false;
|
||||
|
||||
if (createParentDirs)
|
||||
{
|
||||
for (auto separatorPos = dirName.find_first_not_of(dirSeparator), dirEnd = std::string::npos;
|
||||
separatorPos != std::string::npos;
|
||||
dirEnd = separatorPos, separatorPos = dirName.find_first_not_of(dirSeparator, separatorPos))
|
||||
{
|
||||
separatorPos = dirName.find(dirSeparator, separatorPos);
|
||||
if (dirEnd != std::string::npos)
|
||||
{
|
||||
auto parentDir = dirName.substr(0, dirEnd);
|
||||
if (skipParentFn(parentDir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!createParentFn(parentDir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
116
libmediation/fs/osdep/directory_unix.cpp
Normal file
116
libmediation/fs/osdep/directory_unix.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include "../directory.h"
|
||||
#include "../directory_priv.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fnmatch.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
char getDirSeparator() { return '/'; }
|
||||
|
||||
string extractFileDir(const string& fileName)
|
||||
{
|
||||
size_t index = fileName.find_last_of('/');
|
||||
if (index != string::npos)
|
||||
return fileName.substr(0, index + 1);
|
||||
return "";
|
||||
}
|
||||
|
||||
bool fileExists(const string& fileName)
|
||||
{
|
||||
struct stat buf;
|
||||
return stat(fileName.c_str(), &buf) == 0;
|
||||
}
|
||||
|
||||
uint64_t getFileSize(const std::string& fileName)
|
||||
{
|
||||
struct stat fileStat;
|
||||
auto res = stat(fileName.c_str(), &fileStat) == 0;
|
||||
return res ? static_cast<uint64_t>(fileStat.st_size) : 0;
|
||||
}
|
||||
|
||||
bool createDir(const std::string& dirName, bool createParentDirs)
|
||||
{
|
||||
auto ok = preCreateDir([](auto) { return false; },
|
||||
[](auto&& parentDir) {
|
||||
if (mkdir(parentDir.c_str(), S_IREAD | S_IWRITE | S_IEXEC) == -1)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getDirSeparator(), dirName, createParentDirs);
|
||||
|
||||
return ok ? mkdir(dirName.c_str(), S_IREAD | S_IWRITE | S_IEXEC) == 0 : false;
|
||||
}
|
||||
|
||||
bool deleteFile(const string& fileName) { return unlink(fileName.c_str()) == 0; }
|
||||
|
||||
bool findFiles(const string& path, const string& fileMask, vector<string>* fileList, bool savePaths)
|
||||
{
|
||||
dirent** namelist;
|
||||
|
||||
int n = scandir(path.c_str(), &namelist, 0, 0); // alphasort);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
if (namelist[n]->d_type == DT_REG)
|
||||
{
|
||||
string fileName(namelist[n]->d_name);
|
||||
|
||||
if (0 == fnmatch(fileMask.c_str(), fileName.c_str(), 0))
|
||||
fileList->push_back(savePaths ? path + fileName : fileName);
|
||||
}
|
||||
free(namelist[n]);
|
||||
}
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findDirs(const string& path, vector<string>* dirsList)
|
||||
{
|
||||
dirent** namelist;
|
||||
|
||||
int n = scandir(path.c_str(), &namelist, 0, 0); // alphasort);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
if (namelist[n]->d_type == DT_DIR)
|
||||
{
|
||||
string dirName(namelist[n]->d_name);
|
||||
|
||||
// we save only normal ones
|
||||
if ("." != dirName && ".." != dirName)
|
||||
dirsList->push_back(path + dirName + "/");
|
||||
}
|
||||
free(namelist[n]);
|
||||
}
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findFilesRecursive(const string& path, const string& mask, vector<string>* const fileList)
|
||||
{
|
||||
recurseDirectorySearch(findFiles, findDirs, path, mask, fileList);
|
||||
return true;
|
||||
}
|
131
libmediation/fs/osdep/directory_win32.cpp
Normal file
131
libmediation/fs/osdep/directory_win32.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "../directory.h"
|
||||
#include "../directory_priv.h"
|
||||
|
||||
#include "../file.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
char getDirSeparator() { return '\\'; }
|
||||
|
||||
string extractFileDir(const string& fileName)
|
||||
{
|
||||
size_t index = fileName.find_last_of('\\');
|
||||
if (index != string::npos)
|
||||
return fileName.substr(0, index + 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool fileExists(const string& fileName)
|
||||
{
|
||||
File f;
|
||||
return f.open(fileName.c_str(), File::ofRead | File::ofOpenExisting);
|
||||
}
|
||||
|
||||
uint64_t getFileSize(const std::string& fileName)
|
||||
{
|
||||
File f;
|
||||
if (f.open(fileName.c_str(), File::ofRead | File::ofOpenExisting))
|
||||
{
|
||||
uint64_t rv;
|
||||
return f.size(&rv) ? rv : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool createDir(const std::string& dirName, bool createParentDirs)
|
||||
{
|
||||
bool ok = preCreateDir(
|
||||
[](auto&& parentDir) {
|
||||
return parentDir.empty() || parentDir[parentDir.size() - 1] == ':' || parentDir == "\\\\." ||
|
||||
parentDir == "\\\\.\\" || // UNC patch prefix
|
||||
(strStartWith(parentDir, "\\\\.\\") && parentDir[parentDir.size() - 1] == '}'); // UNC patch prefix
|
||||
},
|
||||
[](auto&& parentDir) {
|
||||
if (CreateDirectory(toWide(parentDir).data(), 0) == 0)
|
||||
{
|
||||
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getDirSeparator(), dirName, createParentDirs);
|
||||
return ok ? CreateDirectory(toWide(dirName).data(), 0) != 0 : false;
|
||||
}
|
||||
|
||||
bool deleteFile(const string& fileName)
|
||||
{
|
||||
if (DeleteFile(toWide(fileName).data()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
return false;
|
||||
}
|
||||
|
||||
return DeleteFile(toWide(fileName).data()) != 0;
|
||||
}
|
||||
|
||||
bool findFiles(const string& path, const string& fileMask, vector<string>* fileList, bool savePaths)
|
||||
{
|
||||
WIN32_FIND_DATA fileData; // Data structure describes the file found
|
||||
HANDLE hSearch; // Search handle returned by FindFirstFile
|
||||
|
||||
auto searchStr = toWide(path + '/' + fileMask);
|
||||
hSearch = FindFirstFile(searchStr.data(), &fileData);
|
||||
if (hSearch == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
auto fileName = toUtf8(fileData.cFileName);
|
||||
fileList->push_back(savePaths ? (path + '/' + fileName) : fileName);
|
||||
}
|
||||
} while (FindNextFile(hSearch, &fileData));
|
||||
|
||||
FindClose(hSearch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findDirs(const string& path, vector<string>* dirsList)
|
||||
{
|
||||
WIN32_FIND_DATA fileData; // Data structure describes the file found
|
||||
HANDLE hSearch; // Search handle returned by FindFirstFile
|
||||
|
||||
auto searchStr = toWide(path + "*");
|
||||
hSearch = FindFirstFile(searchStr.data(), &fileData);
|
||||
if (hSearch == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(fileData.dwFileAttributes ^ FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
auto dirName = toUtf8(fileData.cFileName);
|
||||
|
||||
if ("." != dirName && ".." != dirName)
|
||||
dirsList->push_back(path + dirName + "/");
|
||||
}
|
||||
|
||||
} while (FindNextFile(hSearch, &fileData));
|
||||
|
||||
FindClose(hSearch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findFilesRecursive(const string& path, const string& mask, vector<string>* const fileList)
|
||||
{
|
||||
recurseDirectorySearch(findFiles, findDirs, path, mask, fileList);
|
||||
return true;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user