/* * Copyright 2004 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef WEBRTC_BASE_FILEUTILS_H_ #define WEBRTC_BASE_FILEUTILS_H_ #include #if !defined(WEBRTC_WIN) #include #include #include #include #include #endif #include "webrtc/base/checks.h" #include "webrtc/base/constructormagic.h" #include "webrtc/base/platform_file.h" namespace rtc { class FileStream; class Pathname; ////////////////////////// // Directory Iterator // ////////////////////////// // A DirectoryIterator is created with a given directory. It originally points // to the first file in the directory, and can be advanecd with Next(). This // allows you to get information about each file. class DirectoryIterator { friend class Filesystem; public: // Constructor DirectoryIterator(); // Destructor virtual ~DirectoryIterator(); // Starts traversing a directory // dir is the directory to traverse // returns true if the directory exists and is valid // The iterator will point to the first entry in the directory virtual bool Iterate(const Pathname &path); // Advances to the next file // returns true if there were more files in the directory. virtual bool Next(); // returns true if the file currently pointed to is a directory virtual bool IsDirectory() const; // returns the name of the file currently pointed to virtual std::string Name() const; private: std::string directory_; #if defined(WEBRTC_WIN) WIN32_FIND_DATA data_; HANDLE handle_; #else DIR *dir_; struct dirent *dirent_; struct stat stat_; #endif }; enum FileTimeType { FTT_CREATED, FTT_MODIFIED, FTT_ACCESSED }; class FilesystemInterface { public: virtual ~FilesystemInterface() {} // Returns a DirectoryIterator for a given pathname. // TODO: Do fancy abstracted stuff virtual DirectoryIterator* IterateDirectory(); // Opens a file. Returns an open StreamInterface if function succeeds. // Otherwise, returns null. // TODO: Add an error param to indicate failure reason, similar to // FileStream::Open virtual FileStream *OpenFile(const Pathname &filename, const std::string &mode) = 0; // This will attempt to delete the path located at filename. // It DCHECKs and returns false if the path points to a folder or a // non-existent file. virtual bool DeleteFile(const Pathname &filename) = 0; // This will attempt to delete the empty folder located at 'folder' // It DCHECKs and returns false if the path points to a file or a non-existent // folder. It fails normally if the folder is not empty or can otherwise // not be deleted. virtual bool DeleteEmptyFolder(const Pathname &folder) = 0; // Creates a directory. This will call itself recursively to create /foo/bar // even if /foo does not exist. Returns true if the function succeeds. virtual bool CreateFolder(const Pathname &pathname) = 0; // This moves a file from old_path to new_path, where "old_path" is a // plain file. This DCHECKs and returns false if old_path points to a // directory, and returns true if the function succeeds. virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path) = 0; // Returns true if pathname refers to a directory virtual bool IsFolder(const Pathname& pathname) = 0; // Returns true if pathname refers to a file virtual bool IsFile(const Pathname& pathname) = 0; // Returns true if pathname refers to no filesystem object, every parent // directory either exists, or is also absent. virtual bool IsAbsent(const Pathname& pathname) = 0; // A folder appropriate for storing temporary files (Contents are // automatically deleted when the program exits) virtual bool GetTemporaryFolder(Pathname &path, bool create, const std::string *append) = 0; virtual std::string TempFilename(const Pathname &dir, const std::string &prefix) = 0; // Determines the size of the file indicated by path. virtual bool GetFileSize(const Pathname& path, size_t* size) = 0; // Determines a timestamp associated with the file indicated by path. virtual bool GetFileTime(const Pathname& path, FileTimeType which, time_t* time) = 0; // Note: These might go into some shared config section later, but they're // used by some methods in this interface, so we're leaving them here for now. void SetOrganizationName(const std::string& organization) { organization_name_ = organization; } void GetOrganizationName(std::string* organization) { RTC_DCHECK(organization); *organization = organization_name_; } void SetApplicationName(const std::string& application) { application_name_ = application; } void GetApplicationName(std::string* application) { RTC_DCHECK(application); *application = application_name_; } protected: std::string organization_name_; std::string application_name_; }; class Filesystem { public: static FilesystemInterface *default_filesystem() { RTC_DCHECK(default_filesystem_); return default_filesystem_; } static void set_default_filesystem(FilesystemInterface *filesystem) { default_filesystem_ = filesystem; } static FilesystemInterface *swap_default_filesystem( FilesystemInterface *filesystem) { FilesystemInterface *cur = default_filesystem_; default_filesystem_ = filesystem; return cur; } static DirectoryIterator *IterateDirectory() { return EnsureDefaultFilesystem()->IterateDirectory(); } static bool CreateFolder(const Pathname &pathname) { return EnsureDefaultFilesystem()->CreateFolder(pathname); } static FileStream *OpenFile(const Pathname &filename, const std::string &mode) { return EnsureDefaultFilesystem()->OpenFile(filename, mode); } static bool DeleteFile(const Pathname &filename) { return EnsureDefaultFilesystem()->DeleteFile(filename); } static bool MoveFile(const Pathname &old_path, const Pathname &new_path) { return EnsureDefaultFilesystem()->MoveFile(old_path, new_path); } static bool IsFolder(const Pathname& pathname) { return EnsureDefaultFilesystem()->IsFolder(pathname); } static bool IsFile(const Pathname &pathname) { return EnsureDefaultFilesystem()->IsFile(pathname); } static bool IsAbsent(const Pathname &pathname) { return EnsureDefaultFilesystem()->IsAbsent(pathname); } static bool GetTemporaryFolder(Pathname &path, bool create, const std::string *append) { return EnsureDefaultFilesystem()->GetTemporaryFolder(path, create, append); } static std::string TempFilename(const Pathname &dir, const std::string &prefix) { return EnsureDefaultFilesystem()->TempFilename(dir, prefix); } static bool GetFileSize(const Pathname& path, size_t* size) { return EnsureDefaultFilesystem()->GetFileSize(path, size); } static bool GetFileTime(const Pathname& path, FileTimeType which, time_t* time) { return EnsureDefaultFilesystem()->GetFileTime(path, which, time); } static void SetOrganizationName(const std::string& organization) { EnsureDefaultFilesystem()->SetOrganizationName(organization); } static void GetOrganizationName(std::string* organization) { EnsureDefaultFilesystem()->GetOrganizationName(organization); } static void SetApplicationName(const std::string& application) { EnsureDefaultFilesystem()->SetApplicationName(application); } static void GetApplicationName(std::string* application) { EnsureDefaultFilesystem()->GetApplicationName(application); } private: static FilesystemInterface* default_filesystem_; static FilesystemInterface *EnsureDefaultFilesystem(); RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem); }; } // namespace rtc #endif // WEBRTC_BASE_FILEUTILS_H_