Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use std::filesystem instead of windows API in Orbiter core #424

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 21 additions & 53 deletions Sound/XRSound/src/Utils/FileList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,79 +53,47 @@ void FileList::Scan(const char *pPath, const int recursionLevel)

// This code was broken out from XRPayloadClassData::InitializeXRPayloadClassData().

WIN32_FIND_DATA findFileData;
char pConfigFilespecWildcard[MAX_PATH];
sprintf_s(pConfigFilespecWildcard, "%s\\*", pPath); // iterate through all files and directories

HANDLE hFind = ::FindFirstFile(pConfigFilespecWildcard, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
return; // directory is empty (should really never happen because "." and ".." are always present)

// found at least one file
goto process_file; // a little goofy, but that's Windows' goofy FindFirstFile/FindNextFile for you...

// now loop through all remaining files
for (;;)
{
if (::FindNextFile(hFind, &findFileData) != 0)
{
process_file: // entry point from FirstFirstFile
// build the new configdir-relative path
char pNodeFilespec[MAX_PATH];
sprintf_s(pNodeFilespec, "%s\\%s", pPath, findFileData.cFileName); // e.g., "Vessels\XRParts.cfg"

if (!STARTSWITH_DOT(findFileData)) // file not "." or ".."?
for (auto& file : fs::directory_iterator(pPath)) {
if (file.path().stem().c_str()[0] != '.') {
if (clbkFilterNode(file))
{
if (clbkFilterNode(pNodeFilespec, findFileData))
// node should be included
if (file.is_directory())
{
// node should be included
if (IS_DIRECTORY(findFileData))
{
// this is a directory, so recurse down into it
Scan(pNodeFilespec, recursionLevel + 1);
}
else if (!IS_EMPTY(findFileData)) // it's a file node; is it not empty?
{
// it's a file and it's not empty, so add it to our master list of nodes and invoke the callback for subclasses to hook
m_allFiles.push_back(pNodeFilespec);
clbkProcessFile(pNodeFilespec, findFileData);
}
// this is a directory, so recurse down into it
Scan(file.path().string().c_str(), recursionLevel + 1);
}
else if (file.file_size() > 0) // it's a file node; is it not empty?
{
// it's a file and it's not empty, so add it to our master list of nodes and invoke the callback for subclasses to hook
m_allFiles.push_back(file.path().string().c_str());
clbkProcessFile(file);
}
}
} // if (::FindNextFile(hFind, &findFileData) != 0)
else // FindNextFile failed
{
// check the error; continue parsing next file unless "no more files" reached
DWORD dwError = GetLastError();
if (dwError == ERROR_NO_MORE_FILES)
break; // all done
// else skip this file: fall through and parse the next file
}
} // for (;;)
FindClose(hFind);
}
}

// Invoked for each file or folder node found. The default method here looks at bRecurseSubfolders (for folder nodes) and
// pFileTypesToAccept (for file nodes) to decide whether accept a node or not.
// Subclasses should override this method if they want more advanced filtering.
//
// Returns true if file node should be included or folder should be recursed into, or false if the node should be skipped.
bool FileList::clbkFilterNode(const char *pPathOfNode, const WIN32_FIND_DATA &fd)
bool FileList::clbkFilterNode(const fs::directory_entry& entry)
{
if (IS_DIRECTORY(fd))
return m_bRecurseSubfolders;
if (entry.is_directory())
return m_bRecurseSubfolders;

// it's a file node
bool bAcceptFile = false;
if (!m_fileTypesToAccept.empty())
{
const char *pFileExtension = strrchr(fd.cFileName, '.');
if (pFileExtension) // e.g., ".flac"
if (entry.path().extension().string().length() > 0) // e.g., ".flac"
{
// see if we have a case-insensitive match for this extension in our master list
for (vector<CString>::const_iterator it = m_fileTypesToAccept.begin(); it != m_fileTypesToAccept.end(); it++)
for (auto it = m_fileTypesToAccept.begin(); it != m_fileTypesToAccept.end(); it++)
{
if (_stricmp(pFileExtension, *it) == 0)
if (stricmp(entry.path().extension().string().c_str(), *it) == 0)
{
bAcceptFile = true;
break;
Expand All @@ -140,7 +108,7 @@ bool FileList::clbkFilterNode(const char *pPathOfNode, const WIN32_FIND_DATA &fd
}

// Callback invoked for non-empty file nodes that passed the clbkFilterNode check; this is here for subclasses to hook.
void FileList::clbkProcessFile(const char *pFilespec, const WIN32_FIND_DATA &fd)
void FileList::clbkProcessFile(const fs::directory_entry& entry)
{
// no-op; this method is for subclasses to use
}
Expand Down
14 changes: 9 additions & 5 deletions Sound/XRSound/src/Utils/FileList.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

using namespace std;

#include <filesystem>
namespace fs = std::filesystem;

class FileList
{
public:
Expand All @@ -23,9 +26,10 @@ class FileList

static bool DirectoryExists(const char *pPath)
{
DWORD dwAttrib = GetFileAttributes(pPath);

return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
std::error_code ec;
auto status = fs::status(pPath, ec);
if(ec) return false;
return fs::is_directory(status);
}

// Scan (or rescan) file tree.
Expand All @@ -41,10 +45,10 @@ class FileList

// Invoked for each file or folder node found; should return true if file node should be included or folder should be
// recursed into, or false if the node should be skipped.
virtual bool clbkFilterNode(const char *pPathOfNode, const WIN32_FIND_DATA &fd);
virtual bool clbkFilterNode(const fs::directory_entry &);

// Callback invoked for non-empty file nodes that passed the clbkFilterNode check; this is here for subclasses to hook.
virtual void clbkProcessFile(const char *pFilespec, const WIN32_FIND_DATA &fd);
virtual void clbkProcessFile(const fs::directory_entry &);

int GetScannedFileCount() const { return static_cast<int>(m_allFiles.size()); }
bool IsEmpty() const { return m_allFiles.empty(); }
Expand Down
33 changes: 12 additions & 21 deletions Src/Orbiter/FlightRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
#include "State.h"
#include "MenuInfoBar.h"
#include <fstream>
#include <iomanip>
#include <io.h>
#include <direct.h>
#include <errno.h>
#include <string>
#include <filesystem>
namespace fs = std::filesystem;

using namespace std;

Expand Down Expand Up @@ -776,24 +774,17 @@ void Orbiter::FRecorder_Reset ()

bool Orbiter::FRecorder_PrepareDir (const char *fname, bool force)
{
char cbuf[256];
strcpy (cbuf, "Flights\\"); strcat (cbuf, fname);
if (_mkdir (cbuf) == -1) {
if (errno == EEXIST && !force) return false;
// don't overwrite existing recording
struct _finddata_t fd;
char cb2[256], cb3[256];
strcpy (cb2, cbuf); strcat (cb2, "\\*");
intptr_t handle = _findfirst (cb2, &fd), res = handle;
while (res != -1) {
if (!(fd.attrib & _A_SUBDIR)) {
sprintf (cb3, "%s\\%s", cbuf, fd.name);
_unlink (cb3);
}
res = _findnext (handle, &fd);
}
_findclose (handle);
fs::path dir = fs::path("Flights") / fname;
std::error_code ec;
auto status = fs::status(dir, ec);

// don't overwrite existing recording
if (!ec) {
if(fs::is_directory(status) && !force) return false;
fs::remove_all(dir);
}
fs::create_directory(dir);

return true;
}

Expand Down
18 changes: 6 additions & 12 deletions Src/Orbiter/GraphicsAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#include "Util.h"
#include "resource.h"
#include <wincodec.h>
#include <io.h>
#include <filesystem>
namespace fs = std::filesystem;

using std::min;

Expand Down Expand Up @@ -178,24 +179,17 @@ ScreenAnnotation *GraphicsClient::clbkCreateAnnotation ()

bool GraphicsClient::TexturePath (const char *fname, char *path) const
{
struct _finddata_t fd;
intptr_t fh;

// first try htex directory
strcpy (path, g_pOrbiter->Cfg()->CfgDirPrm.HightexDir);
strcat (path, fname);
if ((fh = _findfirst (path, &fd)) != -1) {
_findclose (fh);
return true;
}
if (fs::exists(path)) return true;

// try tex directory
strcpy (path, g_pOrbiter->Cfg()->CfgDirPrm.TextureDir);
strcat (path, fname);
if ((fh = _findfirst (path, &fd)) != -1) {
_findclose (fh);
return true;
}

if (fs::exists(path)) return true;

return false;
}

Expand Down
35 changes: 12 additions & 23 deletions Src/Orbiter/OptionsPages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// ======================================================================

#include <windows.h>
#include <io.h>
#include <array>
#include "OptionsPages.h"
#include "DlgCtrl.h"
Expand Down Expand Up @@ -1905,19 +1904,13 @@ void OptionsPage_Planetarium::RescanMarkerList(HWND hPage)
const std::vector< oapi::GraphicsClient::LABELLIST>& list = g_psys->LabelList();
if (!list.size()) return;

char cbuf[256];
_finddata_t fdata;
intptr_t fh = g_psys->FindFirst(FILETYPE_MARKER, &fdata, cbuf);
if (fh >= 0) {
int n = 0;
do {
SendDlgItemMessage(hPage, IDC_OPT_PLN_MKRLIST, LB_ADDSTRING, 0, (LPARAM)trim_string(cbuf));
if (n < list.size() && list[n].active)
SendDlgItemMessage(hPage, IDC_OPT_PLN_MKRLIST, LB_SETSEL, TRUE, n);
n++;
} while (!g_psys->FindNext(fh, &fdata, cbuf));
_findclose(fh);
}
int n = 0;
g_psys->ForEach(FILETYPE_MARKER, [&](const fs::directory_entry& entry) {
SendDlgItemMessage(hPage, IDC_OPT_PLN_MKRLIST, LB_ADDSTRING, 0, (LPARAM)entry.path().stem().string().c_str());
if (n < list.size() && list[n].active)
SendDlgItemMessage(hPage, IDC_OPT_PLN_MKRLIST, LB_SETSEL, TRUE, n);
n++;
});
}

// ======================================================================
Expand Down Expand Up @@ -2084,18 +2077,14 @@ void OptionsPage_Labels::UpdateFeatureList(HWND hPage)
if (planet->LabelFormat() < 2) {
oapi::GraphicsClient::LABELLIST* list = planet->LabelList(&nlist);
if (!nlist) return;
_finddata_t fdata;
long fh = planet->FindFirst(FILETYPE_MARKER, &fdata, cpath, cbuf);
if (fh >= 0) {
n = 0;
do {
SendDlgItemMessage(hPage, IDC_OPT_MKR_FEATURELIST, LB_ADDSTRING, 0, (LPARAM)trim_string(cbuf));

n = 0;
planet->ForEach(FILETYPE_MARKER, [&](const fs::directory_entry& entry) {
SendDlgItemMessage(hPage, IDC_OPT_MKR_FEATURELIST, LB_ADDSTRING, 0, (LPARAM)entry.path().stem().string().c_str());
if (n < nlist && list[n].active)
SendDlgItemMessage(hPage, IDC_OPT_MKR_FEATURELIST, LB_SETSEL, TRUE, n);
n++;
} while (!planet->FindNext(fh, &fdata, cbuf));
_findclose(fh);
}
});
}
else {
int nlabel = planet->NumLabelLegend();
Expand Down
33 changes: 10 additions & 23 deletions Src/Orbiter/Orbiter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

#include <windows.h>
#include <zmouse.h>
#include <commctrl.h>
#include <mmsystem.h>
#include <process.h>
#include <direct.h>
#include <stdio.h>
#include <time.h>
#include <fstream>
#include <iomanip>
#include <io.h>
#include <process.h>
#include "cmdline.h"
#include "D3d7util.h"
#include "D3dmath.h"
Expand Down Expand Up @@ -48,6 +43,8 @@
#include "DlgCtrl.h"
#include "GraphicsAPI.h"
#include "ConsoleManager.h"
#include <filesystem>
namespace fs = std::filesystem;

#ifdef INLINEGRAPHICS
#include "OGraphics.h"
Expand Down Expand Up @@ -544,18 +541,13 @@ int Orbiter::GetVersion () const
return v;
}

static bool FileExists(const char* path)
{
return access(path, 0) != -1;
}

//! Finds legacy module consisting of a single DLL
//! @return true on success
//! @param cbufOut returns path to the plugin DLL
static bool FindStandaloneDll(const char *path, const char *name, char* cbufOut)
{
sprintf (cbufOut, "%s\\%s.dll", path, name);
return FileExists(cbufOut);
return fs::exists(cbufOut);
}

//! Finds module consisting of a plugin DLL inside a plugin-specific folder
Expand All @@ -564,7 +556,7 @@ static bool FindStandaloneDll(const char *path, const char *name, char* cbufOut)
static bool FindDllInPluginFolder(const char *path, const char *name, char* cbufOut)
{
sprintf(cbufOut, "%s\\%s\\%s.dll", path, name, name);
return FileExists(cbufOut);
return fs::exists(cbufOut);
}

void Orbiter::LoadModules(const std::string& path, const std::list<std::string>& names)
Expand All @@ -573,19 +565,14 @@ void Orbiter::LoadModules(const std::string& path, const std::list<std::string>&
LoadModule(path.c_str(), name.c_str());
}


void Orbiter::LoadModules(const std::string& path)
{
struct _finddata_t fdata;
intptr_t fh = _findfirst((path + std::string("\\*.dll")).c_str(), &fdata);
if (fh == -1) return; // no files found
do {
if (strlen(fdata.name) > 4) {
fdata.name[strlen(fdata.name) - 4] = '\0'; // cut off extension
LoadModule(path.c_str(), fdata.name);
for (const auto& entry : fs::directory_iterator(path)) {
auto fpath = entry.path();
if (fpath.extension().string() == ".dll") {
LoadModule(path.c_str(), fpath.stem().string().c_str());
}
} while (!_findnext(fh, &fdata));
_findclose(fh);
}
}

//-----------------------------------------------------------------------------
Expand Down
Loading
Loading