Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / base / fileutils.h
1 /*
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
16 #if defined(WEBRTC_WIN)
17 #include "webrtc/base/win32.h"
18 #else
19 #include <dirent.h>
20 #include <stdio.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #endif
25
26 #include "webrtc/base/basictypes.h"
27 #include "webrtc/base/common.h"
28 #include "webrtc/base/scoped_ptr.h"
29
30 namespace rtc {
31
32 class FileStream;
33 class Pathname;
34
35 //////////////////////////
36 // Directory Iterator   //
37 //////////////////////////
38
39 // A DirectoryIterator is created with a given directory. It originally points
40 // to the first file in the directory, and can be advanecd with Next(). This
41 // allows you to get information about each file.
42
43 class DirectoryIterator {
44   friend class Filesystem;
45  public:
46   // Constructor
47   DirectoryIterator();
48   // Destructor
49   virtual ~DirectoryIterator();
50
51   // Starts traversing a directory
52   // dir is the directory to traverse
53   // returns true if the directory exists and is valid
54   // The iterator will point to the first entry in the directory
55   virtual bool Iterate(const Pathname &path);
56
57   // Advances to the next file
58   // returns true if there were more files in the directory.
59   virtual bool Next();
60
61   // returns true if the file currently pointed to is a directory
62   virtual bool IsDirectory() const;
63
64   // returns the name of the file currently pointed to
65   virtual std::string Name() const;
66
67   // returns the size of the file currently pointed to
68   virtual size_t FileSize() const;
69
70   // returns true if the file is older than seconds
71   virtual bool OlderThan(int seconds) const;
72
73   // checks whether current file is a special directory file "." or ".."
74   bool IsDots() const {
75     std::string filename(Name());
76     return (filename.compare(".") == 0) || (filename.compare("..") == 0);
77   }
78
79  private:
80   std::string directory_;
81 #if defined(WEBRTC_WIN)
82   WIN32_FIND_DATA data_;
83   HANDLE handle_;
84 #else
85   DIR *dir_;
86   struct dirent *dirent_;
87   struct stat stat_;
88 #endif
89 };
90
91 enum FileTimeType { FTT_CREATED, FTT_MODIFIED, FTT_ACCESSED };
92
93 class FilesystemInterface {
94  public:
95   virtual ~FilesystemInterface() {}
96
97   // Returns a DirectoryIterator for a given pathname.
98   // TODO: Do fancy abstracted stuff
99   virtual DirectoryIterator *IterateDirectory() {
100     return new DirectoryIterator();
101   }
102
103   // Opens a file. Returns an open StreamInterface if function succeeds.
104   // Otherwise, returns NULL.
105   // TODO: Add an error param to indicate failure reason, similar to
106   // FileStream::Open
107   virtual FileStream *OpenFile(const Pathname &filename,
108                                const std::string &mode) = 0;
109
110   // Atomically creates an empty file accessible only to the current user if one
111   // does not already exist at the given path, otherwise fails. This is the only
112   // secure way to create a file in a shared temp directory (e.g., C:\Temp on
113   // Windows or /tmp on Linux).
114   // Note that if it is essential that a file be successfully created then the
115   // app must generate random names and retry on failure, or else it will be
116   // vulnerable to a trivial DoS.
117   virtual bool CreatePrivateFile(const Pathname &filename) = 0;
118
119   // This will attempt to delete the path located at filename.
120   // It ASSERTS and returns false if the path points to a folder or a
121   // non-existent file.
122   virtual bool DeleteFile(const Pathname &filename) = 0;
123
124   // This will attempt to delete the empty folder located at 'folder'
125   // It ASSERTS and returns false if the path points to a file or a non-existent
126   // folder. It fails normally if the folder is not empty or can otherwise
127   // not be deleted.
128   virtual bool DeleteEmptyFolder(const Pathname &folder) = 0;
129
130   // This will call IterateDirectory, to get a directory iterator, and then
131   // call DeleteFolderAndContents and DeleteFile on every path contained in this
132   // folder. If the folder is empty, this returns true.
133   virtual bool DeleteFolderContents(const Pathname &folder);
134
135   // This deletes the contents of a folder, recursively, and then deletes
136   // the folder itself.
137   virtual bool DeleteFolderAndContents(const Pathname &folder) {
138     return DeleteFolderContents(folder) && DeleteEmptyFolder(folder);
139   }
140
141   // This will delete whatever is located at path, be it a file or a folder.
142   // If it is a folder, it will delete it recursively by calling
143   // DeleteFolderAndContents
144   bool DeleteFileOrFolder(const Pathname &path) {
145     if (IsFolder(path))
146       return DeleteFolderAndContents(path);
147     else
148       return DeleteFile(path);
149   }
150
151   // Creates a directory. This will call itself recursively to create /foo/bar
152   // even if /foo does not exist. Returns true if the function succeeds.
153   virtual bool CreateFolder(const Pathname &pathname) = 0;
154
155   // This moves a file from old_path to new_path, where "old_path" is a
156   // plain file. This ASSERTs and returns false if old_path points to a
157   // directory, and returns true if the function succeeds.
158   // If the new path is on a different volume than the old path, this function
159   // will attempt to copy and, if that succeeds, delete the old path.
160   virtual bool MoveFolder(const Pathname &old_path,
161                           const Pathname &new_path) = 0;
162
163   // This moves a directory from old_path to new_path, where "old_path" is a
164   // directory. This ASSERTs and returns false if old_path points to a plain
165   // file, and returns true if the function succeeds.
166   // If the new path is on a different volume, this function will attempt to
167   // copy and if that succeeds, delete the old path.
168   virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path) = 0;
169
170   // This attempts to move whatever is located at old_path to new_path,
171   // be it a file or folder.
172   bool MoveFileOrFolder(const Pathname &old_path, const Pathname &new_path) {
173     if (IsFile(old_path)) {
174       return MoveFile(old_path, new_path);
175     } else {
176       return MoveFolder(old_path, new_path);
177     }
178   }
179
180   // This copies a file from old_path to new_path. This method ASSERTs and
181   // returns false if old_path is a folder, and returns true if the copy
182   // succeeds.
183   virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path) = 0;
184
185   // This copies a folder from old_path to new_path.
186   bool CopyFolder(const Pathname &old_path, const Pathname &new_path);
187
188   bool CopyFileOrFolder(const Pathname &old_path, const Pathname &new_path) {
189     if (IsFile(old_path))
190       return CopyFile(old_path, new_path);
191     else
192       return CopyFolder(old_path, new_path);
193   }
194
195   // Returns true if pathname refers to a directory
196   virtual bool IsFolder(const Pathname& pathname) = 0;
197
198   // Returns true if pathname refers to a file
199   virtual bool IsFile(const Pathname& pathname) = 0;
200
201   // Returns true if pathname refers to no filesystem object, every parent
202   // directory either exists, or is also absent.
203   virtual bool IsAbsent(const Pathname& pathname) = 0;
204
205   // Returns true if pathname represents a temporary location on the system.
206   virtual bool IsTemporaryPath(const Pathname& pathname) = 0;
207
208   // A folder appropriate for storing temporary files (Contents are
209   // automatically deleted when the program exits)
210   virtual bool GetTemporaryFolder(Pathname &path, bool create,
211                                   const std::string *append) = 0;
212
213   virtual std::string TempFilename(const Pathname &dir,
214                                    const std::string &prefix) = 0;
215
216   // Determines the size of the file indicated by path.
217   virtual bool GetFileSize(const Pathname& path, size_t* size) = 0;
218
219   // Determines a timestamp associated with the file indicated by path.
220   virtual bool GetFileTime(const Pathname& path, FileTimeType which,
221                            time_t* time) = 0;
222
223   // Returns the path to the running application.
224   // Note: This is not guaranteed to work on all platforms.  Be aware of the
225   // limitations before using it, and robustly handle failure.
226   virtual bool GetAppPathname(Pathname* path) = 0;
227
228   // Get a folder that is unique to the current application, which is suitable
229   // for sharing data between executions of the app.  If the per_user arg is
230   // true, the folder is also specific to the current user.
231   virtual bool GetAppDataFolder(Pathname* path, bool per_user) = 0;
232
233   // Get a temporary folder that is unique to the current user and application.
234   // TODO: Re-evaluate the goals of this function.  We probably just need any
235   // directory that won't collide with another existing directory, and which
236   // will be cleaned up when the program exits.
237   virtual bool GetAppTempFolder(Pathname* path) = 0;
238
239   // Delete the contents of the folder returned by GetAppTempFolder
240   bool CleanAppTempFolder();
241
242   virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes) = 0;
243
244   // Returns the absolute path of the current directory.
245   virtual Pathname GetCurrentDirectory() = 0;
246
247   // Note: These might go into some shared config section later, but they're
248   // used by some methods in this interface, so we're leaving them here for now.
249   void SetOrganizationName(const std::string& organization) {
250     organization_name_ = organization;
251   }
252   void GetOrganizationName(std::string* organization) {
253     ASSERT(NULL != organization);
254     *organization = organization_name_;
255   }
256   void SetApplicationName(const std::string& application) {
257     application_name_ = application;
258   }
259   void GetApplicationName(std::string* application) {
260     ASSERT(NULL != application);
261     *application = application_name_;
262   }
263
264  protected:
265   std::string organization_name_;
266   std::string application_name_;
267 };
268
269 class Filesystem {
270  public:
271   static FilesystemInterface *default_filesystem() {
272     ASSERT(default_filesystem_ != NULL);
273     return default_filesystem_;
274   }
275
276   static void set_default_filesystem(FilesystemInterface *filesystem) {
277     default_filesystem_ = filesystem;
278   }
279
280   static FilesystemInterface *swap_default_filesystem(
281       FilesystemInterface *filesystem) {
282     FilesystemInterface *cur = default_filesystem_;
283     default_filesystem_ = filesystem;
284     return cur;
285   }
286
287   static DirectoryIterator *IterateDirectory() {
288     return EnsureDefaultFilesystem()->IterateDirectory();
289   }
290
291   static bool CreateFolder(const Pathname &pathname) {
292     return EnsureDefaultFilesystem()->CreateFolder(pathname);
293   }
294
295   static FileStream *OpenFile(const Pathname &filename,
296                               const std::string &mode) {
297     return EnsureDefaultFilesystem()->OpenFile(filename, mode);
298   }
299
300   static bool CreatePrivateFile(const Pathname &filename) {
301     return EnsureDefaultFilesystem()->CreatePrivateFile(filename);
302   }
303
304   static bool DeleteFile(const Pathname &filename) {
305     return EnsureDefaultFilesystem()->DeleteFile(filename);
306   }
307
308   static bool DeleteEmptyFolder(const Pathname &folder) {
309     return EnsureDefaultFilesystem()->DeleteEmptyFolder(folder);
310   }
311
312   static bool DeleteFolderContents(const Pathname &folder) {
313     return EnsureDefaultFilesystem()->DeleteFolderContents(folder);
314   }
315
316   static bool DeleteFolderAndContents(const Pathname &folder) {
317     return EnsureDefaultFilesystem()->DeleteFolderAndContents(folder);
318   }
319
320   static bool MoveFolder(const Pathname &old_path, const Pathname &new_path) {
321     return EnsureDefaultFilesystem()->MoveFolder(old_path, new_path);
322   }
323
324   static bool MoveFile(const Pathname &old_path, const Pathname &new_path) {
325     return EnsureDefaultFilesystem()->MoveFile(old_path, new_path);
326   }
327
328   static bool CopyFolder(const Pathname &old_path, const Pathname &new_path) {
329     return EnsureDefaultFilesystem()->CopyFolder(old_path, new_path);
330   }
331
332   static bool CopyFile(const Pathname &old_path, const Pathname &new_path) {
333     return EnsureDefaultFilesystem()->CopyFile(old_path, new_path);
334   }
335
336   static bool IsFolder(const Pathname& pathname) {
337     return EnsureDefaultFilesystem()->IsFolder(pathname);
338   }
339
340   static bool IsFile(const Pathname &pathname) {
341     return EnsureDefaultFilesystem()->IsFile(pathname);
342   }
343
344   static bool IsAbsent(const Pathname &pathname) {
345     return EnsureDefaultFilesystem()->IsAbsent(pathname);
346   }
347
348   static bool IsTemporaryPath(const Pathname& pathname) {
349     return EnsureDefaultFilesystem()->IsTemporaryPath(pathname);
350   }
351
352   static bool GetTemporaryFolder(Pathname &path, bool create,
353                                  const std::string *append) {
354     return EnsureDefaultFilesystem()->GetTemporaryFolder(path, create, append);
355   }
356
357   static std::string TempFilename(const Pathname &dir,
358                                   const std::string &prefix) {
359     return EnsureDefaultFilesystem()->TempFilename(dir, prefix);
360   }
361
362   static bool GetFileSize(const Pathname& path, size_t* size) {
363     return EnsureDefaultFilesystem()->GetFileSize(path, size);
364   }
365
366   static bool GetFileTime(const Pathname& path, FileTimeType which,
367                           time_t* time) {
368     return EnsureDefaultFilesystem()->GetFileTime(path, which, time);
369   }
370
371   static bool GetAppPathname(Pathname* path) {
372     return EnsureDefaultFilesystem()->GetAppPathname(path);
373   }
374
375   static bool GetAppDataFolder(Pathname* path, bool per_user) {
376     return EnsureDefaultFilesystem()->GetAppDataFolder(path, per_user);
377   }
378
379   static bool GetAppTempFolder(Pathname* path) {
380     return EnsureDefaultFilesystem()->GetAppTempFolder(path);
381   }
382
383   static bool CleanAppTempFolder() {
384     return EnsureDefaultFilesystem()->CleanAppTempFolder();
385   }
386
387   static bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes) {
388     return EnsureDefaultFilesystem()->GetDiskFreeSpace(path, freebytes);
389   }
390
391   // Definition has to be in the .cc file due to returning forward-declared
392   // Pathname by value.
393   static Pathname GetCurrentDirectory();
394
395   static void SetOrganizationName(const std::string& organization) {
396     EnsureDefaultFilesystem()->SetOrganizationName(organization);
397   }
398
399   static void GetOrganizationName(std::string* organization) {
400     EnsureDefaultFilesystem()->GetOrganizationName(organization);
401   }
402
403   static void SetApplicationName(const std::string& application) {
404     EnsureDefaultFilesystem()->SetApplicationName(application);
405   }
406
407   static void GetApplicationName(std::string* application) {
408     EnsureDefaultFilesystem()->GetApplicationName(application);
409   }
410
411  private:
412   static FilesystemInterface* default_filesystem_;
413
414   static FilesystemInterface *EnsureDefaultFilesystem();
415   DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem);
416 };
417
418 class FilesystemScope{
419  public:
420   explicit FilesystemScope(FilesystemInterface *new_fs) {
421     old_fs_ = Filesystem::swap_default_filesystem(new_fs);
422   }
423   ~FilesystemScope() {
424     Filesystem::set_default_filesystem(old_fs_);
425   }
426  private:
427   FilesystemInterface* old_fs_;
428   DISALLOW_IMPLICIT_CONSTRUCTORS(FilesystemScope);
429 };
430
431 // Generates a unique filename based on the input path.  If no path component
432 // is specified, it uses the temporary directory.  If a filename is provided,
433 // up to 100 variations of form basename-N.extension are tried.  When
434 // create_empty is true, an empty file of this name is created (which
435 // decreases the chance of a temporary filename collision with another
436 // process).
437 bool CreateUniqueFile(Pathname& path, bool create_empty);
438
439 // Taken from Chromium's base/platform_file.h.
440 // Don't use ClosePlatformFile to close a file opened with FdopenPlatformFile.
441 // Use fclose instead.
442 // TODO(grunell): Remove when Chromium has started to use AEC in each source.
443 // http://crbug.com/264611.
444 #if defined(WEBRTC_WIN)
445 typedef HANDLE PlatformFile;
446 const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
447 #elif defined(WEBRTC_POSIX)
448 typedef int PlatformFile;
449 const PlatformFile kInvalidPlatformFileValue = -1;
450 #else
451 #error Unsupported platform
452 #endif
453
454 FILE* FdopenPlatformFileForWriting(PlatformFile file);
455 bool ClosePlatformFile(PlatformFile file);
456
457 }  // namespace rtc
458
459 #endif  // WEBRTC_BASE_FILEUTILS_H_