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