Fix sort order of unlaunched apps on app list start page.
[chromium-blink-merge.git] / base / files / file_util.cc
blob32dab6bd40d8ee6b0113522259a8b2ff123f5712
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/files/file_util.h"
7 #if defined(OS_WIN)
8 #include <io.h>
9 #endif
10 #include <stdio.h>
12 #include <fstream>
13 #include <limits>
15 #include "base/files/file_enumerator.h"
16 #include "base/files/file_path.h"
17 #include "base/logging.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/strings/utf_string_conversions.h"
23 namespace base {
25 namespace {
27 // The maximum number of 'uniquified' files we will try to create.
28 // This is used when the filename we're trying to download is already in use,
29 // so we create a new unique filename by appending " (nnn)" before the
30 // extension, where 1 <= nnn <= kMaxUniqueFiles.
31 // Also used by code that cleans up said files.
32 static const int kMaxUniqueFiles = 100;
34 } // namespace
36 int64 ComputeDirectorySize(const FilePath& root_path) {
37 int64 running_size = 0;
38 FileEnumerator file_iter(root_path, true, FileEnumerator::FILES);
39 while (!file_iter.Next().empty())
40 running_size += file_iter.GetInfo().GetSize();
41 return running_size;
44 bool Move(const FilePath& from_path, const FilePath& to_path) {
45 if (from_path.ReferencesParent() || to_path.ReferencesParent())
46 return false;
47 return internal::MoveUnsafe(from_path, to_path);
50 bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
51 // We open the file in binary format even if they are text files because
52 // we are just comparing that bytes are exactly same in both files and not
53 // doing anything smart with text formatting.
54 std::ifstream file1(filename1.value().c_str(),
55 std::ios::in | std::ios::binary);
56 std::ifstream file2(filename2.value().c_str(),
57 std::ios::in | std::ios::binary);
59 // Even if both files aren't openable (and thus, in some sense, "equal"),
60 // any unusable file yields a result of "false".
61 if (!file1.is_open() || !file2.is_open())
62 return false;
64 const int BUFFER_SIZE = 2056;
65 char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE];
66 do {
67 file1.read(buffer1, BUFFER_SIZE);
68 file2.read(buffer2, BUFFER_SIZE);
70 if ((file1.eof() != file2.eof()) ||
71 (file1.gcount() != file2.gcount()) ||
72 (memcmp(buffer1, buffer2, static_cast<size_t>(file1.gcount())))) {
73 file1.close();
74 file2.close();
75 return false;
77 } while (!file1.eof() || !file2.eof());
79 file1.close();
80 file2.close();
81 return true;
84 bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) {
85 std::ifstream file1(filename1.value().c_str(), std::ios::in);
86 std::ifstream file2(filename2.value().c_str(), std::ios::in);
88 // Even if both files aren't openable (and thus, in some sense, "equal"),
89 // any unusable file yields a result of "false".
90 if (!file1.is_open() || !file2.is_open())
91 return false;
93 do {
94 std::string line1, line2;
95 getline(file1, line1);
96 getline(file2, line2);
98 // Check for mismatched EOF states, or any error state.
99 if ((file1.eof() != file2.eof()) ||
100 file1.bad() || file2.bad()) {
101 return false;
104 // Trim all '\r' and '\n' characters from the end of the line.
105 std::string::size_type end1 = line1.find_last_not_of("\r\n");
106 if (end1 == std::string::npos)
107 line1.clear();
108 else if (end1 + 1 < line1.length())
109 line1.erase(end1 + 1);
111 std::string::size_type end2 = line2.find_last_not_of("\r\n");
112 if (end2 == std::string::npos)
113 line2.clear();
114 else if (end2 + 1 < line2.length())
115 line2.erase(end2 + 1);
117 if (line1 != line2)
118 return false;
119 } while (!file1.eof() || !file2.eof());
121 return true;
124 bool ReadFileToString(const FilePath& path,
125 std::string* contents,
126 size_t max_size) {
127 if (contents)
128 contents->clear();
129 if (path.ReferencesParent())
130 return false;
131 FILE* file = OpenFile(path, "rb");
132 if (!file) {
133 return false;
136 const size_t kBufferSize = 1 << 16;
137 scoped_ptr<char[]> buf(new char[kBufferSize]);
138 size_t len;
139 size_t size = 0;
140 bool read_status = true;
142 // Many files supplied in |path| have incorrect size (proc files etc).
143 // Hence, the file is read sequentially as opposed to a one-shot read.
144 while ((len = fread(buf.get(), 1, kBufferSize, file)) > 0) {
145 if (contents)
146 contents->append(buf.get(), std::min(len, max_size - size));
148 if ((max_size - size) < len) {
149 read_status = false;
150 break;
153 size += len;
155 read_status = read_status && !ferror(file);
156 CloseFile(file);
158 return read_status;
161 bool ReadFileToString(const FilePath& path, std::string* contents) {
162 return ReadFileToString(path, contents, std::numeric_limits<size_t>::max());
165 bool IsDirectoryEmpty(const FilePath& dir_path) {
166 FileEnumerator files(dir_path, false,
167 FileEnumerator::FILES | FileEnumerator::DIRECTORIES);
168 if (files.Next().empty())
169 return true;
170 return false;
173 FILE* CreateAndOpenTemporaryFile(FilePath* path) {
174 FilePath directory;
175 if (!GetTempDir(&directory))
176 return NULL;
178 return CreateAndOpenTemporaryFileInDir(directory, path);
181 bool CreateDirectory(const FilePath& full_path) {
182 return CreateDirectoryAndGetError(full_path, NULL);
185 bool GetFileSize(const FilePath& file_path, int64* file_size) {
186 File::Info info;
187 if (!GetFileInfo(file_path, &info))
188 return false;
189 *file_size = info.size;
190 return true;
193 bool TouchFile(const FilePath& path,
194 const Time& last_accessed,
195 const Time& last_modified) {
196 int flags = File::FLAG_OPEN | File::FLAG_WRITE_ATTRIBUTES;
198 #if defined(OS_WIN)
199 // On Windows, FILE_FLAG_BACKUP_SEMANTICS is needed to open a directory.
200 if (DirectoryExists(path))
201 flags |= File::FLAG_BACKUP_SEMANTICS;
202 #endif // OS_WIN
204 File file(path, flags);
205 if (!file.IsValid())
206 return false;
208 return file.SetTimes(last_accessed, last_modified);
211 bool CloseFile(FILE* file) {
212 if (file == NULL)
213 return true;
214 return fclose(file) == 0;
217 bool TruncateFile(FILE* file) {
218 if (file == NULL)
219 return false;
220 long current_offset = ftell(file);
221 if (current_offset == -1)
222 return false;
223 #if defined(OS_WIN)
224 int fd = _fileno(file);
225 if (_chsize(fd, current_offset) != 0)
226 return false;
227 #else
228 int fd = fileno(file);
229 if (ftruncate(fd, current_offset) != 0)
230 return false;
231 #endif
232 return true;
235 int GetUniquePathNumber(const FilePath& path,
236 const FilePath::StringType& suffix) {
237 bool have_suffix = !suffix.empty();
238 if (!PathExists(path) &&
239 (!have_suffix || !PathExists(FilePath(path.value() + suffix)))) {
240 return 0;
243 FilePath new_path;
244 for (int count = 1; count <= kMaxUniqueFiles; ++count) {
245 new_path = path.InsertBeforeExtensionASCII(StringPrintf(" (%d)", count));
246 if (!PathExists(new_path) &&
247 (!have_suffix || !PathExists(FilePath(new_path.value() + suffix)))) {
248 return count;
252 return -1;
255 } // namespace base