diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 9f8e92e6b..6f48a81d6 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -42,28 +42,10 @@ FilesystemNode::FilesystemNode(const string& p) _realNode = Common::SharedPtr(tmp); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FilesystemNode::operator<(const FilesystemNode& node) const -{ - if (isDirectory() != node.isDirectory()) - return isDirectory(); - - return BSPF_strcasecmp(getDisplayName().c_str(), node.getDisplayName().c_str()) < 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FilesystemNode::operator==(const FilesystemNode& node) const -{ - return BSPF_strcasecmp(getDisplayName().c_str(), node.getDisplayName().c_str()) == 0; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::exists() const { - if (_realNode == 0) - return false; - - return _realNode->exists(); + return _realNode ? _realNode->exists() : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -84,13 +66,6 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, bool hidden) con return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const string& FilesystemNode::getDisplayName() const -{ - assert(_realNode); - return _realNode->getDisplayName(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const string& FilesystemNode::getName() const { @@ -101,10 +76,7 @@ const string& FilesystemNode::getName() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::hasParent() const { - if (_realNode == 0) - return false; - - return _realNode->getParent() != 0; + return _realNode ? (_realNode->getParent() != 0) : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -137,35 +109,35 @@ string FilesystemNode::getRelativePath() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::isDirectory() const { - if (_realNode == 0) - return false; - - return _realNode->isDirectory(); + return _realNode ? _realNode->isDirectory() : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::isFile() const { - if (_realNode == 0) - return false; - - return _realNode->isFile(); + return _realNode ? _realNode->isFile() : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::isReadable() const { - if (_realNode == 0) - return false; - - return _realNode->isReadable(); + return _realNode ? _realNode->isReadable() : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::isWritable() const { - if (_realNode == 0) - return false; - - return _realNode->isWritable(); + return _realNode ? _realNode->isWritable() : false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FilesystemNode::makeDir() +{ + return (_realNode && !_realNode->exists()) ? _realNode->makeDir() : false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FilesystemNode::rename(const string& newfile) +{ + return (_realNode && _realNode->exists()) ? _realNode->rename(newfile) : false; } diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index 37f6bfcc9..347c5894f 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -34,8 +34,6 @@ * paths (and it's left to them whether / or \ or : is the path separator :-); * but it is also possible to use inodes or vrefs (MacOS 9) or anything else. * - * NOTE: Backends still have to provide a way to extract a path from a FSIntern - * * You may ask now: "isn't this cheating? Why do we go through all this when we use * a path in the end anyway?!?". * Well, for once as long as we don't provide our own file open/read/write API, we @@ -48,12 +46,6 @@ * And if we ever want to support devices with no FS in the classical sense (Palm...), * we can build upon this. */ - -/* - * TODO - Instead of starting with getRoot(), we should rather add a getDefaultDir() - * call that on Unix might return the current dir or the users home dir... - * i.e. the root dir is usually not the best starting point for browsing. - */ #include "Array.hxx" #include "SharedPtr.hxx" @@ -69,29 +61,8 @@ class AbstractFilesystemNode; class FSList : public Common::Array { }; /** - * FilesystemNode provides an abstraction for file paths, allowing for portable - * file system browsing. To this ends, multiple or single roots have to be supported - * (compare Unix with a single root, Windows with multiple roots C:, D:, ...). - * - * To this end, we abstract away from paths; implementations can be based on - * paths (and it's left to them whether / or \ or : is the path separator :-); - * but it is also possible to use inodes or vrefs (MacOS 9) or anything else. - * - * NOTE: Backends still have to provide a way to extract a path from a FSIntern - * - * You may ask now: "isn't this cheating? Why do we go through all this when we use - * a path in the end anyway?!?". - * Well, for once as long as we don't provide our own file open/read/write API, we - * still have to use fopen(). Since all our targets already support fopen(), it should - * be possible to get a fopen() compatible string for any file system node. - * - * Secondly, with this abstraction layer, we still avoid a lot of complications based on - * differences in FS roots, different path separators, or even systems with no real - * paths (MacOS 9 doesn't even have the notion of a "current directory"). - * And if we ever want to support devices with no FS in the classical sense (Palm...), - * we can build upon this. - * - * This class acts as a wrapper around the AbstractFilesystemNode class defined in backends/fs. + * This class acts as a wrapper around the AbstractFilesystemNode class defined + * in backends/fs. */ class FilesystemNode { @@ -129,16 +100,26 @@ class FilesystemNode * Compare the name of this node to the name of another. Directories * go before normal files. */ - bool operator<(const FilesystemNode& node) const; + inline bool operator<(const FilesystemNode& node) const + { + if (isDirectory() != node.isDirectory()) + return isDirectory(); + + return BSPF_strcasecmp(getName().c_str(), node.getName().c_str()) < 0; + } /** * Compare the name of this node to the name of another, testing for - * equality + * equality, */ - bool operator==(const FilesystemNode& node) const; + inline bool operator==(const FilesystemNode& node) const + { + return BSPF_strcasecmp(getName().c_str(), node.getName().c_str()) == 0; + } /** - * Indicates whether the object referred by this path exists in the filesystem or not. + * Indicates whether the object referred by this path exists in the + * filesystem or not. * * @return bool true if the path exists, false otherwise. */ @@ -148,18 +129,11 @@ class FilesystemNode * Return a list of child nodes of this directory node. If called on a node * that does not represent a directory, false is returned. * - * @return true if successful, false otherwise (e.g. when the directory does not exist). + * @return true if successful, false otherwise (e.g. when the directory + * does not exist). */ - virtual bool getChildren(FSList &fslist, ListMode mode = kListDirectoriesOnly, bool hidden = false) const; - - /** - * Return a human readable string for this node, usable for display (e.g. - * in the GUI code). Do *not* rely on it being usable for anything else, - * like constructing paths! - * - * @return the display name - */ - virtual const string& getDisplayName() const; + virtual bool getChildren(FSList &fslist, ListMode mode = kListDirectoriesOnly, + bool hidden = false) const; /** * Return a string representation of the name of the file. This is can be @@ -235,7 +209,8 @@ class FilesystemNode * Indicates whether the object referred by this path can be written to or not. * * If the path refers to a directory, writability implies being able to modify - * the directory entry (i.e. rename the directory, remove it or write files inside of it). + * the directory entry (i.e. rename the directory, remove it or write files + * inside of it). * * If the path refers to a file, writability implies being able to write data * to the file. @@ -244,6 +219,20 @@ class FilesystemNode */ virtual bool isWritable() const; + /** + * Create a directory from the current node path. + * + * @return bool true if the directory was created, false otherwise. + */ + virtual bool makeDir(); + + /** + Rename the current node path with the new given name. + * + * @return bool true if the node was renamed, false otherwise. + */ + virtual bool rename(const string& newfile); + private: Common::SharedPtr _realNode; FilesystemNode(AbstractFilesystemNode* realNode); @@ -274,7 +263,8 @@ class AbstractFilesystemNode virtual ~AbstractFilesystemNode() {} /* - * Indicates whether the object referred by this path exists in the filesystem or not. + * Indicates whether the object referred by this path exists in the + * filesystem or not. */ virtual bool exists() const = 0; @@ -286,17 +276,11 @@ class AbstractFilesystemNode * @param mode Mode to use while listing the directory. * @param hidden Whether to include hidden files or not in the results. * - * @return true if succesful, false otherwise (e.g. when the directory does not exist). + * @return true if successful, false otherwise (e.g. when the directory + * does not exist). */ virtual bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const = 0; - /** - * Returns a human readable path string. - * - * @note By default, this method returns the value of getName(). - */ - virtual const string& getDisplayName() const { return getName(); } - /** * Returns the last component of the path pointed by this FilesystemNode. * @@ -304,7 +288,8 @@ class AbstractFilesystemNode * /foo/bar.txt would return /bar.txt * /foo/bar/ would return /bar/ * - * @note This method is very architecture dependent, please check the concrete implementation for more information. + * @note This method is very architecture dependent, please check the concrete + * implementation for more information. */ virtual const string& getName() const = 0; @@ -346,7 +331,8 @@ class AbstractFilesystemNode * Indicates whether the object referred by this path can be written to or not. * * If the path refers to a directory, writability implies being able to modify - * the directory entry (i.e. rename the directory, remove it or write files inside of it). + * the directory entry (i.e. rename the directory, remove it or write files + * inside of it). * * If the path refers to a file, writability implies being able to write data * to the file. @@ -356,14 +342,18 @@ class AbstractFilesystemNode virtual bool isWritable() const = 0; /** - Create a directory from the given path. + * Create a directory from the current node path. + * + * @return bool true if the directory was created, false otherwise. */ - static bool makeDir(const string& path); + virtual bool makeDir() = 0; /** - Rename the given file with a new name. + Rename the current node path with the new given name. + * + * @return bool true if the node was renamed, false otherwise. */ - static bool renameFile(const string& oldfile, const string& newfile); + virtual bool rename(const string& newfile) = 0; /** Create an absolute pathname from the given path (if it isn't already @@ -391,17 +381,6 @@ class AbstractFilesystemNode * @param path The path string to create a FilesystemNode for. */ static AbstractFilesystemNode* makeFileNodePath(const string& path); - - // TODO - the following method isn't actually used anywhere in - // the current code (2012-06-14) - /** - * Returns a special node representing the filesystem root. - * The starting point for any file system browsing. - * - * On Unix, this will be simply the node for / (the root directory). - * On Windows, it will be a special node which "contains" all drives (C:, D:, E:). - */ - static AbstractFilesystemNode* makeRootFileNode(); }; #endif diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 7a028a780..39912ce35 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -386,10 +386,7 @@ void OSystem::setBaseDir(const string& basedir) FilesystemNode node(basedir); myBaseDir = node.getPath(); if(!node.isDirectory()) - { - AbstractFilesystemNode::makeDir(myBaseDir); - myBaseDir = FilesystemNode(node.getPath()).getPath(); - } + node.makeDir(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -819,7 +816,7 @@ uInt8* OSystem::openROM(string file, string& md5, uInt32& size) { // Get the filename from the rom pathname FilesystemNode node(file); - file = node.getDisplayName(); + file = node.getName(); props.set(Cartridge_MD5, md5); props.set(Cartridge_Name, file); @@ -951,10 +948,7 @@ void OSystem::validatePath(string& path, const string& setting, mySettings->getString(setting); FilesystemNode node(s); if(!node.isDirectory()) - { - AbstractFilesystemNode::makeDir(s); - node = FilesystemNode(node.getPath()); - } + node.makeDir(); path = node.getPath(); mySettings->setString(setting, node.getRelativePath()); } diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx index ba479cabf..f478530d9 100644 --- a/src/gui/BrowserDialog.cxx +++ b/src/gui/BrowserDialog.cxx @@ -178,7 +178,7 @@ void BrowserDialog::updateListing() // Now add the directory entries for(unsigned int idx = 0; idx < content.size(); idx++) { - string name = content[idx].getDisplayName(); + string name = content[idx].getName(); bool isDir = content[idx].isDirectory(); if(isDir) name = " [" + name + "]"; diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 6888f8f2d..7a875cb22 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -401,18 +401,15 @@ void LauncherDialog::loadDirListing() bool domatch = myPattern && myPattern->getEditString() != ""; for(unsigned int idx = 0; idx < files.size(); idx++) { - string name = files[idx].getDisplayName(); bool isDir = files[idx].isDirectory(); + const string& name = isDir ? (" [" + files[idx].getName() + "]") + : files[idx].getName(); // Honour the filtering settings // Showing only certain ROM extensions is determined by the extension // that we want - if there are no extensions, it implies show all files // In this way, showing all files is on the 'fast code path' - if(isDir) - { - name = " [" + name + "]"; - } - else if(myRomExts.size() > 0) + if(!isDir && myRomExts.size() > 0) { // Skip over those names we've filtered out if(!LauncherFilterDialog::isValidRomName(name, myRomExts)) diff --git a/src/gui/LoggerDialog.cxx b/src/gui/LoggerDialog.cxx index aef818091..b70a3ce40 100644 --- a/src/gui/LoggerDialog.cxx +++ b/src/gui/LoggerDialog.cxx @@ -116,8 +116,9 @@ void LoggerDialog::saveConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void LoggerDialog::saveLogFile() { - string path = AbstractFilesystemNode::getAbsolutePath("stella", "~", "log"); - FilesystemNode node(path); + ostringstream path; + path << "~" << BSPF_PATH_SEPARATOR << "stella.log"; + FilesystemNode node(path.str()); ofstream out(node.getPath().c_str(), ios::out); if(out.is_open()) diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index bdc57e8a0..ac9272d05 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -152,13 +152,12 @@ void RomAuditDialog::auditRoms() const string& name = props.get(Cartridge_Name); // Only rename the file if we found a valid properties entry - if(name != "" && name != files[idx].getDisplayName()) + if(name != "" && name != files[idx].getName()) { const string& newfile = node.getPath() + name + "." + extension; - if(files[idx].getPath() != newfile) - if(AbstractFilesystemNode::renameFile(files[idx].getPath(), newfile)) - renamed++; + if(files[idx].getPath() != newfile && files[idx].rename(newfile)) + renamed++; } else notfound++; diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 99d3cd65e..90e38c0a0 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -38,6 +38,10 @@ #include +#ifndef MAXPATHLEN // No MAXPATHLEN, as happens on Hurd + #define MAXPATHLEN 1024 +#endif + /* * Implementation of the Stella file system API based on POSIX (for Linux and OSX) * @@ -58,10 +62,9 @@ class POSIXFilesystemNode : public AbstractFilesystemNode * @param verify true if the isValid and isDirectory/isFile flags should * be verified during the construction. */ - POSIXFilesystemNode(const string& path, bool verify); + POSIXFilesystemNode(const string& path, bool verify = true); bool exists() const { return access(_path.c_str(), F_OK) == 0; } - const string& getDisplayName() const { return _displayName; } const string& getName() const { return _displayName; } const string& getPath() const { return _path; } string getRelativePath() const; @@ -69,6 +72,8 @@ class POSIXFilesystemNode : public AbstractFilesystemNode 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; } + bool makeDir(); + bool rename(const string& newfile); bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; AbstractFilesystemNode* getParent() const; @@ -149,22 +154,14 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify) if(_path[0] == '~') { const char* home = getenv("HOME"); -#ifdef MAXPATHLEN if (home != NULL && strlen(home) < MAXPATHLEN) -#else // No MAXPATHLEN, as happens on Hurd - if (home != NULL) -#endif { _path.replace(0, 1, home); } } // Get absolute path -#ifdef MAXPATHLEN char buf[MAXPATHLEN]; -#else // No MAXPATHLEN, as happens on Hurd - char buf[1024]; -#endif if(realpath(_path.c_str(), buf)) _path = buf; @@ -283,6 +280,54 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool POSIXFilesystemNode::makeDir() +{ + if(mkdir(_path.c_str(), 0777) == 0) + { + // Get absolute path + char buf[MAXPATHLEN]; + if(realpath(_path.c_str(), buf)) + _path = buf; + + _displayName = lastPathComponent(_path); + setFlags(); + + // Add a trailing slash, if necessary + if (_path.length() > 0 && _path[_path.length()-1] != '/') + _path += '/'; + + return true; + } + else + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool POSIXFilesystemNode::rename(const string& newfile) +{ + if(std::rename(_path.c_str(), newfile.c_str()) == 0) + { + _path = newfile; + + // Get absolute path + char buf[MAXPATHLEN]; + if(realpath(_path.c_str(), buf)) + _path = buf; + + _displayName = lastPathComponent(_path); + setFlags(); + + // Add a trailing slash, if necessary + if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '/') + _path += '/'; + + return true; + } + else + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AbstractFilesystemNode* POSIXFilesystemNode::getParent() const { @@ -292,32 +337,13 @@ AbstractFilesystemNode* POSIXFilesystemNode::getParent() const const char *start = _path.c_str(); const char *end = lastPathComponent(_path); - return new POSIXFilesystemNode(string(start, end - start), true); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AbstractFilesystemNode* AbstractFilesystemNode::makeRootFileNode() -{ - return new POSIXFilesystemNode(); + return new POSIXFilesystemNode(string(start, end - start)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AbstractFilesystemNode* AbstractFilesystemNode::makeFileNodePath(const string& path) { - return new POSIXFilesystemNode(path, true); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool AbstractFilesystemNode::makeDir(const string& path) -{ - return mkdir(path.c_str(), 0777) == 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool AbstractFilesystemNode::renameFile(const string& oldfile, - const string& newfile) -{ - return rename(oldfile.c_str(), newfile.c_str()) == 0; + return new POSIXFilesystemNode(path); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/win32/FSNodeWin32.cxx b/src/win32/FSNodeWin32.cxx index 9d8871648..05640bd60 100644 --- a/src/win32/FSNodeWin32.cxx +++ b/src/win32/FSNodeWin32.cxx @@ -69,7 +69,8 @@ static HomeFinder myHomeFinder; /* * Implementation of the Stella file system API based on Windows API. * - * Parts of this class are documented in the base interface class, AbstractFilesystemNode. + * Parts of this class are documented in the base interface class, + * AbstractFilesystemNode. */ class WindowsFilesystemNode : public AbstractFilesystemNode { @@ -95,7 +96,6 @@ class WindowsFilesystemNode : public AbstractFilesystemNode WindowsFilesystemNode(const string& path); bool exists() const { return _access(_path.c_str(), F_OK) == 0; } - const string& getDisplayName() const { return _displayName; } const string& getName() const { return _displayName; } const string& getPath() const { return _path; } string getRelativePath() const; @@ -103,6 +103,8 @@ class WindowsFilesystemNode : public AbstractFilesystemNode 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; } + bool makeDir(); + bool rename(const string& newfile); bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; AbstractFilesystemNode* getParent() const; @@ -116,6 +118,12 @@ class WindowsFilesystemNode : public AbstractFilesystemNode bool _isValid; private: + /** + * Tests and sets the _isValid and _isDirectory/_isFile flags, + * using the GetFileAttributes() function. + */ + virtual void setFlags(); + /** * Adds a single WindowsFilesystemNode to a given list. * This method is used by getChildren() to populate the directory entries list. @@ -169,6 +177,36 @@ const char* lastPathComponent(const string& str) return cur + 1; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void WindowsFilesystemNode::setFlags() +{ + // Get absolute path + TCHAR buf[4096]; + if(GetFullPathName(_path.c_str(), 4096, buf, NULL)) + _path = buf; + + _displayName = lastPathComponent(_path); + + // Check whether it is a directory, and whether the file actually exists + DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str())); + + if (fileAttribs == INVALID_FILE_ATTRIBUTES) + { + _isDirectory = _isFile = _isValid = 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] != '\\') + _path += '\\'; + } + _isPseudoRoot = false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void WindowsFilesystemNode::addFile(AbstractFSList& list, ListMode mode, const char* base, WIN32_FIND_DATA* find_data) @@ -246,31 +284,7 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p) if(_path[0] == '~') _path.replace(0, 1, myHomeFinder.getHomePath()); - // Get absolute path - TCHAR buf[4096]; - if(GetFullPathName(_path.c_str(), 4096, buf, NULL)) - _path = buf; - - _displayName = lastPathComponent(_path); - - // Check whether it is a directory, and whether the file actually exists - DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str())); - - if (fileAttribs == INVALID_FILE_ATTRIBUTES) - { - _isDirectory = _isFile = _isValid = 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] != '\\') - _path += '\\'; - } - _isPseudoRoot = false; + setFlags(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -345,11 +359,33 @@ bool WindowsFilesystemNode:: return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool WindowsFilesystemNode::makeDir() +{ + if(!_isPseudoRoot && CreateDirectory(_path.c_str(), NULL) != 0) + { + setFlags(); + return true; + } + else + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool WindowsFilesystemNode::rename(const string& newfile) +{ + if(!_isPseudoRoot && MoveFile(_path.c_str(), newfile.c_str()) != 0) + { + setFlags(); + return true; + } + else + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AbstractFilesystemNode* WindowsFilesystemNode::getParent() const { -// assert(_isValid || _isPseudoRoot); - if (!_isValid || _isPseudoRoot) return 0; @@ -370,31 +406,12 @@ AbstractFilesystemNode* WindowsFilesystemNode::getParent() const return p; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AbstractFilesystemNode* AbstractFilesystemNode::makeRootFileNode() -{ - return new WindowsFilesystemNode(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AbstractFilesystemNode* AbstractFilesystemNode::makeFileNodePath(const string& path) { return new WindowsFilesystemNode(path); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool AbstractFilesystemNode::makeDir(const string& path) -{ - return CreateDirectory(path.c_str(), NULL) != 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool AbstractFilesystemNode::renameFile(const string& oldfile, - const string& newfile) -{ - return MoveFile(oldfile.c_str(), newfile.c_str()) != 0; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string AbstractFilesystemNode::getAbsolutePath(const string& p, const string& startpath,