diff options
Diffstat (limited to 'chromium/third_party/webrtc/base/fileutils.cc')
-rw-r--r-- | chromium/third_party/webrtc/base/fileutils.cc | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/chromium/third_party/webrtc/base/fileutils.cc b/chromium/third_party/webrtc/base/fileutils.cc new file mode 100644 index 00000000000..60bd0f8f427 --- /dev/null +++ b/chromium/third_party/webrtc/base/fileutils.cc @@ -0,0 +1,307 @@ +/* + * 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. + */ + +#include <assert.h> + +#if defined(WEBRTC_WIN) +// TODO(grunell): Remove io.h includes when Chromium has started +// to use AEC in each source. http://crbug.com/264611. +#include <io.h> +#include "webrtc/base/win32.h" +#endif + +#include "webrtc/base/pathutils.h" +#include "webrtc/base/fileutils.h" +#include "webrtc/base/stringutils.h" +#include "webrtc/base/stream.h" + +#if defined(WEBRTC_WIN) +#include "webrtc/base/win32filesystem.h" +#else +#include "webrtc/base/unixfilesystem.h" +#endif + +#if !defined(WEBRTC_WIN) +#define MAX_PATH 260 +#endif + +namespace rtc { + +////////////////////////// +// 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. + + // Constructor +DirectoryIterator::DirectoryIterator() +#ifdef WEBRTC_WIN + : handle_(INVALID_HANDLE_VALUE) { +#else + : dir_(NULL), dirent_(NULL) { +#endif +} + + // Destructor +DirectoryIterator::~DirectoryIterator() { +#if defined(WEBRTC_WIN) + if (handle_ != INVALID_HANDLE_VALUE) + ::FindClose(handle_); +#else + if (dir_) + closedir(dir_); +#endif +} + + // Starts traversing a directory. + // dir is the directory to traverse + // returns true if the directory exists and is valid +bool DirectoryIterator::Iterate(const Pathname &dir) { + directory_ = dir.pathname(); +#if defined(WEBRTC_WIN) + if (handle_ != INVALID_HANDLE_VALUE) + ::FindClose(handle_); + std::string d = dir.pathname() + '*'; + handle_ = ::FindFirstFile(ToUtf16(d).c_str(), &data_); + if (handle_ == INVALID_HANDLE_VALUE) + return false; +#else + if (dir_ != NULL) + closedir(dir_); + dir_ = ::opendir(directory_.c_str()); + if (dir_ == NULL) + return false; + dirent_ = readdir(dir_); + if (dirent_ == NULL) + return false; + + if (::stat(std::string(directory_ + Name()).c_str(), &stat_) != 0) + return false; +#endif + return true; +} + + // Advances to the next file + // returns true if there were more files in the directory. +bool DirectoryIterator::Next() { +#if defined(WEBRTC_WIN) + return ::FindNextFile(handle_, &data_) == TRUE; +#else + dirent_ = ::readdir(dir_); + if (dirent_ == NULL) + return false; + + return ::stat(std::string(directory_ + Name()).c_str(), &stat_) == 0; +#endif +} + + // returns true if the file currently pointed to is a directory +bool DirectoryIterator::IsDirectory() const { +#if defined(WEBRTC_WIN) + return (data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FALSE; +#else + return S_ISDIR(stat_.st_mode); +#endif +} + + // returns the name of the file currently pointed to +std::string DirectoryIterator::Name() const { +#if defined(WEBRTC_WIN) + return ToUtf8(data_.cFileName); +#else + assert(dirent_ != NULL); + return dirent_->d_name; +#endif +} + + // returns the size of the file currently pointed to +size_t DirectoryIterator::FileSize() const { +#if !defined(WEBRTC_WIN) + return stat_.st_size; +#else + return data_.nFileSizeLow; +#endif +} + + // returns the last modified time of this file +time_t DirectoryIterator::FileModifyTime() const { +#if defined(WEBRTC_WIN) + time_t val; + FileTimeToUnixTime(data_.ftLastWriteTime, &val); + return val; +#else + return stat_.st_mtime; +#endif +} + +FilesystemInterface* Filesystem::default_filesystem_ = NULL; + +FilesystemInterface *Filesystem::EnsureDefaultFilesystem() { + if (!default_filesystem_) { +#if defined(WEBRTC_WIN) + default_filesystem_ = new Win32Filesystem(); +#else + default_filesystem_ = new UnixFilesystem(); +#endif + } + return default_filesystem_; +} + +bool FilesystemInterface::CopyFolder(const Pathname &old_path, + const Pathname &new_path) { + bool success = true; + VERIFY(IsFolder(old_path)); + Pathname new_dir; + new_dir.SetFolder(new_path.pathname()); + Pathname old_dir; + old_dir.SetFolder(old_path.pathname()); + if (!CreateFolder(new_dir)) + return false; + DirectoryIterator *di = IterateDirectory(); + if (!di) + return false; + if (di->Iterate(old_dir.pathname())) { + do { + if (di->Name() == "." || di->Name() == "..") + continue; + Pathname source; + Pathname dest; + source.SetFolder(old_dir.pathname()); + dest.SetFolder(new_path.pathname()); + source.SetFilename(di->Name()); + dest.SetFilename(di->Name()); + if (!CopyFileOrFolder(source, dest)) + success = false; + } while (di->Next()); + } + delete di; + return success; +} + +bool FilesystemInterface::DeleteFolderContents(const Pathname &folder) { + bool success = true; + VERIFY(IsFolder(folder)); + DirectoryIterator *di = IterateDirectory(); + if (!di) + return false; + if (di->Iterate(folder)) { + do { + if (di->Name() == "." || di->Name() == "..") + continue; + Pathname subdir; + subdir.SetFolder(folder.pathname()); + if (di->IsDirectory()) { + subdir.AppendFolder(di->Name()); + if (!DeleteFolderAndContents(subdir)) { + success = false; + } + } else { + subdir.SetFilename(di->Name()); + if (!DeleteFile(subdir)) { + success = false; + } + } + } while (di->Next()); + } + delete di; + return success; +} + +bool FilesystemInterface::CleanAppTempFolder() { + Pathname path; + if (!GetAppTempFolder(&path)) + return false; + if (IsAbsent(path)) + return true; + if (!IsTemporaryPath(path)) { + ASSERT(false); + return false; + } + return DeleteFolderContents(path); +} + +Pathname Filesystem::GetCurrentDirectory() { + return EnsureDefaultFilesystem()->GetCurrentDirectory(); +} + +bool CreateUniqueFile(Pathname& path, bool create_empty) { + LOG(LS_INFO) << "Path " << path.pathname() << std::endl; + // If no folder is supplied, use the temporary folder + if (path.folder().empty()) { + Pathname temporary_path; + if (!Filesystem::GetTemporaryFolder(temporary_path, true, NULL)) { + printf("Get temp failed\n"); + return false; + } + path.SetFolder(temporary_path.pathname()); + } + + // If no filename is supplied, use a temporary name + if (path.filename().empty()) { + std::string folder(path.folder()); + std::string filename = Filesystem::TempFilename(folder, "gt"); + path.SetPathname(filename); + if (!create_empty) { + Filesystem::DeleteFile(path.pathname()); + } + return true; + } + + // Otherwise, create a unique name based on the given filename + // foo.txt -> foo-N.txt + const std::string basename = path.basename(); + const size_t MAX_VERSION = 100; + size_t version = 0; + while (version < MAX_VERSION) { + std::string pathname = path.pathname(); + + if (!Filesystem::IsFile(pathname)) { + if (create_empty) { + FileStream* fs = Filesystem::OpenFile(pathname, "w"); + delete fs; + } + return true; + } + version += 1; + char version_base[MAX_PATH]; + sprintfn(version_base, ARRAY_SIZE(version_base), "%s-%u", + basename.c_str(), version); + path.SetBasename(version_base); + } + return true; +} + +// Taken from Chromium's base/platform_file_*.cc. +// TODO(grunell): Remove when Chromium has started to use AEC in each source. +// http://crbug.com/264611. +FILE* FdopenPlatformFileForWriting(PlatformFile file) { +#if defined(WEBRTC_WIN) + if (file == kInvalidPlatformFileValue) + return NULL; + int fd = _open_osfhandle(reinterpret_cast<intptr_t>(file), 0); + if (fd < 0) + return NULL; + return _fdopen(fd, "w"); +#else + return fdopen(file, "w"); +#endif +} + +bool ClosePlatformFile(PlatformFile file) { +#if defined(WEBRTC_WIN) + return CloseHandle(file) != 0; +#else + return close(file); +#endif +} + +} // namespace rtc |