Line data Source code
1 : /* Copyright (C) 2016 Wildfire Games.
2 : *
3 : * Permission is hereby granted, free of charge, to any person obtaining
4 : * a copy of this software and associated documentation files (the
5 : * "Software"), to deal in the Software without restriction, including
6 : * without limitation the rights to use, copy, modify, merge, publish,
7 : * distribute, sublicense, and/or sell copies of the Software, and to
8 : * permit persons to whom the Software is furnished to do so, subject to
9 : * the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included
12 : * in all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 : */
22 :
23 : /*
24 : * 'tree' of VFS directories and files
25 : */
26 :
27 : #ifndef INCLUDED_VFS_TREE
28 : #define INCLUDED_VFS_TREE
29 :
30 : #include <map>
31 :
32 : #include "lib/file/file_system.h" // CFileInfo
33 : #include "lib/file/common/file_loader.h" // PIFileLoader
34 : #include "lib/file/common/real_directory.h" // PRealDirectory
35 : #include "lib/file/vfs/vfs_path.h"
36 :
37 12237 : class VfsFile
38 : {
39 : public:
40 : VfsFile(const VfsPath& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& provider);
41 :
42 7584 : const VfsPath& Name() const
43 : {
44 7584 : return m_name;
45 : }
46 :
47 7955 : size_t Size() const
48 : {
49 7955 : return m_size;
50 : }
51 :
52 2303 : time_t MTime() const
53 : {
54 2303 : return m_mtime;
55 : }
56 :
57 77 : size_t Priority() const
58 : {
59 77 : return m_priority;
60 : }
61 :
62 3221 : const PIFileLoader& Loader() const
63 : {
64 3221 : return m_loader;
65 : }
66 :
67 : private:
68 : VfsPath m_name;
69 : size_t m_size;
70 : time_t m_mtime;
71 :
72 : size_t m_priority;
73 :
74 : PIFileLoader m_loader;
75 : };
76 :
77 :
78 5181 : class VfsDirectory
79 : {
80 : /**
81 : * remove all files with a lower priority than @p file
82 : * and do the same for all subdirectories recursively.
83 : * @return true if the directory is empty afterwards
84 : **/
85 : bool DeleteTree(const VfsFile& file);
86 :
87 : public:
88 : typedef std::map<VfsPath, VfsFile> VfsFiles;
89 : typedef std::map<VfsPath, VfsDirectory> VfsSubdirectories;
90 :
91 : VfsDirectory();
92 :
93 : /**
94 : * remove the given file or subdirectory according to the priority of the
95 : * passed .DELETED file.
96 : * CAUTION: Invalidates all previously returned pointers of the file or
97 : * subdirectory (and contents) if those have lower priority
98 : * than @p file.
99 : **/
100 : void DeleteSubtree(const VfsFile& file);
101 :
102 : /**
103 : * @return address of existing or newly inserted file.
104 : **/
105 : VfsFile* AddFile(const VfsFile& file);
106 :
107 : /**
108 : * @return address of existing or newly inserted subdirectory.
109 : **/
110 : VfsDirectory* AddSubdirectory(const VfsPath& name);
111 :
112 : /**
113 : * remove the given file from the virtual directory (no effect on
114 : * the physical file). no effect if the file does not exist.
115 : **/
116 : void RemoveFile(const VfsPath& name);
117 :
118 : /**
119 : * @return file with the given name.
120 : * (note: non-const to allow changes to the file)
121 : **/
122 : VfsFile* GetFile(const VfsPath& name);
123 :
124 : /**
125 : * @return subdirectory with the given name.
126 : * (note: non-const to allow changes to the subdirectory)
127 : **/
128 : VfsDirectory* GetSubdirectory(const VfsPath& name);
129 :
130 : // note: exposing only iterators wouldn't enable callers to reserve space.
131 :
132 218 : const VfsFiles& Files() const
133 : {
134 218 : return m_files;
135 : }
136 :
137 7 : const VfsSubdirectories& Subdirectories() const
138 : {
139 7 : return m_subdirectories;
140 : }
141 :
142 : /**
143 : * side effect: the next ShouldPopulate() will return true.
144 : **/
145 : void SetAssociatedDirectory(const PRealDirectory& realDirectory);
146 :
147 18113 : const PRealDirectory& AssociatedDirectory() const
148 : {
149 18113 : return m_realDirectory;
150 : }
151 :
152 : /**
153 : * @return whether this directory should be populated from its
154 : * AssociatedDirectory(). note that calling this is a promise to
155 : * do so if true is returned -- the flag is reset immediately.
156 : **/
157 : bool ShouldPopulate();
158 :
159 : /**
160 : * ensure the next ShouldPopulate returns true.
161 : **/
162 : void RequestRepopulate();
163 :
164 : /**
165 : * empty file and subdirectory lists (e.g. when rebuilding VFS).
166 : * CAUTION: this invalidates all previously returned pointers.
167 : **/
168 : void Clear();
169 :
170 : private:
171 : VfsFiles m_files;
172 : VfsSubdirectories m_subdirectories;
173 :
174 : PRealDirectory m_realDirectory;
175 : volatile intptr_t m_shouldPopulate; // (cpu_CAS can't be used on bool)
176 : };
177 :
178 :
179 : /**
180 : * @return a string containing file attributes (location, size, timestamp) and name.
181 : **/
182 : extern std::wstring FileDescription(const VfsFile& file);
183 :
184 : /**
185 : * @return a string holding each files' description (one per line).
186 : **/
187 : extern std::wstring FileDescriptions(const VfsDirectory& directory, size_t indentLevel);
188 :
189 : /**
190 : * append each directory's files' description to the given string.
191 : **/
192 : void DirectoryDescriptionR(std::wstring& descriptions, const VfsDirectory& directory, size_t indentLevel);
193 :
194 : #endif // #ifndef INCLUDED_VFS_TREE
|