Deprecate restore_scissor_on_fbo_change workaround
[chromium-blink-merge.git] / base / file_util.cc
blobe9806763855f8b3cc90eb13176ca2a4d330dce11
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/file_util.h"
7 #if defined(OS_WIN)
8 #include <io.h>
9 #endif
10 #include <stdio.h>
12 #include <fstream>
14 #include "base/files/file_enumerator.h"
15 #include "base/files/file_path.h"
16 #include "base/logging.h"
17 #include "base/strings/string_piece.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
22 namespace base {
24 namespace {
26 const FilePath::CharType kExtensionSeparator = FILE_PATH_LITERAL('.');
28 // The maximum number of 'uniquified' files we will try to create.
29 // This is used when the filename we're trying to download is already in use,
30 // so we create a new unique filename by appending " (nnn)" before the
31 // extension, where 1 <= nnn <= kMaxUniqueFiles.
32 // Also used by code that cleans up said files.
33 static const int kMaxUniqueFiles = 100;
35 } // namespace
37 bool g_bug108724_debug = false;
39 int64 ComputeDirectorySize(const FilePath& root_path) {
40 int64 running_size = 0;
41 FileEnumerator file_iter(root_path, true, FileEnumerator::FILES);
42 while (!file_iter.Next().empty())
43 running_size += file_iter.GetInfo().GetSize();
44 return running_size;
47 bool Move(const FilePath& from_path, const FilePath& to_path) {
48 if (from_path.ReferencesParent() || to_path.ReferencesParent())
49 return false;
50 return internal::MoveUnsafe(from_path, to_path);
53 bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
54 if (from_path.ReferencesParent() || to_path.ReferencesParent())
55 return false;
56 return internal::CopyFileUnsafe(from_path, to_path);
59 bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
60 // We open the file in binary format even if they are text files because
61 // we are just comparing that bytes are exactly same in both files and not
62 // doing anything smart with text formatting.
63 std::ifstream file1(filename1.value().c_str(),
64 std::ios::in | std::ios::binary);
65 std::ifstream file2(filename2.value().c_str(),
66 std::ios::in | std::ios::binary);
68 // Even if both files aren't openable (and thus, in some sense, "equal"),
69 // any unusable file yields a result of "false".
70 if (!file1.is_open() || !file2.is_open())
71 return false;
73 const int BUFFER_SIZE = 2056;
74 char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE];
75 do {
76 file1.read(buffer1, BUFFER_SIZE);
77 file2.read(buffer2, BUFFER_SIZE);
79 if ((file1.eof() != file2.eof()) ||
80 (file1.gcount() != file2.gcount()) ||
81 (memcmp(buffer1, buffer2, file1.gcount()))) {
82 file1.close();
83 file2.close();
84 return false;
86 } while (!file1.eof() || !file2.eof());
88 file1.close();
89 file2.close();
90 return true;
93 bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) {
94 std::ifstream file1(filename1.value().c_str(), std::ios::in);
95 std::ifstream file2(filename2.value().c_str(), std::ios::in);
97 // Even if both files aren't openable (and thus, in some sense, "equal"),
98 // any unusable file yields a result of "false".
99 if (!file1.is_open() || !file2.is_open())
100 return false;
102 do {
103 std::string line1, line2;
104 getline(file1, line1);
105 getline(file2, line2);
107 // Check for mismatched EOF states, or any error state.
108 if ((file1.eof() != file2.eof()) ||
109 file1.bad() || file2.bad()) {
110 return false;
113 // Trim all '\r' and '\n' characters from the end of the line.
114 std::string::size_type end1 = line1.find_last_not_of("\r\n");
115 if (end1 == std::string::npos)
116 line1.clear();
117 else if (end1 + 1 < line1.length())
118 line1.erase(end1 + 1);
120 std::string::size_type end2 = line2.find_last_not_of("\r\n");
121 if (end2 == std::string::npos)
122 line2.clear();
123 else if (end2 + 1 < line2.length())
124 line2.erase(end2 + 1);
126 if (line1 != line2)
127 return false;
128 } while (!file1.eof() || !file2.eof());
130 return true;
133 bool ReadFileToString(const FilePath& path, std::string* contents) {
134 if (path.ReferencesParent())
135 return false;
136 FILE* file = file_util::OpenFile(path, "rb");
137 if (!file) {
138 return false;
141 char buf[1 << 16];
142 size_t len;
143 while ((len = fread(buf, 1, sizeof(buf), file)) > 0) {
144 if (contents)
145 contents->append(buf, len);
147 file_util::CloseFile(file);
149 return true;
152 } // namespace base
154 // -----------------------------------------------------------------------------
156 namespace file_util {
158 using base::FileEnumerator;
159 using base::FilePath;
160 using base::kExtensionSeparator;
161 using base::kMaxUniqueFiles;
163 bool IsDirectoryEmpty(const FilePath& dir_path) {
164 FileEnumerator files(dir_path, false,
165 FileEnumerator::FILES | FileEnumerator::DIRECTORIES);
166 if (files.Next().empty())
167 return true;
168 return false;
171 FILE* CreateAndOpenTemporaryFile(FilePath* path) {
172 FilePath directory;
173 if (!GetTempDir(&directory))
174 return NULL;
176 return CreateAndOpenTemporaryFileInDir(directory, path);
179 bool CreateDirectory(const base::FilePath& full_path) {
180 return CreateDirectoryAndGetError(full_path, NULL);
183 bool GetFileSize(const FilePath& file_path, int64* file_size) {
184 base::PlatformFileInfo info;
185 if (!GetFileInfo(file_path, &info))
186 return false;
187 *file_size = info.size;
188 return true;
191 bool TouchFile(const FilePath& path,
192 const base::Time& last_accessed,
193 const base::Time& last_modified) {
194 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE_ATTRIBUTES;
196 #if defined(OS_WIN)
197 // On Windows, FILE_FLAG_BACKUP_SEMANTICS is needed to open a directory.
198 if (DirectoryExists(path))
199 flags |= base::PLATFORM_FILE_BACKUP_SEMANTICS;
200 #endif // OS_WIN
202 const base::PlatformFile file =
203 base::CreatePlatformFile(path, flags, NULL, NULL);
204 if (file != base::kInvalidPlatformFileValue) {
205 bool result = base::TouchPlatformFile(file, last_accessed, last_modified);
206 base::ClosePlatformFile(file);
207 return result;
210 return false;
213 bool SetLastModifiedTime(const FilePath& path,
214 const base::Time& last_modified) {
215 return TouchFile(path, last_modified, last_modified);
218 bool CloseFile(FILE* file) {
219 if (file == NULL)
220 return true;
221 return fclose(file) == 0;
224 bool TruncateFile(FILE* file) {
225 if (file == NULL)
226 return false;
227 long current_offset = ftell(file);
228 if (current_offset == -1)
229 return false;
230 #if defined(OS_WIN)
231 int fd = _fileno(file);
232 if (_chsize(fd, current_offset) != 0)
233 return false;
234 #else
235 int fd = fileno(file);
236 if (ftruncate(fd, current_offset) != 0)
237 return false;
238 #endif
239 return true;
242 int GetUniquePathNumber(
243 const FilePath& path,
244 const FilePath::StringType& suffix) {
245 bool have_suffix = !suffix.empty();
246 if (!PathExists(path) &&
247 (!have_suffix || !PathExists(FilePath(path.value() + suffix)))) {
248 return 0;
251 FilePath new_path;
252 for (int count = 1; count <= kMaxUniqueFiles; ++count) {
253 new_path =
254 path.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", count));
255 if (!PathExists(new_path) &&
256 (!have_suffix || !PathExists(FilePath(new_path.value() + suffix)))) {
257 return count;
261 return -1;
264 } // namespace file_util