blob: 9489de8193df95e8cb28de55d5f36f832900e796 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_BASE_FILEUTILS_H_
12#define WEBRTC_BASE_FILEUTILS_H_
13
14#include <string>
15
xians@webrtc.orge46bc772014-10-10 08:36:56 +000016#if !defined(WEBRTC_WIN)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017#include <dirent.h>
18#include <stdio.h>
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <unistd.h>
22#endif
23
24#include "webrtc/base/basictypes.h"
25#include "webrtc/base/common.h"
kwiberg4485ffb2016-04-26 08:14:39 -070026#include "webrtc/base/constructormagic.h"
xians@webrtc.orge46bc772014-10-10 08:36:56 +000027#include "webrtc/base/platform_file.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000028
29namespace rtc {
30
31class FileStream;
32class Pathname;
33
34//////////////////////////
35// Directory Iterator //
36//////////////////////////
37
38// A DirectoryIterator is created with a given directory. It originally points
39// to the first file in the directory, and can be advanecd with Next(). This
40// allows you to get information about each file.
41
42class DirectoryIterator {
43 friend class Filesystem;
44 public:
45 // Constructor
46 DirectoryIterator();
47 // Destructor
48 virtual ~DirectoryIterator();
49
50 // Starts traversing a directory
51 // dir is the directory to traverse
52 // returns true if the directory exists and is valid
53 // The iterator will point to the first entry in the directory
54 virtual bool Iterate(const Pathname &path);
55
56 // Advances to the next file
57 // returns true if there were more files in the directory.
58 virtual bool Next();
59
60 // returns true if the file currently pointed to is a directory
61 virtual bool IsDirectory() const;
62
63 // returns the name of the file currently pointed to
64 virtual std::string Name() const;
65
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000066 private:
67 std::string directory_;
68#if defined(WEBRTC_WIN)
69 WIN32_FIND_DATA data_;
70 HANDLE handle_;
71#else
72 DIR *dir_;
73 struct dirent *dirent_;
74 struct stat stat_;
75#endif
76};
77
78enum FileTimeType { FTT_CREATED, FTT_MODIFIED, FTT_ACCESSED };
79
80class FilesystemInterface {
81 public:
82 virtual ~FilesystemInterface() {}
83
84 // Returns a DirectoryIterator for a given pathname.
85 // TODO: Do fancy abstracted stuff
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000086 virtual DirectoryIterator* IterateDirectory();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000087
88 // Opens a file. Returns an open StreamInterface if function succeeds.
89 // Otherwise, returns NULL.
90 // TODO: Add an error param to indicate failure reason, similar to
91 // FileStream::Open
92 virtual FileStream *OpenFile(const Pathname &filename,
93 const std::string &mode) = 0;
94
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000095 // This will attempt to delete the path located at filename.
96 // It ASSERTS and returns false if the path points to a folder or a
97 // non-existent file.
98 virtual bool DeleteFile(const Pathname &filename) = 0;
99
100 // This will attempt to delete the empty folder located at 'folder'
101 // It ASSERTS and returns false if the path points to a file or a non-existent
102 // folder. It fails normally if the folder is not empty or can otherwise
103 // not be deleted.
104 virtual bool DeleteEmptyFolder(const Pathname &folder) = 0;
105
106 // This will call IterateDirectory, to get a directory iterator, and then
107 // call DeleteFolderAndContents and DeleteFile on every path contained in this
108 // folder. If the folder is empty, this returns true.
109 virtual bool DeleteFolderContents(const Pathname &folder);
110
111 // This deletes the contents of a folder, recursively, and then deletes
112 // the folder itself.
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000113 virtual bool DeleteFolderAndContents(const Pathname& folder);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000114
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000115 // Creates a directory. This will call itself recursively to create /foo/bar
116 // even if /foo does not exist. Returns true if the function succeeds.
117 virtual bool CreateFolder(const Pathname &pathname) = 0;
118
119 // This moves a file from old_path to new_path, where "old_path" is a
120 // plain file. This ASSERTs and returns false if old_path points to a
121 // directory, and returns true if the function succeeds.
122 // If the new path is on a different volume than the old path, this function
123 // will attempt to copy and, if that succeeds, delete the old path.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000124 virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path) = 0;
125
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126 // This copies a file from old_path to new_path. This method ASSERTs and
127 // returns false if old_path is a folder, and returns true if the copy
128 // succeeds.
129 virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path) = 0;
130
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000131 // Returns true if pathname refers to a directory
132 virtual bool IsFolder(const Pathname& pathname) = 0;
133
134 // Returns true if pathname refers to a file
135 virtual bool IsFile(const Pathname& pathname) = 0;
136
137 // Returns true if pathname refers to no filesystem object, every parent
138 // directory either exists, or is also absent.
139 virtual bool IsAbsent(const Pathname& pathname) = 0;
140
141 // Returns true if pathname represents a temporary location on the system.
142 virtual bool IsTemporaryPath(const Pathname& pathname) = 0;
143
144 // A folder appropriate for storing temporary files (Contents are
145 // automatically deleted when the program exits)
146 virtual bool GetTemporaryFolder(Pathname &path, bool create,
147 const std::string *append) = 0;
148
149 virtual std::string TempFilename(const Pathname &dir,
150 const std::string &prefix) = 0;
151
152 // Determines the size of the file indicated by path.
153 virtual bool GetFileSize(const Pathname& path, size_t* size) = 0;
154
155 // Determines a timestamp associated with the file indicated by path.
156 virtual bool GetFileTime(const Pathname& path, FileTimeType which,
157 time_t* time) = 0;
158
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000159 // Get a folder that is unique to the current application, which is suitable
160 // for sharing data between executions of the app. If the per_user arg is
161 // true, the folder is also specific to the current user.
162 virtual bool GetAppDataFolder(Pathname* path, bool per_user) = 0;
163
164 // Get a temporary folder that is unique to the current user and application.
165 // TODO: Re-evaluate the goals of this function. We probably just need any
166 // directory that won't collide with another existing directory, and which
167 // will be cleaned up when the program exits.
168 virtual bool GetAppTempFolder(Pathname* path) = 0;
169
Peter Boström0c4e06b2015-10-07 12:23:21 +0200170 virtual bool GetDiskFreeSpace(const Pathname& path, int64_t* freebytes) = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000171
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000172 // Note: These might go into some shared config section later, but they're
173 // used by some methods in this interface, so we're leaving them here for now.
174 void SetOrganizationName(const std::string& organization) {
175 organization_name_ = organization;
176 }
177 void GetOrganizationName(std::string* organization) {
178 ASSERT(NULL != organization);
179 *organization = organization_name_;
180 }
181 void SetApplicationName(const std::string& application) {
182 application_name_ = application;
183 }
184 void GetApplicationName(std::string* application) {
185 ASSERT(NULL != application);
186 *application = application_name_;
187 }
188
189 protected:
190 std::string organization_name_;
191 std::string application_name_;
192};
193
194class Filesystem {
195 public:
196 static FilesystemInterface *default_filesystem() {
197 ASSERT(default_filesystem_ != NULL);
198 return default_filesystem_;
199 }
200
201 static void set_default_filesystem(FilesystemInterface *filesystem) {
202 default_filesystem_ = filesystem;
203 }
204
205 static FilesystemInterface *swap_default_filesystem(
206 FilesystemInterface *filesystem) {
207 FilesystemInterface *cur = default_filesystem_;
208 default_filesystem_ = filesystem;
209 return cur;
210 }
211
212 static DirectoryIterator *IterateDirectory() {
213 return EnsureDefaultFilesystem()->IterateDirectory();
214 }
215
216 static bool CreateFolder(const Pathname &pathname) {
217 return EnsureDefaultFilesystem()->CreateFolder(pathname);
218 }
219
220 static FileStream *OpenFile(const Pathname &filename,
221 const std::string &mode) {
222 return EnsureDefaultFilesystem()->OpenFile(filename, mode);
223 }
224
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000225 static bool DeleteFile(const Pathname &filename) {
226 return EnsureDefaultFilesystem()->DeleteFile(filename);
227 }
228
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000229 static bool DeleteFolderContents(const Pathname &folder) {
230 return EnsureDefaultFilesystem()->DeleteFolderContents(folder);
231 }
232
233 static bool DeleteFolderAndContents(const Pathname &folder) {
234 return EnsureDefaultFilesystem()->DeleteFolderAndContents(folder);
235 }
236
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000237 static bool MoveFile(const Pathname &old_path, const Pathname &new_path) {
238 return EnsureDefaultFilesystem()->MoveFile(old_path, new_path);
239 }
240
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000241 static bool CopyFile(const Pathname &old_path, const Pathname &new_path) {
242 return EnsureDefaultFilesystem()->CopyFile(old_path, new_path);
243 }
244
245 static bool IsFolder(const Pathname& pathname) {
246 return EnsureDefaultFilesystem()->IsFolder(pathname);
247 }
248
249 static bool IsFile(const Pathname &pathname) {
250 return EnsureDefaultFilesystem()->IsFile(pathname);
251 }
252
253 static bool IsAbsent(const Pathname &pathname) {
254 return EnsureDefaultFilesystem()->IsAbsent(pathname);
255 }
256
257 static bool IsTemporaryPath(const Pathname& pathname) {
258 return EnsureDefaultFilesystem()->IsTemporaryPath(pathname);
259 }
260
261 static bool GetTemporaryFolder(Pathname &path, bool create,
262 const std::string *append) {
263 return EnsureDefaultFilesystem()->GetTemporaryFolder(path, create, append);
264 }
265
266 static std::string TempFilename(const Pathname &dir,
267 const std::string &prefix) {
268 return EnsureDefaultFilesystem()->TempFilename(dir, prefix);
269 }
270
271 static bool GetFileSize(const Pathname& path, size_t* size) {
272 return EnsureDefaultFilesystem()->GetFileSize(path, size);
273 }
274
275 static bool GetFileTime(const Pathname& path, FileTimeType which,
276 time_t* time) {
277 return EnsureDefaultFilesystem()->GetFileTime(path, which, time);
278 }
279
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000280 static bool GetAppDataFolder(Pathname* path, bool per_user) {
281 return EnsureDefaultFilesystem()->GetAppDataFolder(path, per_user);
282 }
283
284 static bool GetAppTempFolder(Pathname* path) {
285 return EnsureDefaultFilesystem()->GetAppTempFolder(path);
286 }
287
Peter Boström0c4e06b2015-10-07 12:23:21 +0200288 static bool GetDiskFreeSpace(const Pathname& path, int64_t* freebytes) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000289 return EnsureDefaultFilesystem()->GetDiskFreeSpace(path, freebytes);
290 }
291
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000292 static void SetOrganizationName(const std::string& organization) {
293 EnsureDefaultFilesystem()->SetOrganizationName(organization);
294 }
295
296 static void GetOrganizationName(std::string* organization) {
297 EnsureDefaultFilesystem()->GetOrganizationName(organization);
298 }
299
300 static void SetApplicationName(const std::string& application) {
301 EnsureDefaultFilesystem()->SetApplicationName(application);
302 }
303
304 static void GetApplicationName(std::string* application) {
305 EnsureDefaultFilesystem()->GetApplicationName(application);
306 }
307
308 private:
309 static FilesystemInterface* default_filesystem_;
310
311 static FilesystemInterface *EnsureDefaultFilesystem();
henrikg3c089d72015-09-16 05:37:44 -0700312 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000313};
314
315class FilesystemScope{
316 public:
317 explicit FilesystemScope(FilesystemInterface *new_fs) {
318 old_fs_ = Filesystem::swap_default_filesystem(new_fs);
319 }
320 ~FilesystemScope() {
321 Filesystem::set_default_filesystem(old_fs_);
322 }
323 private:
324 FilesystemInterface* old_fs_;
henrikg3c089d72015-09-16 05:37:44 -0700325 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(FilesystemScope);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000326};
327
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000328} // namespace rtc
329
330#endif // WEBRTC_BASE_FILEUTILS_H_