volume.h
Classes:
class
class
File object in a FileSystem.
class
Base class for all FileIO objects.
class
Base class for objects in a FileSystem.
class
Collection of FileNode objects.
Namespaces:
namespace
namespace
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _VOLUME_H_ 25#define _VOLUME_H_ 26 27#ifndef _TSIGNAL_H_ 28#include "core/util/tSignal.h" 29#endif 30 31#ifndef _TVECTOR_H_ 32#include "core/util/tVector.h" 33#endif 34 35#ifndef _REFBASE_H_ 36#include "core/util/refBase.h" 37#endif 38 39#ifndef _TDICTIONARY_H_ 40#include "core/util/tDictionary.h" 41#endif 42 43#ifndef _TORQUE_LIST_ 44#include "core/util/tList.h" 45#endif 46 47#ifndef _PATH_H_ 48#include "core/util/path.h" 49#endif 50 51#ifndef _TIMECLASS_H_ 52#include "core/util/timeClass.h" 53#endif 54 55namespace Torque 56{ 57namespace FS 58{ 59 60///@defgroup VolumeSystem Volume System 61/// Volume access. 62 63//----------------------------------------------------------------------------- 64 65/// Base class for all FileIO objects. 66/// @ingroup VolumeSystem 67class FileBase : public StrongRefBase 68{ 69public: 70 virtual ~FileBase() {} 71}; 72 73 74//----------------------------------------------------------------------------- 75 76/// Base class for objects in a FileSystem. 77/// This class provides the functionality required by all file system 78/// files, which is basically name and attributes. 79/// @ingroup VolumeSystem 80class FileNode : public FileBase 81{ 82public: 83 enum NodeStatus 84 { 85 Open, ///< In an open state 86 Closed, ///< In a closed state 87 EndOfFile, ///< End of file reached 88 UnknownError, ///< An undetermined error has occurred 89 FileSystemFull, ///< File system full 90 NoSuchFile, ///< File or path does not exist 91 AccessDenied, ///< File access denied 92 IllegalCall, ///< An unsupported operation was used. 93 SharingViolation, ///< File being used by another process 94 NoDisk, ///< No disk or dvd in drive 95 DriveOpen, ///< Disk or DVD drive open 96 WrongDisk, ///< Disk or DVD has been swapped 97 }; 98 99 enum Mode 100 { 101 File = 1 << 0, ///< Normal file 102 Directory = 1 << 1, ///< Directory 103 System = 1 << 2, ///< OS specific system file 104 Hidden = 1 << 3, ///< Hidden file or directory 105 ReadOnly = 1 << 4, ///< Read only 106 Compressed = 1 << 5, ///< Part of a compressed archive? 107 Encrypted = 1 << 6, ///< Part of an encrypted archive? 108 Library = 1 << 7, ///< Dynamic Library 109 Executable = 1 << 8, ///< Executable file 110 }; 111 112 struct Attributes 113 { 114 U32 flags; ///< File/Directory modes 115 String name; ///< File/Directory name 116 Time mtime; ///< Last modified time 117 Time atime; ///< Last access time 118 U64 size; 119 }; 120 121public: 122 FileNode(); 123 124 // Properties 125 virtual Path getName() const = 0; 126 virtual NodeStatus getStatus() const = 0; 127 128 virtual bool getAttributes(Attributes*) = 0; 129 130 // Convenience routines - may be overridden for optimal access 131 virtual Time getModifiedTime(); ///< @note This will return Time() on failure 132 virtual U64 getSize(); ///< @note This will return 0 on failure 133 virtual U32 getChecksum(); ///< @note This will return 0 on failure 134 135protected: 136 virtual U32 calculateChecksum() = 0; ///< return 0 on failure 137 138private: 139 U32 mChecksum; 140 Torque::Time mLastChecksum; 141}; 142 143typedef WeakRefPtr<FileNode> FileNodePtr; 144typedef StrongRefPtr<FileNode> FileNodeRef; 145 146 147//----------------------------------------------------------------------------- 148 149/// File object in a FileSystem. 150/// File object in a FileSystem. When a file is initially obtained from a 151/// FileSystem it is in a closed state. 152/// @ingroup VolumeSystem 153class File : public FileNode 154{ 155public: 156 enum AccessMode 157 { 158 Read = 0, ///< Open for read only. 159 Write = 1, ///< Open for write only. 160 ReadWrite = 2, ///< Open for read-write. 161 WriteAppend = 3 ///< Write-only, starting at end of file. 162 }; 163 164 enum SeekMode 165 { 166 Begin, ///< Relative to the start of the file 167 Current, ///< Relative to the current position 168 End, ///< Relative to the end of the file 169 }; 170 171 File(); 172 virtual ~File(); 173 174 // Properties 175 virtual U32 getPosition() = 0; 176 virtual U32 setPosition(U32 pos, SeekMode mode) = 0; 177 178 // Functions 179 virtual bool open(AccessMode mode) = 0; 180 virtual bool close() = 0; 181 182 virtual U32 read(void* dst, U32 size) = 0; 183 virtual U32 write(const void* src, U32 size) = 0; 184}; 185 186typedef WeakRefPtr<File> FilePtr; 187typedef StrongRefPtr<File> FileRef; 188 189 190//----------------------------------------------------------------------------- 191 192/// Directory in a FileSystem. 193/// Directory object in a FileSystem. When a directory is initially obtained from a 194/// FileSystem it is in a closed state. 195/// @ingroup VolumeSystem 196class Directory : public FileNode 197{ 198public: 199 Directory(); 200 virtual ~Directory(); 201 202 // Functions 203 virtual bool open() = 0; 204 virtual bool close() = 0; 205 virtual bool read(Attributes*) = 0; 206}; 207 208typedef WeakRefPtr<Directory> DirectoryPtr; 209typedef StrongRefPtr<Directory> DirectoryRef; 210 211 212//----------------------------------------------------------------------------- 213 214class FileSystem; 215 216class FileSystemChangeNotifier 217{ 218public: 219 typedef Delegate<void(const Path &)> ChangeDelegate; 220 typedef Signal<void(const Path &)> ChangeSignal; 221 222public: 223 FileSystemChangeNotifier( FileSystem *fs ) 224 : mFS( fs ), 225 mNotifying( false ) 226 { 227 } 228 229 virtual ~FileSystemChangeNotifier() {} 230 231 /// Adds a file change notification. 232 /// @see FS::AddChangeNotification 233 virtual bool addNotification( const Path &path, ChangeDelegate callback ); 234 235 /// Removes an existing file change notification. 236 /// @see FS::RemoveChangeNotification 237 virtual bool removeNotification( const Path &path, ChangeDelegate callback ); 238 239 void startNotifier(); 240 void stopNotifier(); 241 242 /// Returns true if the notifier is enabled and file 243 /// change notifications will be sent. 244 bool isNotifying() const { return mNotifying; } 245 246protected: 247 struct FileInfo 248 { 249 /// The full path to the file. 250 Path filePath; 251 252 /// The last known modification time. 253 Time savedLastModTime; 254 255 /// The notifications and reference count. 256 ChangeSignal signal; 257 }; 258 259 typedef List<FileInfo> FileInfoList; 260 typedef Map<Path, FileInfoList> DirMap; ///< map a directory to a list of files and their mod times 261 262 void process(); 263 264 virtual void internalProcessOnce() = 0; 265 266 /// This is called so the inherited class can do its own bookkeeping on addNotification() 267 /// @note We pass the directory here, not the file 268 virtual bool internalAddNotification( const Path &dir ) = 0; 269 270 /// This is called so the inherited class can do its own bookkeeping on removeNotification() 271 /// @note We pass the directory here, not the file 272 virtual bool internalRemoveNotification( const Path &dir ) = 0; 273 274 /// Called by the inherited class to let us know a directory has changed 275 /// so we can find the file which changed and notify on it 276 void internalNotifyDirChanged( const Path &dir ); 277 278 /// Makes sure paths going in and out of the notifier will have the same format 279 String cleanPath(const Path& dir); 280 281 FileSystem *mFS; 282 283 DirMap mDirMap; 284 285 bool mNotifying; 286}; 287 288//----------------------------------------------------------------------------- 289 290/// Collection of FileNode objects. 291/// File systems represent collections of FileNode objects. Functions are 292/// provided for manipulating FileNode objects but the internal organization 293/// and representation is opaque. 294/// Path names must be fully specified relative to the file system root and 295/// names cannot contain relative path information. 296/// @ingroup VolumeSystem 297class FileSystem : public FileBase 298{ 299public: 300 FileSystem(); 301 virtual ~FileSystem(); 302 303 virtual String getTypeStr() const = 0; ///< Used for describing the file system type 304 305 virtual FileNodeRef resolve(const Path& path) = 0; 306 virtual FileNodeRef create(const Path& path,FileNode::Mode) = 0; 307 virtual bool remove(const Path& path) = 0; 308 virtual bool rename(const Path& a,const Path& b) = 0; 309 virtual Path mapTo(const Path& path) = 0; 310 virtual Path mapFrom(const Path& path) = 0; 311 312 /// Returns the file change notifier. 313 /// @see FS::AddChangeNotification 314 /// @see FS::RemoveChangeNotification 315 FileSystemChangeNotifier *getChangeNotifier() { return mChangeNotifier; } 316 317 bool isReadOnly() { return mReadOnly; } 318 319protected: 320 FileSystemChangeNotifier *mChangeNotifier; 321 bool mReadOnly; 322}; 323 324typedef WeakRefPtr<FileSystem> FileSystemPtr; 325typedef StrongRefPtr<FileSystem> FileSystemRef; 326 327 328//----------------------------------------------------------------------------- 329///@name File System Access 330/// A collection of file systems. 331/// @ingroup VolumeSystem 332class MountSystem 333{ 334public: 335 virtual ~MountSystem() {} 336 337 FileRef createFile(const Path& path); 338 DirectoryRef createDirectory(const Path& path, FileSystemRef fs = NULL); 339 virtual bool createPath(const Path& path); 340 341 FileRef openFile(const Path& path,File::AccessMode mode); 342 DirectoryRef openDirectory(const Path& path); 343 344 bool remove(const Path& path); 345 346 bool rename(const Path& from,const Path& to); 347 348 virtual bool mount(String root, FileSystemRef fs); 349 virtual bool mount(String root, const Path &path); 350 virtual FileSystemRef unmount(String root); 351 virtual bool unmount(FileSystemRef fs); 352 353 bool setCwd(const Path& file); 354 const Path &getCwd() const; 355 356 FileSystemRef getFileSystem(const Path& path); 357 bool getFileAttributes(const Path& path,FileNode::Attributes* attr); 358 FileNodeRef getFileNode(const Path& path); 359 360 bool mapFSPath( const String &inRoot, const Path &inPath, Path &outPath ); 361 362 virtual S32 findByPattern( const Path &inBasePath, const String &inFilePattern, bool inRecursive, Vector<String> &outList, bool includeDirs=false, bool multiMatch = true ); 363 364 bool isFile(const Path &path); 365 bool isDirectory(const Path &path, FileSystemRef fsRef = NULL); 366 bool isReadOnly(const Path &path); 367 368 S32 getNumMounts() const { return mMountList.size(); } 369 String getMountRoot( S32 index ) const { return mMountList[index].root; } 370 String getMountPath( S32 index ) const { return mMountList[index].fileSystem->mapTo(mMountList[index].path); } 371 String getMountType( S32 index ) const { return mMountList[index].fileSystem->getTypeStr(); } 372 373 // File system notifications 374 void startFileChangeNotifications(); 375 void stopFileChangeNotifications(); 376 377protected: 378 virtual void _log(const String& msg); 379 380protected: 381 struct MountFS 382 { 383 String root; // Root for file system 384 String path; // File system path 385 FileSystemRef fileSystem; 386 }; 387 388 virtual FileSystemRef _removeMountFromList(String root); 389 virtual FileSystemRef _getFileSystemFromList(const Path& path) const ; 390 void _setFindByPatternOverrideFS(FileSystemRef fs) { mFindByPatternOverrideFS = fs; } 391 392 Path _normalize(const Path& path); 393 394 Vector<MountFS> mMountList; 395 Path mCWD; 396 FileSystemRef mFindByPatternOverrideFS; 397}; 398 399///@name File System Access 400/// Functions for mounting file systems and dealing with files and directories. 401/// The kernel provides FileSystem mounting, the concept of a current working 402/// directory as well as relative paths. 403///@{ 404 405/// Mount file system 406///@ingroup VolumeSystem 407bool Mount(String root, FileSystemRef fs); 408 409/// Mount file system redirect 410///@ingroup VolumeSystem 411bool Mount(String root, const Path &path); 412 413/// Remove mounted file system. 414/// The file system object associated with the given root is unmounted. 415/// Open files associated with this file system are unaffected. 416///@return The unmounted file system. 417///@ingroup VolumeSystem 418FileSystemRef Unmount(String root); 419 420/// Remove mounted file system. 421/// Open files associated with this file system are unaffected. 422///@return true if the filesystem was successfully unmounted, false otherwise (most likely, the FS was not mounted) 423bool Unmount(FileSystemRef fs); 424 425/// Find the the file system which owns the given file. 426///@ingroup VolumeSystem 427FileSystemRef GetFileSystem(const Path &file); 428 429/// Find the file system node for the given file. 430///@return Null if the file doesn't exist 431///@ingroup VolumeSystem 432FileNodeRef GetFileNode(const Path &path); 433 434/// Adds a file change notification callback. 435///@ingroup VolumeSystem 436template <class T,class U> 437inline bool AddChangeNotification( const Path &path, T obj, U func ) 438{ 439 FileSystemRef fs = GetFileSystem( path ); 440 if ( !fs || !fs->getChangeNotifier() ) 441 return false; 442 443 FileSystemChangeNotifier::ChangeDelegate dlg( obj, func ); 444 return fs->getChangeNotifier()->addNotification( path, dlg ); 445} 446 447/// Removes an existing file change notification callback. 448///@ingroup VolumeSystem 449template <class T,class U> 450inline bool RemoveChangeNotification( const Path &path, T obj, U func ) 451{ 452 FileSystemRef fs = GetFileSystem( path ); 453 if ( !fs || !fs->getChangeNotifier() ) 454 return false; 455 456 FileSystemChangeNotifier::ChangeDelegate dlg( obj, func ); 457 return fs->getChangeNotifier()->removeNotification( path, dlg ); 458} 459 460/// Map a real file system path to a virtual one based on a root. 461/// This is useful when we get a real path back from an OS file dialog for example. 462/// e.g. If we have a root "gumby" which points at "C:/foo/bar", 463/// MapFSPath("gumby", "C:/foo/bar/blat/picture.png", path ); 464/// will map "C:/foo/bar/blat/picture.png" to "gumby:/blat/picture.png" 465///@param inRoot The root to check 466///@param inPath The real file system path 467///@param outPath The resulting volume system path 468///@return Success or failure 469bool MapFSPath( const String &inRoot, const Path &inPath, Path &outPath ); 470 471/// Returns a true file system path without virtual mounts. 472/// 473///@param inPath The path to convert. 474///@param outPath The resulting real file system path. 475/// 476bool GetFSPath( const Path &inPath, Path &outPath ); 477 478/// Find files matching a pattern starting in a given dir. 479///@param inBasePath path to start in 480///@param inFilePattern the file pattern [it uses the FindMatch class] 481///@param inRecursive do we search recursively? 482///@param outList the list of files as Strings [Paths are more expensive to compute, so these may be converted on demand] 483///@param multiMatch match against multiple file patterns given in inFilePattern? 484///@return number of files which matched 485///@ingroup VolumeSystem 486S32 FindByPattern( const Path &inBasePath, const String &inFilePattern, bool inRecursive, Vector<String> &outList, bool multiMatch = false ); 487 488/// Set current working directory. 489///@ingroup VolumeSystem 490bool SetCwd(const Path &file); 491 492/// Get the current working directory. 493///@ingroup VolumeSystem 494const Path& GetCwd(); 495 496/// Remove (or delete) a file from the file system. 497///@ingroup VolumeSystem 498bool Remove(const Path &file); 499 500/// Rename a file or directory. 501///@ingroup VolumeSystem 502bool Rename(const Path &from, const Path &to); 503 504/// Get the file attributes. 505/// @return success 506///@ingroup VolumeSystem 507bool GetFileAttributes(const Path &path, FileNode::Attributes *attr); 508 509/// Compare modified times of p1 & p2 510/// @return -1 if p1 < p2, 0 if p1 == p2, 1 if p1 > p2 511S32 CompareModifiedTimes(const Path& p1, const Path& p2); 512 513/// Open a file. 514/// If the file exists a file object will be returned even if the 515/// open operation fails. 516///@return Null if the file does not exist 517///@ingroup VolumeSystem 518FileRef OpenFile(const Path &file, File::AccessMode mode); 519 520/// Read in an entire file 521/// @note Caller is responsible for freeing memory 522///@param inPath the file 523///@param outData the pointer to return the data 524///@param outSize the size of the data returned 525///@param inNullTerminate add an extra '\0' byte to the return buffer 526///@return successful read? If not, outData will be NULL and outSize will be 0 527bool ReadFile(const Path &inPath, void *&outData, U32 &outSize, bool inNullTerminate = false ); 528 529/// Open a directory. 530/// If the directory exists a directory object will be returned even if the 531/// open operation fails. 532///@return Null if the file does not exist 533///@ingroup VolumeSystem 534DirectoryRef OpenDirectory(const Path &file); 535 536/// Create a file. 537/// The file object is returned in a closed state. 538///@ingroup VolumeSystem 539FileRef CreateFile(const Path &file); 540 541/// Create a directory. 542/// The directory object is returned in a closed state. 543///@ingroup VolumeSystem 544DirectoryRef CreateDirectory(const Path &file); 545 546/// Create all the directories in the path if they don't already exist 547///@ingroup VolumeSystem 548bool CreatePath(const Path &path); 549 550bool IsReadOnly(const Path &path); 551bool IsDirectory(const Path &path); 552bool IsFile(const Path &path); 553bool VerifyWriteAccess(const Path &path); 554 555/// This returns a unique file path from the components 556/// by appending numbers to the end of the file name if 557/// a file with the same name already exists. 558/// 559/// @param path The root and directory for the file. 560/// @param fileName The file name without extension. 561/// @param ext The dot-less extension. 562String MakeUniquePath( const char *path, const char *fileName, const char *ext ); 563 564void StartFileChangeNotifications(); 565void StopFileChangeNotifications(); 566 567S32 GetNumMounts(); 568String GetMountRoot( S32 index ); 569String GetMountPath( S32 index ); 570String GetMountType( S32 index ); 571 572///@} 573 574} // Namespace FS 575} // Namespace Torque 576 577#endif 578 579