123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _VOLUME_H_
- #define _VOLUME_H_
- #ifndef _TSIGNAL_H_
- #include "core/util/tSignal.h"
- #endif
- #ifndef _TVECTOR_H_
- #include "core/util/tVector.h"
- #endif
- #ifndef _REFBASE_H_
- #include "core/util/refBase.h"
- #endif
- #ifndef _TDICTIONARY_H_
- #include "core/util/tDictionary.h"
- #endif
- #ifndef _TORQUE_LIST_
- #include "core/util/tList.h"
- #endif
- #ifndef _PATH_H_
- #include "core/util/path.h"
- #endif
- #ifndef _TIMECLASS_H_
- #include "core/util/timeClass.h"
- #endif
- namespace Torque
- {
- namespace FS
- {
- ///@defgroup VolumeSystem Volume System
- /// Volume access.
- //-----------------------------------------------------------------------------
- /// Base class for all FileIO objects.
- /// @ingroup VolumeSystem
- class FileBase : public StrongRefBase
- {
- public:
- virtual ~FileBase() {}
- };
- //-----------------------------------------------------------------------------
- /// Base class for objects in a FileSystem.
- /// This class provides the functionality required by all file system
- /// files, which is basically name and attributes.
- /// @ingroup VolumeSystem
- class FileNode : public FileBase
- {
- public:
- enum NodeStatus
- {
- Open, ///< In an open state
- Closed, ///< In a closed state
- EndOfFile, ///< End of file reached
- UnknownError, ///< An undetermined error has occurred
- FileSystemFull, ///< File system full
- NoSuchFile, ///< File or path does not exist
- AccessDenied, ///< File access denied
- IllegalCall, ///< An unsupported operation was used.
- SharingViolation, ///< File being used by another process
- NoDisk, ///< No disk or dvd in drive
- DriveOpen, ///< Disk or DVD drive open
- WrongDisk, ///< Disk or DVD has been swapped
- };
- enum Mode
- {
- File = 1 << 0, ///< Normal file
- Directory = 1 << 1, ///< Directory
- System = 1 << 2, ///< OS specific system file
- Hidden = 1 << 3, ///< Hidden file or directory
- ReadOnly = 1 << 4, ///< Read only
- Compressed = 1 << 5, ///< Part of a compressed archive?
- Encrypted = 1 << 6, ///< Part of an encrypted archive?
- Library = 1 << 7, ///< Dynamic Library
- Executable = 1 << 8, ///< Executable file
- };
- struct Attributes
- {
- U32 flags; ///< File/Directory modes
- String name; ///< File/Directory name
- Time mtime; ///< Last modified time
- Time atime; ///< Last access time
- Time ctime; ///< Creation Time
- U64 size;
- };
- public:
- FileNode();
- // Properties
- virtual Path getName() const = 0;
- virtual NodeStatus getStatus() const = 0;
- virtual bool getAttributes(Attributes*) = 0;
- // Convenience routines - may be overridden for optimal access
- virtual Time getModifiedTime(); ///< @note This will return Time() on failure
- virtual Time getCreatedTime(); ///< @note This will return Time() on failure
- virtual U64 getSize(); ///< @note This will return 0 on failure
- virtual U32 getChecksum(); ///< @note This will return 0 on failure
- protected:
- virtual U32 calculateChecksum() = 0; ///< return 0 on failure
- private:
- U32 mChecksum;
- Torque::Time mLastChecksum;
- };
- typedef WeakRefPtr<FileNode> FileNodePtr;
- typedef StrongRefPtr<FileNode> FileNodeRef;
- //-----------------------------------------------------------------------------
- /// File object in a FileSystem.
- /// File object in a FileSystem. When a file is initially obtained from a
- /// FileSystem it is in a closed state.
- /// @ingroup VolumeSystem
- class File : public FileNode
- {
- public:
- enum AccessMode
- {
- Read = 0, ///< Open for read only.
- Write = 1, ///< Open for write only.
- ReadWrite = 2, ///< Open for read-write.
- WriteAppend = 3 ///< Write-only, starting at end of file.
- };
- enum SeekMode
- {
- Begin, ///< Relative to the start of the file
- Current, ///< Relative to the current position
- End, ///< Relative to the end of the file
- };
- File();
- virtual ~File();
- // Properties
- virtual U32 getPosition() = 0;
- virtual U32 setPosition(U32 pos, SeekMode mode) = 0;
- // Functions
- virtual bool open(AccessMode mode) = 0;
- virtual bool close() = 0;
- virtual U32 read(void* dst, U32 size) = 0;
- virtual U32 write(const void* src, U32 size) = 0;
- };
- typedef WeakRefPtr<File> FilePtr;
- typedef StrongRefPtr<File> FileRef;
- //-----------------------------------------------------------------------------
- /// Directory in a FileSystem.
- /// Directory object in a FileSystem. When a directory is initially obtained from a
- /// FileSystem it is in a closed state.
- /// @ingroup VolumeSystem
- class Directory : public FileNode
- {
- public:
- Directory();
- virtual ~Directory();
- // Functions
- virtual bool open() = 0;
- virtual bool close() = 0;
- virtual bool read(Attributes*) = 0;
- bool dump(Vector<Path>& out);
- bool dumpFiles(Vector<Path>& out);
- bool dumpDirectories(Vector<Path>& out);
- };
- typedef WeakRefPtr<Directory> DirectoryPtr;
- typedef StrongRefPtr<Directory> DirectoryRef;
- //-----------------------------------------------------------------------------
- class FileSystem;
- class FileSystemChangeNotifier
- {
- public:
- typedef Delegate<void(const Path &)> ChangeDelegate;
- typedef Signal<void(const Path &)> ChangeSignal;
- public:
- FileSystemChangeNotifier( FileSystem *fs )
- : mFS( fs ),
- mNotifying( false )
- {
- }
- virtual ~FileSystemChangeNotifier() {}
- /// Adds a file change notification.
- /// @see FS::AddChangeNotification
- virtual bool addNotification( const Path &path, ChangeDelegate callback );
- /// Removes an existing file change notification.
- /// @see FS::RemoveChangeNotification
- virtual bool removeNotification( const Path &path, ChangeDelegate callback );
- void startNotifier();
- void stopNotifier();
- /// Returns true if the notifier is enabled and file
- /// change notifications will be sent.
- bool isNotifying() const { return mNotifying; }
- protected:
- struct FileInfo
- {
- /// The full path to the file.
- Path filePath;
- /// The last known modification time.
- Time savedLastModTime;
- /// The notifications and reference count.
- ChangeSignal signal;
- };
- typedef List<FileInfo> FileInfoList;
- typedef Map<Path, FileInfoList> DirMap; ///< map a directory to a list of files and their mod times
- void process();
- virtual void internalProcessOnce() = 0;
- /// This is called so the inherited class can do its own bookkeeping on addNotification()
- /// @note We pass the directory here, not the file
- virtual bool internalAddNotification( const Path &dir ) = 0;
- /// This is called so the inherited class can do its own bookkeeping on removeNotification()
- /// @note We pass the directory here, not the file
- virtual bool internalRemoveNotification( const Path &dir ) = 0;
- /// Called by the inherited class to let us know a directory has changed
- /// so we can find the file which changed and notify on it
- void internalNotifyDirChanged( const Path &dir );
- /// Makes sure paths going in and out of the notifier will have the same format
- String cleanPath(const Path& dir);
- FileSystem *mFS;
- DirMap mDirMap;
- bool mNotifying;
- };
- //-----------------------------------------------------------------------------
- /// Collection of FileNode objects.
- /// File systems represent collections of FileNode objects. Functions are
- /// provided for manipulating FileNode objects but the internal organization
- /// and representation is opaque.
- /// Path names must be fully specified relative to the file system root and
- /// names cannot contain relative path information.
- /// @ingroup VolumeSystem
- class FileSystem : public FileBase
- {
- public:
- FileSystem();
- virtual ~FileSystem();
- virtual String getTypeStr() const = 0; ///< Used for describing the file system type
- virtual FileNodeRef resolve(const Path& path) = 0;
- virtual FileNodeRef resolveLoose(const Path& path) { return resolve(path); }
- virtual FileNodeRef create(const Path& path,FileNode::Mode) = 0;
- virtual bool remove(const Path& path) = 0;
- virtual bool rename(const Path& a,const Path& b) = 0;
- virtual Path mapTo(const Path& path) = 0;
- virtual Path mapFrom(const Path& path) = 0;
- /// Returns the file change notifier.
- /// @see FS::AddChangeNotification
- /// @see FS::RemoveChangeNotification
- FileSystemChangeNotifier *getChangeNotifier() { return mChangeNotifier; }
- bool isReadOnly() { return mReadOnly; }
- protected:
- FileSystemChangeNotifier *mChangeNotifier;
- bool mReadOnly;
- };
- typedef WeakRefPtr<FileSystem> FileSystemPtr;
- typedef StrongRefPtr<FileSystem> FileSystemRef;
- //-----------------------------------------------------------------------------
- ///@name File System Access
- /// A collection of file systems.
- /// @ingroup VolumeSystem
- class MountSystem
- {
- public:
- virtual ~MountSystem() {}
- FileRef createFile(const Path& path);
- bool copyFile(const Path& source, const Path& destination, bool noOverwrite);
- bool dumpDirectories(const Path& path, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath);
- DirectoryRef createDirectory(const Path& path, FileSystemRef fs = NULL);
- virtual bool createPath(const Path& path);
- FileRef openFile(const Path& path,File::AccessMode mode);
- DirectoryRef openDirectory(const Path& path);
- bool remove(const Path& path);
- bool rename(const Path& from,const Path& to);
- virtual bool mount(String root, FileSystemRef fs);
- virtual bool mount(String root, const Path &path);
- virtual FileSystemRef unmount(String root);
- virtual bool unmount(FileSystemRef fs);
- bool setCwd(const Path& file);
- const Path &getCwd() const;
- FileSystemRef getFileSystem(const Path& path);
- bool getFileAttributes(const Path& path,FileNode::Attributes* attr);
- FileNodeRef getFileNode(const Path& path);
- bool mapFSPath( const String &inRoot, const Path &inPath, Path &outPath );
- virtual S32 findByPattern( const Path &inBasePath, const String &inFilePattern, bool inRecursive, Vector<String> &outList, bool includeDirs=false, bool multiMatch = true );
- bool isFile(const Path &path);
- bool isDirectory(const Path &path, FileSystemRef fsRef = NULL);
- bool isReadOnly(const Path &path);
- S32 getNumMounts() const { return mMountList.size(); }
- String getMountRoot( S32 index ) const { return mMountList[index].root; }
- String getMountPath( S32 index ) const { return mMountList[index].fileSystem->mapTo(mMountList[index].path); }
- String getMountType( S32 index ) const { return mMountList[index].fileSystem->getTypeStr(); }
- // File system notifications
- void startFileChangeNotifications();
- void stopFileChangeNotifications();
- private:
- bool _dumpDirectories(DirectoryRef directory, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath, S32 currentDepth, const Path& basePath);
- protected:
- virtual void _log(const String& msg);
- protected:
- struct MountFS
- {
- String root; // Root for file system
- String path; // File system path
- FileSystemRef fileSystem;
- };
-
- virtual FileSystemRef _removeMountFromList(String root);
- virtual FileSystemRef _getFileSystemFromList(const Path& path) const ;
- void _setFindByPatternOverrideFS(FileSystemRef fs) { mFindByPatternOverrideFS = fs; }
- Path _normalize(const Path& path);
- Vector<MountFS> mMountList;
- Path mCWD;
- FileSystemRef mFindByPatternOverrideFS;
- };
- ///@name File System Access
- /// Functions for mounting file systems and dealing with files and directories.
- /// The kernel provides FileSystem mounting, the concept of a current working
- /// directory as well as relative paths.
- ///@{
- /// Mount file system
- ///@ingroup VolumeSystem
- bool Mount(String root, FileSystemRef fs);
- /// Mount file system redirect
- ///@ingroup VolumeSystem
- bool Mount(String root, const Path &path);
- /// Remove mounted file system.
- /// The file system object associated with the given root is unmounted.
- /// Open files associated with this file system are unaffected.
- ///@return The unmounted file system.
- ///@ingroup VolumeSystem
- FileSystemRef Unmount(String root);
- /// Remove mounted file system.
- /// Open files associated with this file system are unaffected.
- ///@return true if the filesystem was successfully unmounted, false otherwise (most likely, the FS was not mounted)
- bool Unmount(FileSystemRef fs);
- /// Find the the file system which owns the given file.
- ///@ingroup VolumeSystem
- FileSystemRef GetFileSystem(const Path &file);
- /// Find the file system node for the given file.
- ///@return Null if the file doesn't exist
- ///@ingroup VolumeSystem
- FileNodeRef GetFileNode(const Path &path);
- /// Adds a file change notification callback.
- ///@ingroup VolumeSystem
- template <class T,class U>
- inline bool AddChangeNotification( const Path &path, T obj, U func )
- {
- FileSystemRef fs = GetFileSystem( path );
- if ( !fs || !fs->getChangeNotifier() )
- return false;
- FileSystemChangeNotifier::ChangeDelegate dlg( obj, func );
- return fs->getChangeNotifier()->addNotification( path, dlg );
- }
- /// Removes an existing file change notification callback.
- ///@ingroup VolumeSystem
- template <class T,class U>
- inline bool RemoveChangeNotification( const Path &path, T obj, U func )
- {
- FileSystemRef fs = GetFileSystem( path );
- if ( !fs || !fs->getChangeNotifier() )
- return false;
- FileSystemChangeNotifier::ChangeDelegate dlg( obj, func );
- return fs->getChangeNotifier()->removeNotification( path, dlg );
- }
- /// Map a real file system path to a virtual one based on a root.
- /// This is useful when we get a real path back from an OS file dialog for example.
- /// e.g. If we have a root "gumby" which points at "C:/foo/bar",
- /// MapFSPath("gumby", "C:/foo/bar/blat/picture.png", path );
- /// will map "C:/foo/bar/blat/picture.png" to "gumby:/blat/picture.png"
- ///@param inRoot The root to check
- ///@param inPath The real file system path
- ///@param outPath The resulting volume system path
- ///@return Success or failure
- bool MapFSPath( const String &inRoot, const Path &inPath, Path &outPath );
- /// Returns a true file system path without virtual mounts.
- ///
- ///@param inPath The path to convert.
- ///@param outPath The resulting real file system path.
- ///
- bool GetFSPath( const Path &inPath, Path &outPath );
- /// Find files matching a pattern starting in a given dir.
- ///@param inBasePath path to start in
- ///@param inFilePattern the file pattern [it uses the FindMatch class]
- ///@param inRecursive do we search recursively?
- ///@param outList the list of files as Strings [Paths are more expensive to compute, so these may be converted on demand]
- ///@param multiMatch match against multiple file patterns given in inFilePattern?
- ///@return number of files which matched
- ///@ingroup VolumeSystem
- S32 FindByPattern( const Path &inBasePath, const String &inFilePattern, bool inRecursive, Vector<String> &outList, bool multiMatch = false );
- /// Set current working directory.
- ///@ingroup VolumeSystem
- bool SetCwd(const Path &file);
- /// Get the current working directory.
- ///@ingroup VolumeSystem
- const Path& GetCwd();
- /// Remove (or delete) a file from the file system.
- ///@ingroup VolumeSystem
- bool Remove(const Path &file);
- /// Rename a file or directory.
- ///@ingroup VolumeSystem
- bool Rename(const Path &from, const Path &to);
- /// Get the file attributes.
- /// @return success
- ///@ingroup VolumeSystem
- bool GetFileAttributes(const Path &path, FileNode::Attributes *attr);
- /// Compare modified times of p1 & p2
- /// @return -1 if p1 < p2, 0 if p1 == p2, 1 if p1 > p2
- S32 CompareModifiedTimes(const Path& p1, const Path& p2);
- /// Open a file.
- /// If the file exists a file object will be returned even if the
- /// open operation fails.
- ///@return Null if the file does not exist
- ///@ingroup VolumeSystem
- FileRef OpenFile(const Path &file, File::AccessMode mode);
- /// Read in an entire file
- /// @note Caller is responsible for freeing memory
- ///@param inPath the file
- ///@param outData the pointer to return the data
- ///@param outSize the size of the data returned
- ///@param inNullTerminate add an extra '\0' byte to the return buffer
- ///@return successful read? If not, outData will be NULL and outSize will be 0
- bool ReadFile(const Path &inPath, void *&outData, U32 &outSize, bool inNullTerminate = false );
- /// Open a directory.
- /// If the directory exists a directory object will be returned even if the
- /// open operation fails.
- ///@return Null if the file does not exist
- ///@ingroup VolumeSystem
- DirectoryRef OpenDirectory(const Path &file);
- /// Create a file.
- /// The file object is returned in a closed state.
- ///@ingroup VolumeSystem
- FileRef CreateFile(const Path &file);
- /// Copy a file from one location to another.
- bool CopyFile(const Path& source, const Path& destination, bool noOverride);
- /// Retrieve list of directories in the specified directory.
- bool DumpDirectories(const Path& path, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath);
- /// Create a directory.
- /// The directory object is returned in a closed state.
- ///@ingroup VolumeSystem
- DirectoryRef CreateDirectory(const Path &file);
- /// Create all the directories in the path if they don't already exist
- ///@ingroup VolumeSystem
- bool CreatePath(const Path &path);
- bool IsReadOnly(const Path &path);
- bool IsDirectory(const Path &path);
- bool IsFile(const Path &path);
- bool IsScriptFile(const char* pFilePath);
- bool VerifyWriteAccess(const Path &path);
- /// This returns a unique file path from the components
- /// by appending numbers to the end of the file name if
- /// a file with the same name already exists.
- ///
- /// @param path The root and directory for the file.
- /// @param fileName The file name without extension.
- /// @param ext The dot-less extension.
- String MakeUniquePath( const char *path, const char *fileName, const char *ext );
- void StartFileChangeNotifications();
- void StopFileChangeNotifications();
- S32 GetNumMounts();
- String GetMountRoot( S32 index );
- String GetMountPath( S32 index );
- String GetMountType( S32 index );
- ///@}
- } // Namespace FS
- } // Namespace Torque
- #endif
|