1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <io.h> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fstream> 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_piece.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/utf_string_conversions.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst FilePath::CharType kExtensionSeparator = FILE_PATH_LITERAL('.'); 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace file_util { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool EndsWithSeparator(const FilePath& path) { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType value = path.value(); 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (value.empty()) 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FilePath::IsSeparator(value[value.size() - 1]); 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool EnsureEndsWithSeparator(FilePath* path) { 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!DirectoryExists(*path)) 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EndsWithSeparator(*path)) 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType& path_str = 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const_cast<FilePath::StringType&>(path->value()); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott path_str.append(&FilePath::kSeparators[0], 1); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFilePath::StringType GetFileExtensionFromPath(const FilePath& path) { 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType file_name = path.BaseName().value(); 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath::StringType::size_type last_dot = 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_name.rfind(kExtensionSeparator); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FilePath::StringType(last_dot == FilePath::StringType::npos ? 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILE_PATH_LITERAL("") : 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_name, last_dot+1); 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid InsertBeforeExtension(FilePath* path, const FilePath::StringType& suffix) { 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType& value = 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const_cast<FilePath::StringType&>(path->value()); 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath::StringType::size_type last_dot = 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value.rfind(kExtensionSeparator); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath::StringType::size_type last_separator = 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value.find_last_of(FilePath::StringType(FilePath::kSeparators)); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (last_dot == FilePath::StringType::npos || 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (last_separator != std::wstring::npos && last_dot < last_separator)) { 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The path looks something like "C:\pics.old\jojo" or "C:\pics\jojo". 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We should just append the suffix to the entire path. 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value.append(suffix); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value.insert(last_dot, suffix); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ContentsEqual(const FilePath& filename1, const FilePath& filename2) { 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We open the file in binary format even if they are text files because 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we are just comparing that bytes are exactly same in both files and not 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // doing anything smart with text formatting. 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::ifstream file1(filename1.value().c_str(), 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::ios::in | std::ios::binary); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::ifstream file2(filename2.value().c_str(), 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::ios::in | std::ios::binary); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Even if both files aren't openable (and thus, in some sense, "equal"), 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // any unusable file yields a result of "false". 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file1.is_open() || !file2.is_open()) 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int BUFFER_SIZE = 2056; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE]; 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do { 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file1.read(buffer1, BUFFER_SIZE); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file2.read(buffer2, BUFFER_SIZE); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((file1.eof() != file2.eof()) || 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (file1.gcount() != file2.gcount()) || 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (memcmp(buffer1, buffer2, file1.gcount()))) { 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file1.close(); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file2.close(); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (!file1.eof() || !file2.eof()); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file1.close(); 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file2.close(); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) { 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::ifstream file1(filename1.value().c_str(), std::ios::in); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::ifstream file2(filename2.value().c_str(), std::ios::in); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Even if both files aren't openable (and thus, in some sense, "equal"), 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // any unusable file yields a result of "false". 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file1.is_open() || !file2.is_open()) 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do { 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string line1, line2; 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott getline(file1, line1); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott getline(file2, line2); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check for mismatched EOF states, or any error state. 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((file1.eof() != file2.eof()) || 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file1.bad() || file2.bad()) { 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Trim all '\r' and '\n' characters from the end of the line. 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::size_type end1 = line1.find_last_not_of("\r\n"); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (end1 == std::string::npos) 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott line1.clear(); 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else if (end1 + 1 < line1.length()) 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott line1.erase(end1 + 1); 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::size_type end2 = line2.find_last_not_of("\r\n"); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (end2 == std::string::npos) 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott line2.clear(); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else if (end2 + 1 < line2.length()) 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott line2.erase(end2 + 1); 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (line1 != line2) 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (!file1.eof() || !file2.eof()); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ReadFileToString(const FilePath& path, std::string* contents) { 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILE* file = OpenFile(path, "rb"); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file) { 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char buf[1 << 16]; 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t len; 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while ((len = fread(buf, 1, sizeof(buf), file)) > 0) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (contents) 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch contents->append(buf, len); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseFile(file); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsDirectoryEmpty(const FilePath& dir_path) { 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FileEnumerator files(dir_path, false, 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<FileEnumerator::FILE_TYPE>( 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FileEnumerator::FILES | FileEnumerator::DIRECTORIES)); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (files.Next().value().empty()) 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFILE* CreateAndOpenTemporaryFile(FilePath* path) { 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath directory; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!GetTempDir(&directory)) 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CreateAndOpenTemporaryFileInDir(directory, path); 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetFileSize(const FilePath& file_path, int64* file_size) { 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::PlatformFileInfo info; 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!GetFileInfo(file_path, &info)) 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *file_size = info.size; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsDot(const FilePath& path) { 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FILE_PATH_LITERAL(".") == path.BaseName().value(); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsDotDot(const FilePath& path) { 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FILE_PATH_LITERAL("..") == path.BaseName().value(); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TouchFile(const FilePath& path, 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const base::Time& last_accessed, 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const base::Time& last_modified) { 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::PlatformFile file = 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::CreatePlatformFile(path, 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::PLATFORM_FILE_OPEN | 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::PLATFORM_FILE_WRITE_ATTRIBUTES, 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, NULL); 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (file != base::kInvalidPlatformFileValue) { 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool result = base::TouchPlatformFile(file, last_accessed, last_modified); 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::ClosePlatformFile(file); 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return result; 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool SetLastModifiedTime(const FilePath& path, 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const base::Time& last_modified) { 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return TouchFile(path, last_modified, last_modified); 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CloseFile(FILE* file) { 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (file == NULL) 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return fclose(file) == 0; 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool TruncateFile(FILE* file) { 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (file == NULL) 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott long current_offset = ftell(file); 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (current_offset == -1) 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd = _fileno(file); 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (_chsize(fd, current_offset) != 0) 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd = fileno(file); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ftruncate(fd, current_offset) != 0) 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ContainsPath(const FilePath &parent, const FilePath& child) { 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath abs_parent = FilePath(parent); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath abs_child = FilePath(child); 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file_util::AbsolutePath(&abs_parent) || 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !file_util::AbsolutePath(&abs_child)) 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // file_util::AbsolutePath() does not flatten case on Windows, so we must do 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a case-insensitive compare. 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!StartsWith(abs_child.value(), abs_parent.value(), false)) 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!StartsWithASCII(abs_child.value(), abs_parent.value(), true)) 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // file_util::AbsolutePath() normalizes '/' to '\' on Windows, so we only need 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to check kSeparators[0]. 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (abs_child.value().length() <= abs_parent.value().length() || 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott abs_child.value()[abs_parent.value().length()] != 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::kSeparators[0]) 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint64 ComputeDirectorySize(const FilePath& root_path) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 running_size = 0; 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FileEnumerator file_iter(root_path, true, FileEnumerator::FILES); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (FilePath current = file_iter.Next(); !current.empty(); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current = file_iter.Next()) { 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FileEnumerator::FindInfo info; 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_iter.GetFindInfo(&info); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LARGE_INTEGER li = { info.nFileSizeLow, info.nFileSizeHigh }; 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch running_size += li.QuadPart; 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch running_size += info.stat.st_size; 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return running_size; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint64 ComputeFilesSize(const FilePath& directory, 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath::StringType& pattern) { 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 running_size = 0; 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FileEnumerator file_iter(directory, false, FileEnumerator::FILES, pattern); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (FilePath current = file_iter.Next(); !current.empty(); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current = file_iter.Next()) { 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FileEnumerator::FindInfo info; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_iter.GetFindInfo(&info); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LARGE_INTEGER li = { info.nFileSizeLow, info.nFileSizeHigh }; 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch running_size += li.QuadPart; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch running_size += info.stat.st_size; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return running_size; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/////////////////////////////////////////////// 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MemoryMappedFile 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMemoryMappedFile::~MemoryMappedFile() { 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandles(); 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool MemoryMappedFile::Initialize(const FilePath& file_name) { 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (IsValid()) 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!MapFileToMemory(file_name)) { 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandles(); 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool MemoryMappedFile::Initialize(base::PlatformFile file) { 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (IsValid()) 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen file_ = file; 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!MapFileToMemoryInternal()) { 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandles(); 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool MemoryMappedFile::IsValid() const { 34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return data_ != NULL; 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { 3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick file_ = base::CreatePlatformFile( 3503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick file_name, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, 3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, NULL); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (file_ == base::kInvalidPlatformFileValue) { 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Couldn't open " << file_name.value(); 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return MapFileToMemoryInternal(); 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Deprecated functions ---------------------------------------------------- 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN) 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid AppendToPath(std::wstring* path, const std::wstring& new_ending) { 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!path) { 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; // Don't crash in this function in release builds. 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!EndsWithSeparator(FilePath(*path))) 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott path->push_back(FilePath::kSeparators[0]); 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott path->append(new_ending); 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path, 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool recursive) { 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CopyDirectory(FilePath::FromWStringHack(from_path), 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::FromWStringHack(to_path), 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott recursive); 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Delete(const std::wstring& path, bool recursive) { 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Delete(FilePath::FromWStringHack(path), recursive); 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::wstring GetFileExtensionFromPath(const std::wstring& path) { 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType extension = 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GetFileExtensionFromPath(FilePath::FromWStringHack(path)); 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return extension; 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFILE* OpenFile(const std::wstring& filename, const char* mode) { 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return OpenFile(FilePath::FromWStringHack(filename), mode); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ReadFile(const std::wstring& filename, char* data, int size) { 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ReadFile(FilePath::FromWStringHack(filename), data, size); 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint WriteFile(const std::wstring& filename, const char* data, int size) { 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return WriteFile(FilePath::FromWStringHack(filename), data, size); 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 398731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif // OS_WIN 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/////////////////////////////////////////////// 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FileEnumerator 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Note: the main logic is in file_util_<platform>.cc 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FileEnumerator::ShouldSkip(const FilePath& path) { 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType basename = path.BaseName().value(); 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return IsDot(path) || (IsDotDot(path) && !(INCLUDE_DOT_DOT & file_type_)); 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 411