Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / patchman_service / file_manager.h
blobf2c8d1c840584444418525da78326e92186fe350
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef FILE_MANAGER_H
18 #define FILE_MANAGER_H
21 //-----------------------------------------------------------------------------
22 // includes
23 //-----------------------------------------------------------------------------
25 // nel
26 #include "nel/misc/singleton.h"
27 #include "nel/misc/sstring.h"
28 #include "nel/misc/md5.h"
29 #include "nel/misc/smart_ptr.h"
30 #include "nel/net/module.h"
33 //-----------------------------------------------------------------------------
34 // namespace PATCHMAN
35 //-----------------------------------------------------------------------------
37 namespace PATCHMAN
40 //-----------------------------------------------------------------------------
41 // forward class declarations
42 //-----------------------------------------------------------------------------
44 struct SFileInfo;
45 class CFileSpec;
46 class IFileRequestValidator;
47 class IFileInfoUpdateListener;
48 class CRepositoryDirectory;
49 class CFileManager;
52 //-----------------------------------------------------------------------------
53 // struct SFileInfo
54 //-----------------------------------------------------------------------------
56 struct SFileInfo
58 NLMISC::CSString FileName; // this name includes the directory name
59 uint32 FileSize;
60 uint32 FileTime;
61 NLMISC::CHashKeyMD5 Checksum;
63 SFileInfo(): FileSize(0), FileTime(0) {}
65 void clear()
67 FileName.clear();
68 FileSize=0;
69 FileTime=0;
70 Checksum.clear();
73 void serial(NLMISC::IStream& stream)
75 stream.serial(FileName);
76 stream.serial(FileSize);
77 stream.serial(FileTime);
78 stream.serial(Checksum);
81 // a '<' operator for use in STL containers and algorithms
82 bool operator<(const SFileInfo& other) const
84 // compare file names
85 if (FileName<other.FileName) return true;
86 if (other.FileName<FileName) return false;
88 // file names match so compare time stamps
89 if (FileTime<other.FileTime) return true;
90 if (other.FileTime<FileTime) return false;
92 // looks like a match so far so compare sizes
93 if (FileSize<other.FileSize) return true;
94 if (other.FileSize<FileSize) return false;
96 // the entries are identical so compare checksums
97 return Checksum < other.Checksum;
100 // Type used as parameter to updateFileInfo()
101 enum TUpdateMethod { DONT_RECALCULATE, RECALCULATE_IF_CHANGED, FORCE_RECALCULATE };
103 // Update the file info by looking at the given file path on the disk
104 // the fileName parameter is simply a label example: updateFileInfo("foo/bar.txt","c:/rootdir/foo/bar.txt")
105 // The update methods determine whether or not to (re)calculate MD5 checksum
106 // - DONT_RECALCULATE - never recalculate
107 // - RECALCULATE_IF_CHANGED - recalculate if either the file time or file size have changed
108 // - FORCE_RECALCULATE - always recalculate
110 // returns true if the record is valid and unchanged, othrwise returns false
112 bool updateFileInfo(const NLMISC::CSString& fileName,const NLMISC::CSString& fullFileName, TUpdateMethod updateMethod=RECALCULATE_IF_CHANGED, IFileInfoUpdateListener* updateListener=NULL);
114 typedef std::vector<SFileInfo> TFileInfoVector;
115 typedef std::map<NLMISC::CSString,SFileInfo> TFileInfoMap;
118 //-----------------------------------------------------------------------------
119 // class CFileSpec
120 //-----------------------------------------------------------------------------
121 // This class encapsulates a filespec description
122 // The file name and path sections of the spec are treated separately
123 // eg:
124 // toto/*tata - will match all files matching '*tata' in directory toto
125 // toto*/tata - will match files called 'tata' in directories 'toto/',
126 // 'toto_to/', 'toto/to/', etc
127 //-----------------------------------------------------------------------------
129 class CFileSpec
131 public:
132 // ctors
133 CFileSpec();
134 CFileSpec(const NLMISC::CSString& fileSpec);
136 // test a complete match (filename and path)
137 bool matches(const NLMISC::CSString& fullFileName) const;
139 // test whether the given file name matches the filename part of the filespec
140 // note - the supplied filename should already have been stripped of its path
141 bool nameMatches(const NLMISC::CSString& fileName) const;
143 // test whether the given path matches the path part of the filespec
144 // note - the supplied path should not have an attached file name
145 bool pathMatches(const NLMISC::CSString& path) const;
147 // retrieve the filespec as a single string (for serialising, etc)
148 NLMISC::CSString toString() const;
150 // accessors
151 const NLMISC::CSString& nameSpec() const;
152 const NLMISC::CSString& pathSpec() const;
153 bool isWild() const;
154 bool nameIsWild() const;
155 bool pathIsWild() const;
157 private:
158 NLMISC::CSString _NameSpec;
159 NLMISC::CSString _PathSpec;
160 bool _NameIsWild; // true if _NameSpec contains wildcards ('*' or '?')
161 bool _PathIsWild; // true if _PathSpec contains wildcards ('*' or '?')
162 bool _AcceptAllNames;
163 bool _AcceptAllPaths;
167 //-----------------------------------------------------------------------------
168 // class IFileRequestValidator
169 //-----------------------------------------------------------------------------
170 // a callback interface to be implemented by classes who want to
171 // validate getFile() and getFileInfo() requests
172 //-----------------------------------------------------------------------------
174 class IFileRequestValidator
176 public:
177 // overloadable callback methods
178 virtual bool cbValidateDownloadRequest(const NLNET::IModuleProxy *sender,const std::string &fileName) { return true; }
179 virtual bool cbValidateFileInfoRequest(const NLNET::IModuleProxy *sender,const std::string &fileName) { return true; }
183 //-----------------------------------------------------------------------------
184 // class IFileInfoUpdateListener
185 //-----------------------------------------------------------------------------
186 // a callback interface to be implemented by classes who want to
187 // receive update notification for finle info changes
188 //-----------------------------------------------------------------------------
190 class IFileInfoUpdateListener
192 public:
193 // overloadable callback methods
194 virtual void cbFileInfoRescanning(const NLMISC::CSString& fileName,uint32 fileSize) {} // called at start of rescan operation
195 virtual void cbFileInfoUpdate(const SFileInfo& fileInfo) {} // called at end of rescan
196 virtual void cbFileInfoErased(const NLMISC::CSString& fileName) {} //
200 //-----------------------------------------------------------------------------
201 // class CRepositoryDirectory
202 //-----------------------------------------------------------------------------
204 class CRepositoryDirectory: public NLMISC::CRefCount
206 public:
207 // handy types
208 typedef std::map<NLMISC::CSString,TFileInfoMap> TDirectoryTree;
210 // update methods
211 void clear();
212 void rescanFull(IFileInfoUpdateListener* updateListener);
213 void rescanPartial(IFileInfoUpdateListener* updateListener);
214 void updateFile(const NLMISC::CSString& fileName,SFileInfo::TUpdateMethod updateMethod, IFileInfoUpdateListener* updateListener);
216 // query methods
217 void getFileInfo(const NLMISC::CSString& fileSpec,TFileInfoVector& result,IFileRequestValidator* validator,const NLNET::IModuleProxy *sender=NULL) const;
218 void getFile(const NLMISC::CSString& fileName,NLMISC::CSString& resultData,IFileRequestValidator* validator,const NLNET::IModuleProxy *sender=NULL) const;
220 // accessors
221 const NLMISC::CSString &getRootDirectory() const;
223 // persistence methods
224 bool readIndex();
225 bool writeIndex() const;
228 private:
229 // ctor is private because only CFileManager singleton has the right to create us
230 friend class CFileManager;
232 // ctor and init
233 CRepositoryDirectory(const NLMISC::CSString& path);
235 private:
236 // private methods
237 void _rescanDirectory(const NLMISC::CSString& directoryName, bool recurse, IFileInfoUpdateListener* updateListener);
239 // private data
240 NLMISC::CSString _Root; // The root directory from which we are working
241 TDirectoryTree _DirectoryTree; // The set of files that we know (note, directories are mapped directly here)
242 NLMISC::CSString _LastRescan; // The name of the directory that we last rescanned
243 mutable bool _IndexFileIsUpToDate; // Is the index file on disk up to date (or does it need to be rewritten)
245 typedef NLMISC::CSmartPtr<CRepositoryDirectory> TRepositoryDirectoryPtr;
246 typedef NLMISC::CRefPtr<CRepositoryDirectory> TRepositoryDirectoryRefPtr;
249 //-----------------------------------------------------------------------------
250 // class CFileManager
251 //-----------------------------------------------------------------------------
253 class CFileManager: public NLMISC::CSingleton<CFileManager>
255 public:
256 // --------------------------------------------------------
257 // public interface
259 // loading file data
260 bool load(const NLMISC::CSString& fileName, uint32 startOffset, uint32 numBytes, NLMISC::CSString& result);
262 // saving files
263 bool save(const NLMISC::CSString& fileName, const NLMISC::CMemStream& data);
265 // accessing basic info about files
266 uint32 getFileSize(const NLMISC::CSString& fileName);
268 // get hold of a smart pointer to a repository directory object, creating a new one if need be
269 // or sharing an object that already exists
270 TRepositoryDirectoryPtr getRepositoryDirectory(const NLMISC::CSString& path);
273 private:
274 // --------------------------------------------------------
275 // private data for the file cache
276 std::vector<char> _CacheBuffer;
278 struct SCacheFileEntry
280 NLMISC::CSString FileName;
281 uint32 StartOffset;
282 uint32 FileSize;
283 uint32 FileTime;
286 typedef std::list<SCacheFileEntry> TCacheFiles;
287 TCacheFiles _CacheFiles;
289 // --------------------------------------------------------
290 // private data for managing the set of repository directories
291 typedef std::map<NLMISC::CSString,TRepositoryDirectoryRefPtr> TRepositoryDirectories;
292 TRepositoryDirectories _RepositoryDirectories;
295 } // end of namespace
297 //-----------------------------------------------------------------------------
298 #endif