Fixed bug when loading from ZIP files created in OSX. In some

cases, these archives contain directories named '__MACOSX' which
contain link files that were being erroneously detected as actual
ROMs.

Added FilesystemNode::isFile() method, and updated several places
in the code to use it.  Previously, determining whether something
was a file was simply testing if it wasn't a directory, but this
logic isn't always valid (it's possible to be neither a regular
file *nor* a directory).

Bumped version # for RC release.  It's getting very close ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2477 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2012-05-16 20:52:33 +00:00
parent 042afc2edb
commit aa544ecfe9
11 changed files with 68 additions and 40 deletions

View File

@ -22,7 +22,7 @@
#include <cstdlib>
#define STELLA_VERSION "3.7_beta1"
#define STELLA_VERSION "3.7_rc1"
#define STELLA_BUILD atoi("$Rev$" + 6)
#endif

View File

@ -138,7 +138,7 @@ int main(int argc, char* argv[])
{
theOSystem->logMessage("Showing output from 'rominfo' ...\n", 2);
FilesystemNode romnode(romfile);
if(argc > 1 && romnode.exists() && !romnode.isDirectory())
if(argc > 1 && romnode.exists() && romnode.isFile())
theOSystem->logMessage(theOSystem->getROMInfo(romfile), 0);
else
theOSystem->logMessage("ERROR: ROM doesn't exist\n", 0);

View File

@ -623,7 +623,7 @@ string CartDebug::loadSymbolFile(string file)
file += ".sym";
FilesystemNode node(file);
if(node.exists() && !node.isDirectory())
if(node.exists() && node.isFile())
{
ifstream in(node.getPath().c_str());
if(!in.is_open())
@ -696,7 +696,7 @@ string CartDebug::loadConfigFile(string file)
}
}
if(node.exists() && !node.isDirectory())
if(node.exists() && node.isFile())
{
ifstream in(node.getPath().c_str());
if(!in.is_open())
@ -811,7 +811,7 @@ string CartDebug::saveConfigFile(string file)
myOSystem.romFile()).getParent().getPath() + name + ".cfg");
}
if(!node.isDirectory())
if(node.isFile())
{
ofstream out(node.getPath().c_str());
if(!out.is_open())

View File

@ -144,6 +144,15 @@ bool FilesystemNode::isDirectory() const
return _realNode->isDirectory();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FilesystemNode::isFile() const
{
if (_realNode == 0)
return false;
return _realNode->isFile();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FilesystemNode::isReadable() const
{

View File

@ -202,15 +202,16 @@ class FilesystemNode
/**
* Indicates whether the path refers to a directory or not.
*
* @todo Currently we assume that a node that is not a directory
* automatically is a file (ignoring things like symlinks or pipes).
* That might actually be OK... but we could still add an isFile method.
* Or even replace isDirectory by a getType() method that can return values like
* kDirNodeType, kFileNodeType, kInvalidNodeType.
*/
virtual bool isDirectory() const;
/**
* Indicates whether the path refers to a real file or not.
*
* Currently, a symlink or pipe is not considered a file.
*/
virtual bool isFile() const;
/**
* Indicates whether the object referred by this path can be read from or not.
*
@ -317,6 +318,11 @@ class AbstractFilesystemNode
*/
virtual bool isDirectory() const = 0;
/**
* Indicates whether this path refers to a real file or not.
*/
virtual bool isFile() const = 0;
/**
* Indicates whether the object referred by this path can be read from or not.
*
@ -343,10 +349,6 @@ class AbstractFilesystemNode
*/
virtual bool isWritable() const = 0;
/* TODO:
bool isFile();
*/
/**
Create a directory from the given path.
*/

View File

@ -861,7 +861,8 @@ bool OSystem::loadFromZIP(const string& filename, uInt8** image, uInt32& size)
unzGetCurrentFileInfo(tz, &ufo, currfile, 1024, 0, 0, 0, 0);
currfile[1023] = '\0';
if(strlen(currfile) >= 4)
if(strlen(currfile) >= 4 &&
!BSPF_startsWithIgnoreCase(filename, "__MACOSX"))
{
// Grab 3-character extension
const char* ext = currfile + strlen(currfile) - 4;

View File

@ -31,7 +31,7 @@ Serializer::Serializer(const string& filename, bool readonly)
if(readonly)
{
FilesystemNode node(filename);
if(!node.isDirectory() && node.isReadable())
if(node.isFile() && node.isReadable())
{
fstream* str = new fstream(filename.c_str(), ios::in | ios::binary);
if(str && str->is_open())

View File

@ -370,7 +370,8 @@ void LauncherDialog::loadDirListing()
unzGetCurrentFileInfo(tz, &ufo, filename, 1024, 0, 0, 0, 0);
filename[1023] = '\0';
if(strlen(filename) >= 4)
if(strlen(filename) >= 4 &&
!BSPF_startsWithIgnoreCase(filename, "__MACOSX"))
{
// Grab 3-character extension
const char* ext = filename + strlen(filename) - 4;
@ -545,7 +546,8 @@ int LauncherDialog::filesInArchive(const string& archive)
unzGetCurrentFileInfo(tz, &ufo, filename, 1024, 0, 0, 0, 0);
filename[1023] = '\0';
if(strlen(filename) >= 4)
if(strlen(filename) >= 4 &&
!BSPF_startsWithIgnoreCase(filename, "__MACOSX"))
{
// Grab 3-character extension
const char* ext = filename + strlen(filename) - 4;

View File

@ -142,7 +142,7 @@ void RomAuditDialog::auditRoms()
for(unsigned int idx = 0; idx < files.size(); idx++)
{
string extension;
if(!files[idx].isDirectory() &&
if(files[idx].isFile() &&
LauncherFilterDialog::isValidRomName(files[idx].getPath(), extension))
{
// Calculate the MD5 so we can get the rest of the info

View File

@ -53,8 +53,9 @@ class POSIXFilesystemNode : public AbstractFilesystemNode
/**
* Creates a POSIXFilesystemNode for a given path.
*
* @param path String with the path the new node should point to.
* @param verify true if the isValid and isDirectory flags should be verified during the construction.
* @param path String with the path the new node should point to.
* @param verify true if the isValid and isDirectory/isFile flags should
* be verified during the construction.
*/
POSIXFilesystemNode(const string& path, bool verify);
@ -64,6 +65,7 @@ class POSIXFilesystemNode : public AbstractFilesystemNode
const string& getPath() const { return _path; }
string getRelativePath() const;
bool isDirectory() const { return _isDirectory; }
bool isFile() const { return _isFile; }
bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
@ -74,11 +76,13 @@ class POSIXFilesystemNode : public AbstractFilesystemNode
string _displayName;
string _path;
bool _isDirectory;
bool _isFile;
bool _isValid;
private:
/**
* Tests and sets the _isValid and _isDirectory flags, using the stat() function.
* Tests and sets the _isValid and _isDirectory/_isFile flags,
* using the stat() function.
*/
virtual void setFlags();
};
@ -114,7 +118,13 @@ void POSIXFilesystemNode::setFlags()
struct stat st;
_isValid = (0 == stat(_path.c_str(), &st));
_isDirectory = _isValid ? S_ISDIR(st.st_mode) : false;
if(_isValid)
{
_isDirectory = S_ISDIR(st.st_mode);
_isFile = S_ISREG(st.st_mode);
}
else
_isDirectory = _isFile = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -125,6 +135,7 @@ POSIXFilesystemNode::POSIXFilesystemNode()
_displayName = _path;
_isValid = true;
_isDirectory = true;
_isFile = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -229,12 +240,18 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode,
{
struct stat st;
if (stat(entry._path.c_str(), &st) == 0)
{
entry._isDirectory = S_ISDIR(st.st_mode);
entry._isFile = S_ISREG(st.st_mode);
}
else
entry._isDirectory = false;
entry._isDirectory = entry._isFile = false;
}
else
{
entry._isDirectory = (dp->d_type == DT_DIR);
entry._isFile = (dp->d_type == DT_REG);
}
}
#endif
@ -244,7 +261,7 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode,
continue;
// Honor the chosen mode
if ((mode == FilesystemNode::kListFilesOnly && entry._isDirectory) ||
if ((mode == FilesystemNode::kListFilesOnly && !entry._isFile) ||
(mode == FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
continue;

View File

@ -97,6 +97,7 @@ class WindowsFilesystemNode : public AbstractFilesystemNode
const string& getPath() const { return _path; }
string getRelativePath() const;
bool isDirectory() const { return _isDirectory; }
bool isFile() const { return _isFile; }
bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; }
bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; }
@ -107,6 +108,7 @@ class WindowsFilesystemNode : public AbstractFilesystemNode
string _displayName;
string _path;
bool _isDirectory;
bool _isFile;
bool _isPseudoRoot;
bool _isValid;
@ -177,12 +179,14 @@ void WindowsFilesystemNode::addFile(AbstractFSList& list, ListMode mode,
return;
isDirectory = (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? true : false);
isFile = (find_data->dwFileAttributes & FILE_ATTRIBUTE_NORMAL ? true : false);
if ((!isDirectory && mode == FilesystemNode::kListDirectoriesOnly) ||
if ((isFile && mode == FilesystemNode::kListDirectoriesOnly) ||
(isDirectory && mode == FilesystemNode::kListFilesOnly))
return;
entry._isDirectory = isDirectory;
entry._isFile = isFile;
entry._displayName = asciiName;
entry._path = base;
entry._path += asciiName;
@ -221,19 +225,12 @@ const TCHAR* WindowsFilesystemNode::toUnicode(const char* str)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WindowsFilesystemNode::WindowsFilesystemNode()
{
_isDirectory = true;
#ifndef _WIN32_WCE
// Create a virtual root directory for standard Windows system
_isDirectory = true;
_isFile = false;
_isValid = false;
_path = "";
_isPseudoRoot = true;
#else
_displayName = "Root";
// No need to create a pseudo root directory on Windows CE
_isValid = true;
_path = "\\";
_isPseudoRoot = false;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -260,12 +257,12 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p)
if (fileAttribs == INVALID_FILE_ATTRIBUTES)
{
_isDirectory = false;
_isValid = false;
_isDirectory = _isFile = _isValid = false;
}
else
{
_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
_isFile = ((fileAttribs & FILE_ATTRIBUTE_NORMAL) != 0);
_isValid = true;
// Add a trailing backslash, if necessary
@ -301,7 +298,6 @@ bool WindowsFilesystemNode::
if (_isPseudoRoot)
{
#ifndef _WIN32_WCE
// Drives enumeration
TCHAR drive_buffer[100];
GetLogicalDriveStrings(sizeof(drive_buffer) / sizeof(TCHAR), drive_buffer);
@ -316,12 +312,12 @@ bool WindowsFilesystemNode::
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);
myList.push_back(new WindowsFilesystemNode(entry));
}
#endif
}
else
{
@ -365,6 +361,7 @@ AbstractFilesystemNode* WindowsFilesystemNode::getParent() const
p->_path = string(start, end - start);
p->_isValid = true;
p->_isDirectory = true;
p->_isFile = false;
p->_displayName = lastPathComponent(p->_path);
p->_isPseudoRoot = false;
}