mirror of https://github.com/stella-emu/stella.git
Some optimizations for FSNodeWINDOWS.
This commit is contained in:
parent
0a14629fa4
commit
35bc4ac8b6
|
@ -43,7 +43,7 @@ FSNodeZIP::FSNodeZIP(const string& p)
|
|||
if (home != nullptr)
|
||||
_zipFile.replace(0, 1, home);
|
||||
#elif defined(BSPF_WINDOWS)
|
||||
_zipFile.replace(0, 1, myHomeFinder.getHomePath());
|
||||
_zipFile.replace(0, 1, HomeFinder::getHomePath());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -16,69 +16,47 @@
|
|||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
#pragma warning( disable : 4091 )
|
||||
#pragma warning(disable : 4091)
|
||||
#include <shlobj.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// F_OK, R_OK and W_OK are not defined under MSVC, so we define them here
|
||||
// For more information on the modes used by MSVC, check:
|
||||
// http://msdn2.microsoft.com/en-us/library/1w06ktdy(VS.80).aspx
|
||||
#ifndef F_OK
|
||||
#define F_OK 0
|
||||
#endif
|
||||
|
||||
#ifndef R_OK
|
||||
#define R_OK 4
|
||||
#endif
|
||||
|
||||
#ifndef W_OK
|
||||
#define W_OK 2
|
||||
#endif
|
||||
#include <tchar.h>
|
||||
|
||||
#include "Windows.hxx"
|
||||
#include "FSNodeWINDOWS.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::exists() const
|
||||
FSNodeWINDOWS::FSNodeWINDOWS(const string& p)
|
||||
: _path{p.length() > 0 ? p : "~"} // Default to home directory
|
||||
{
|
||||
return _access(_path.c_str(), F_OK) == 0;
|
||||
}
|
||||
// Expand '~' to the users 'home' directory
|
||||
if (_path[0] == '~')
|
||||
_path.replace(0, 1, HomeFinder::getHomePath());
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::isReadable() const
|
||||
{
|
||||
return _access(_path.c_str(), R_OK) == 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::isWritable() const
|
||||
{
|
||||
return _access(_path.c_str(), W_OK) == 0;
|
||||
setFlags();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FSNodeWINDOWS::setFlags()
|
||||
{
|
||||
// Get absolute path
|
||||
TCHAR buf[4096];
|
||||
if(GetFullPathName(_path.c_str(), 4096, buf, NULL))
|
||||
TCHAR buf[MAX_PATH];
|
||||
if(GetFullPathName(_path.c_str(), MAX_PATH - 1, buf, NULL))
|
||||
_path = buf;
|
||||
|
||||
_displayName = lastPathComponent(_path);
|
||||
|
||||
// Check whether it is a directory, and whether the file actually exists
|
||||
const DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));
|
||||
const DWORD fileAttribs = GetFileAttributes(_path.c_str());
|
||||
|
||||
if(fileAttribs == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
_isDirectory = _isFile = _isValid = false;
|
||||
_isDirectory = _isFile = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
_isFile = !_isDirectory;//((fileAttribs & FILE_ATTRIBUTE_NORMAL) != 0);
|
||||
_isValid = true;
|
||||
|
||||
// Add a trailing backslash, if necessary
|
||||
if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '\\')
|
||||
|
@ -87,83 +65,11 @@ void FSNodeWINDOWS::setFlags()
|
|||
_isPseudoRoot = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FSNodeWINDOWS::addFile(AbstractFSList& list, ListMode mode,
|
||||
const char* base, WIN32_FIND_DATA* find_data)
|
||||
{
|
||||
FSNodeWINDOWS entry;
|
||||
const char* const asciiName = toAscii(find_data->cFileName);
|
||||
bool isDirectory = false, isFile = false;
|
||||
|
||||
// Skip local directory (.) and parent (..)
|
||||
if(!strncmp(asciiName, ".", 1) || !strncmp(asciiName, "..", 2))
|
||||
return;
|
||||
|
||||
isDirectory = ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
|
||||
isFile = !isDirectory;//(find_data->dwFileAttributes & FILE_ATTRIBUTE_NORMAL ? true : false);
|
||||
|
||||
if((isFile && mode == FSNode::ListMode::DirectoriesOnly) ||
|
||||
(isDirectory && mode == FSNode::ListMode::FilesOnly))
|
||||
return;
|
||||
|
||||
entry._isDirectory = isDirectory;
|
||||
entry._isFile = isFile;
|
||||
entry._displayName = asciiName;
|
||||
entry._path = base;
|
||||
entry._path += asciiName;
|
||||
if(entry._isDirectory)
|
||||
entry._path += "\\";
|
||||
entry._isValid = true;
|
||||
entry._isPseudoRoot = false;
|
||||
|
||||
list.emplace_back(make_shared<FSNodeWINDOWS>(entry));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
char* FSNodeWINDOWS::toAscii(TCHAR* str)
|
||||
{
|
||||
#ifndef UNICODE
|
||||
return str;
|
||||
#else
|
||||
static char asciiString[MAX_PATH];
|
||||
WideCharToMultiByte(CP_ACP, 0, str, _tcslen(str) + 1, asciiString, sizeof(asciiString), NULL, NULL);
|
||||
return asciiString;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const TCHAR* FSNodeWINDOWS::toUnicode(const char* str)
|
||||
{
|
||||
#ifndef UNICODE
|
||||
return str;
|
||||
#else
|
||||
static TCHAR unicodeString[MAX_PATH];
|
||||
MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, unicodeString, sizeof(unicodeString) / sizeof(TCHAR));
|
||||
return unicodeString;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FSNodeWINDOWS::FSNodeWINDOWS()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FSNodeWINDOWS::FSNodeWINDOWS(const string& p)
|
||||
: _path{p.length() > 0 ? p : "~"} // Default to home directory
|
||||
{
|
||||
// Expand '~' to the users 'home' directory
|
||||
if(_path[0] == '~')
|
||||
_path.replace(0, 1, myHomeFinder.getHomePath());
|
||||
|
||||
setFlags();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FSNodeWINDOWS::getShortPath() const
|
||||
{
|
||||
// If the path starts with the home directory, replace it with '~'
|
||||
const string& home = myHomeFinder.getHomePath();
|
||||
const string& home = HomeFinder::getHomePath();
|
||||
if(home != "" && BSPF::startsWithIgnoreCase(_path, home))
|
||||
{
|
||||
string path = "~";
|
||||
|
@ -176,8 +82,35 @@ string FSNodeWINDOWS::getShortPath() const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::
|
||||
getChildren(AbstractFSList& myList, ListMode mode) const
|
||||
size_t FSNodeWINDOWS::getSize() const
|
||||
{
|
||||
if (_size == 0)
|
||||
{
|
||||
struct _stat st;
|
||||
_size = _stat(_path.c_str(), &st) == 0 ? st.st_size : 0;
|
||||
}
|
||||
return _size;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFSNodePtr FSNodeWINDOWS::getParent() const
|
||||
{
|
||||
if (_isPseudoRoot)
|
||||
return nullptr;
|
||||
|
||||
if (_path.size() > 3)
|
||||
{
|
||||
const char* start = _path.c_str();
|
||||
const char* end = lastPathComponent(_path);
|
||||
|
||||
return make_shared<FSNodeWINDOWS>(string(start, static_cast<size_t>(end - start)));
|
||||
}
|
||||
else
|
||||
return make_shared<FSNodeWINDOWS>();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::getChildren(AbstractFSList& myList, ListMode mode) const
|
||||
{
|
||||
assert(_isDirectory);
|
||||
|
||||
|
@ -193,14 +126,13 @@ bool FSNodeWINDOWS::
|
|||
FSNodeWINDOWS entry;
|
||||
char drive_name[2] = { 0, 0 };
|
||||
|
||||
drive_name[0] = toAscii(current_drive)[0];
|
||||
drive_name[0] = current_drive[0];
|
||||
drive_name[1] = '\0';
|
||||
entry._displayName = drive_name;
|
||||
entry._isDirectory = true;
|
||||
entry._isFile = false;
|
||||
entry._isValid = true;
|
||||
entry._isPseudoRoot = false;
|
||||
entry._path = toAscii(current_drive);
|
||||
entry._path = current_drive;
|
||||
myList.emplace_back(make_shared<FSNodeWINDOWS>(entry));
|
||||
}
|
||||
}
|
||||
|
@ -229,10 +161,52 @@ bool FSNodeWINDOWS::
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
size_t FSNodeWINDOWS::getSize() const
|
||||
void FSNodeWINDOWS::addFile(AbstractFSList& list, ListMode mode,
|
||||
const char* base, const WIN32_FIND_DATA* find_data)
|
||||
{
|
||||
struct _stat st;
|
||||
return _stat(_path.c_str(), &st) == 0 ? st.st_size : 0;
|
||||
const char* const asciiName = find_data->cFileName;
|
||||
bool isDirectory = false, isFile = false;
|
||||
|
||||
// Skip local directory (.) and parent (..)
|
||||
if (!strncmp(asciiName, ".", 1) || !strncmp(asciiName, "..", 2))
|
||||
return;
|
||||
|
||||
isDirectory = static_cast<bool>(find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
isFile = !isDirectory;//(find_data->dwFileAttributes & FILE_ATTRIBUTE_NORMAL ? true : false);
|
||||
|
||||
if ((isFile && mode == FSNode::ListMode::DirectoriesOnly) ||
|
||||
(isDirectory && mode == FSNode::ListMode::FilesOnly))
|
||||
return;
|
||||
|
||||
FSNodeWINDOWS entry;
|
||||
entry._isDirectory = isDirectory;
|
||||
entry._isFile = isFile;
|
||||
entry._displayName = asciiName;
|
||||
entry._path = base;
|
||||
entry._path += asciiName;
|
||||
if (entry._isDirectory)
|
||||
entry._path += "\\";
|
||||
entry._isPseudoRoot = false;
|
||||
|
||||
list.emplace_back(make_shared<FSNodeWINDOWS>(entry));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::exists() const
|
||||
{
|
||||
return _access(_path.c_str(), 0 /*F_OK*/) == 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::isReadable() const
|
||||
{
|
||||
return _access(_path.c_str(), 4 /*R_OK*/) == 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FSNodeWINDOWS::isWritable() const
|
||||
{
|
||||
return _access(_path.c_str(), 2 /*W_OK*/) == 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -258,20 +232,3 @@ bool FSNodeWINDOWS::rename(const string& newfile)
|
|||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFSNodePtr FSNodeWINDOWS::getParent() const
|
||||
{
|
||||
if(_isPseudoRoot)
|
||||
return nullptr;
|
||||
|
||||
if(_path.size() > 3)
|
||||
{
|
||||
const char* start = _path.c_str();
|
||||
const char* end = lastPathComponent(_path);
|
||||
|
||||
return make_shared<FSNodeWINDOWS>(string(start, static_cast<size_t>(end - start)));
|
||||
}
|
||||
else
|
||||
return make_shared<FSNodeWINDOWS>();
|
||||
}
|
||||
|
|
|
@ -18,13 +18,9 @@
|
|||
#ifndef FS_NODE_WINDOWS_HXX
|
||||
#define FS_NODE_WINDOWS_HXX
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#include "FSNode.hxx"
|
||||
#include "HomeFinder.hxx"
|
||||
|
||||
static HomeFinder myHomeFinder;
|
||||
|
||||
// TODO - fix isFile() functionality so that it actually determines if something
|
||||
// is a file; for now, it assumes a file if it isn't a directory
|
||||
|
||||
|
@ -41,9 +37,8 @@ class FSNodeWINDOWS : public AbstractFSNode
|
|||
* Creates a FSNodeWINDOWS with the root node as path.
|
||||
*
|
||||
* In regular windows systems, a virtual root path is used "".
|
||||
* In windows CE, the "\" root is used instead.
|
||||
*/
|
||||
FSNodeWINDOWS();
|
||||
FSNodeWINDOWS() : _isPseudoRoot{true}, _isDirectory{true} { }
|
||||
|
||||
/**
|
||||
* Creates a FSNodeWINDOWS for a given path.
|
||||
|
@ -62,7 +57,6 @@ class FSNodeWINDOWS : public AbstractFSNode
|
|||
void setName(const string& name) override { _displayName = name; }
|
||||
const string& getPath() const override { return _path; }
|
||||
string getShortPath() const override;
|
||||
bool hasParent() const override { return !_isPseudoRoot; }
|
||||
bool isDirectory() const override { return _isDirectory; }
|
||||
bool isFile() const override { return _isFile; }
|
||||
bool isReadable() const override;
|
||||
|
@ -71,16 +65,9 @@ class FSNodeWINDOWS : public AbstractFSNode
|
|||
bool rename(const string& newfile) override;
|
||||
|
||||
size_t getSize() const override;
|
||||
bool getChildren(AbstractFSList& list, ListMode mode) const override;
|
||||
bool hasParent() const override { return !_isPseudoRoot; }
|
||||
AbstractFSNodePtr getParent() const override;
|
||||
|
||||
protected:
|
||||
string _displayName;
|
||||
string _path;
|
||||
bool _isDirectory{true};
|
||||
bool _isFile{false};
|
||||
bool _isPseudoRoot{true};
|
||||
bool _isValid{false};
|
||||
bool getChildren(AbstractFSList& list, ListMode mode) const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -98,23 +85,13 @@ class FSNodeWINDOWS : public AbstractFSNode
|
|||
* @param base String with the directory being listed.
|
||||
* @param find_data Describes a file that the FindFirstFile, FindFirstFileEx, or FindNextFile functions find.
|
||||
*/
|
||||
static void addFile(AbstractFSList& list, ListMode mode, const char* base, WIN32_FIND_DATA* find_data);
|
||||
static void addFile(AbstractFSList& list, ListMode mode,
|
||||
const char* base, const WIN32_FIND_DATA* find_data);
|
||||
|
||||
/**
|
||||
* Converts a Unicode string to Ascii format.
|
||||
*
|
||||
* @param str String to convert from Unicode to Ascii.
|
||||
* @return str in Ascii format.
|
||||
*/
|
||||
static char* toAscii(TCHAR *str);
|
||||
|
||||
/**
|
||||
* Converts an Ascii string to Unicode format.
|
||||
*
|
||||
* @param str String to convert from Ascii to Unicode.
|
||||
* @return str in Unicode format.
|
||||
*/
|
||||
static const TCHAR* toUnicode(const char* str);
|
||||
private:
|
||||
string _displayName, _path;
|
||||
bool _isPseudoRoot{false}, _isDirectory{false}, _isFile{false};
|
||||
mutable size_t _size{0};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,7 @@ class HomeFinder
|
|||
~HomeFinder() = default;
|
||||
|
||||
// Return the 'APPDATA' folder, or an empty string if the folder couldn't be determined.
|
||||
const string& getAppDataPath() const
|
||||
static const string& getAppDataPath()
|
||||
{
|
||||
if(ourAppDataPath == "")
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ class HomeFinder
|
|||
}
|
||||
|
||||
// Return the 'Desktop' folder, or an empty string if the folder couldn't be determined.
|
||||
const string& getDesktopPath() const
|
||||
static const string& getDesktopPath()
|
||||
{
|
||||
if(ourDesktopPath == "")
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ class HomeFinder
|
|||
}
|
||||
|
||||
// Return the 'My Documents' folder, or an empty string if the folder couldn't be determined.
|
||||
const string& getDocumentsPath() const
|
||||
static const string& getDocumentsPath()
|
||||
{
|
||||
if(ourDocumentsPath == "")
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ class HomeFinder
|
|||
}
|
||||
|
||||
// Return the 'HOME/User' folder, or an empty string if the folder couldn't be determined.
|
||||
const string& getHomePath() const
|
||||
static const string& getHomePath()
|
||||
{
|
||||
if(ourHomePath == "")
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue