Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: base/file_util.cc

Issue 12489: Remove file_util::kPathSeparator from posix. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_util.h ('k') | base/file_util_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/file_util.h" 5 #include "base/file_util.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include <fstream> 9 #include <fstream>
10 10
11 #include "base/file_path.h" 11 #include "base/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "unicode/uniset.h" 14 #include "unicode/uniset.h"
15 15
16 #include "base/string_piece.h"
17 #include "base/sys_string_conversions.h"
18
16 namespace file_util { 19 namespace file_util {
17 20
18 const wchar_t kExtensionSeparator = L'.'; 21 void PathComponents(const FilePath& path,
22 std::vector<FilePath::StringType>* components) {
23 DCHECK(components);
24 if (!components)
25 return;
19 26
20 void PathComponents(const std::wstring& path, 27 FilePath::StringType path_str = path.value();
21 std::vector<std::wstring>* components) { 28 FilePath::StringType::size_type start = 0;
22 DCHECK(components != NULL); 29 FilePath::StringType::size_type end =
23 if (components == NULL) 30 path_str.find_first_of(FilePath::kSeparators);
24 return;
25 std::wstring::size_type start = 0;
26 std::wstring::size_type end = path.find(kPathSeparator, start);
27 31
28 // Special case the "/" or "\" directory. On Windows with a drive letter, 32 // If the path starts with a separator, add it to components.
29 // this code path won't hit, but the right thing should still happen.
30 // "E:\foo" will turn into "E:","foo".
31 if (end == start) { 33 if (end == start) {
32 components->push_back(std::wstring(path, 0, 1)); 34 components->push_back(FilePath::StringType(path_str, 0, 1));
33 start = end + 1; 35 start = end + 1;
34 end = path.find(kPathSeparator, start); 36 end = path_str.find_first_of(FilePath::kSeparators, start);
35 } 37 }
36 while (end != std::wstring::npos) { 38 while (end != FilePath::StringType::npos) {
37 std::wstring component = std::wstring(path, start, end - start); 39 FilePath::StringType component =
40 FilePath::StringType(path_str, start, end - start);
38 components->push_back(component); 41 components->push_back(component);
39 start = end + 1; 42 start = end + 1;
40 end = path.find(kPathSeparator, start); 43 end = path_str.find(FilePath::kSeparators, start);
41 } 44 }
42 std::wstring component = std::wstring(path, start); 45
43 components->push_back(component); 46 components->push_back(FilePath::StringType(path_str, start));
44 } 47 }
45 48
46 bool EndsWithSeparator(const FilePath& file_path) { 49 bool EndsWithSeparator(const FilePath& path) {
47 std::wstring path = file_path.ToWStringHack(); 50 FilePath::StringType value = path.value();
48 bool is_sep = (path.length() > 0 && 51 if (value.empty())
49 path[path.length() - 1] == kPathSeparator); 52 return false;
50 return is_sep; 53
54 return FilePath::IsSeparator(value[value.size() - 1]);
51 } 55 }
52 56
53 bool EnsureEndsWithSeparator(FilePath* path) { 57 bool EnsureEndsWithSeparator(FilePath* path) {
54 if (!DirectoryExists(*path)) 58 if (!DirectoryExists(*path))
55 return false; 59 return false;
56 60
57 if (EndsWithSeparator(*path)) 61 if (EndsWithSeparator(*path))
58 return true; 62 return true;
59 63
60 FilePath::StringType& path_str = 64 FilePath::StringType& path_str =
61 const_cast<FilePath::StringType&>(path->value()); 65 const_cast<FilePath::StringType&>(path->value());
62 path_str.append(&FilePath::kSeparators[0], 1); 66 path_str.append(&FilePath::kSeparators[0], 1);
63 67
64 return true; 68 return true;
65 } 69 }
66 70
67 void TrimTrailingSeparator(std::wstring* dir) { 71 void TrimTrailingSeparator(std::wstring* dir) {
68 while (dir->length() > 1 && EndsWithSeparator(dir)) 72 while (dir->length() > 1 && EndsWithSeparator(dir))
69 dir->resize(dir->length() - 1); 73 dir->resize(dir->length() - 1);
70 } 74 }
71 75
72 void UpOneDirectory(std::wstring* dir) {
73 TrimTrailingSeparator(dir);
74
75 std::wstring::size_type last_sep = dir->find_last_of(kPathSeparator);
76 if (last_sep != std::wstring::npos)
77 dir->resize(last_sep);
78 }
79
80 void UpOneDirectoryOrEmpty(std::wstring* dir) {
81 TrimTrailingSeparator(dir);
82
83 std::wstring::size_type last_sep = dir->find_last_of(kPathSeparator);
84 if (last_sep != std::wstring::npos)
85 dir->resize(last_sep);
86 else
87 dir->clear();
88 }
89
90 void TrimFilename(std::wstring* path) {
91 if (EndsWithSeparator(path)) {
92 TrimTrailingSeparator(path);
93 } else {
94 std::wstring::size_type last_sep = path->find_last_of(kPathSeparator);
95 if (last_sep != std::wstring::npos)
96 path->resize(last_sep);
97 }
98 }
99
100 std::wstring GetFilenameFromPath(const std::wstring& path) { 76 std::wstring GetFilenameFromPath(const std::wstring& path) {
101 // TODO(erikkay): fix this - it's not using kPathSeparator, but win unit test 77 // TODO(erikkay): fix this - it's not using kPathSeparator, but win unit test
102 // are exercising '/' as a path separator as well. 78 // are exercising '/' as a path separator as well.
103 std::wstring::size_type pos = path.find_last_of(L"\\/"); 79 std::wstring::size_type pos = path.find_last_of(L"\\/");
104 return std::wstring(path, pos == std::wstring::npos ? 0 : pos + 1); 80 return std::wstring(path, pos == std::wstring::npos ? 0 : pos + 1);
105 } 81 }
106 82
107 std::wstring GetFileExtensionFromPath(const std::wstring& path) { 83 std::wstring GetFileExtensionFromPath(const std::wstring& path) {
108 std::wstring file_name = GetFilenameFromPath(path); 84 std::wstring file_name = GetFilenameFromPath(path);
109 std::wstring::size_type last_dot = file_name.rfind(L'.'); 85 std::wstring::size_type last_dot = file_name.rfind(L'.');
110 return std::wstring(last_dot == std::wstring::npos ? 86 return std::wstring(last_dot == std::wstring::npos ?
111 L"" : 87 L"" :
112 file_name, last_dot+1); 88 file_name, last_dot+1);
113 } 89 }
114 90
115 std::wstring GetFilenameWithoutExtensionFromPath(const std::wstring& path) { 91 std::wstring GetFilenameWithoutExtensionFromPath(const std::wstring& path) {
116 std::wstring file_name = GetFilenameFromPath(path); 92 std::wstring file_name = GetFilenameFromPath(path);
117 std::wstring::size_type last_dot = file_name.rfind(L'.'); 93 std::wstring::size_type last_dot = file_name.rfind(L'.');
118 return file_name.substr(0, last_dot); 94 return file_name.substr(0, last_dot);
119 } 95 }
120 96
121 void AppendToPath(std::wstring* path, const std::wstring& new_ending) {
122 if (!path) {
123 NOTREACHED();
124 return; // Don't crash in this function in release builds.
125 }
126
127 if (!EndsWithSeparator(path))
128 path->push_back(kPathSeparator);
129 path->append(new_ending);
130 }
131
132 void InsertBeforeExtension(std::wstring* path, const std::wstring& suffix) {
133 DCHECK(path);
134
135 const std::wstring::size_type last_dot = path->rfind(kExtensionSeparator);
136 const std::wstring::size_type last_sep = path->rfind(kPathSeparator);
137
138 if (last_dot == std::wstring::npos ||
139 (last_sep != std::wstring::npos && last_dot < last_sep)) {
140 // The path looks something like "C:\pics.old\jojo" or "C:\pics\jojo".
141 // We should just append the suffix to the entire path.
142 path->append(suffix);
143 return;
144 }
145
146 path->insert(last_dot, suffix);
147 }
148
149 void ReplaceIllegalCharacters(std::wstring* file_name, int replace_char) { 97 void ReplaceIllegalCharacters(std::wstring* file_name, int replace_char) {
150 DCHECK(file_name); 98 DCHECK(file_name);
151 99
152 // Control characters, formatting characters, non-characters, and 100 // Control characters, formatting characters, non-characters, and
153 // some printable ASCII characters regarded as dangerous ('"*/:<>?\\'). 101 // some printable ASCII characters regarded as dangerous ('"*/:<>?\\').
154 // See http://blogs.msdn.com/michkap/archive/2006/11/03/941420.aspx 102 // See http://blogs.msdn.com/michkap/archive/2006/11/03/941420.aspx
155 // and http://msdn2.microsoft.com/en-us/library/Aa365247.aspx 103 // and http://msdn2.microsoft.com/en-us/library/Aa365247.aspx
156 // TODO(jungshik): Revisit the set. ZWJ and ZWNJ are excluded because they 104 // TODO(jungshik): Revisit the set. ZWJ and ZWNJ are excluded because they
157 // are legitimate in Arabic and some S/SE Asian scripts. However, when used 105 // are legitimate in Arabic and some S/SE Asian scripts. However, when used
158 // elsewhere, they can be confusing/problematic. 106 // elsewhere, they can be confusing/problematic.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (illegal_characters.contains(wstr[i])) { 157 if (illegal_characters.contains(wstr[i])) {
210 (*file_name)[i] = replace_char; 158 (*file_name)[i] = replace_char;
211 } 159 }
212 ++i; 160 ++i;
213 } 161 }
214 #else 162 #else
215 #error wchar_t* should be either UTF-16 or UTF-32 163 #error wchar_t* should be either UTF-16 or UTF-32
216 #endif 164 #endif
217 } 165 }
218 166
219 // Appends the extension to file adding a '.' if extension doesn't contain one.
220 // This does nothing if extension is empty or '.'. This is used internally by
221 // ReplaceExtension.
222 static void AppendExtension(const std::wstring& extension,
223 std::wstring* file) {
224 if (!extension.empty() && extension != L".") {
225 if (extension[0] != L'.')
226 file->append(L".");
227 file->append(extension);
228 }
229 }
230
231 void ReplaceExtension(std::wstring* file_name, const std::wstring& extension) {
232 const std::wstring::size_type last_dot = file_name->rfind(L'.');
233 if (last_dot == std::wstring::npos) {
234 // No extension, just append the supplied extension.
235 AppendExtension(extension, file_name);
236 return;
237 }
238 const std::wstring::size_type last_separator =
239 file_name->rfind(kPathSeparator);
240 if (last_separator != std::wstring::npos && last_dot < last_separator) {
241 // File name doesn't have extension, but one of the directories does; don't
242 // replace it, just append the supplied extension. For example
243 // 'c:\tmp.bar\foo'.
244 AppendExtension(extension, file_name);
245 return;
246 }
247 std::wstring result = file_name->substr(0, last_dot);
248 AppendExtension(extension, &result);
249 file_name->swap(result);
250 }
251
252 bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) { 167 bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
253 // We open the file in binary format even if they are text files because 168 // We open the file in binary format even if they are text files because
254 // we are just comparing that bytes are exactly same in both files and not 169 // we are just comparing that bytes are exactly same in both files and not
255 // doing anything smart with text formatting. 170 // doing anything smart with text formatting.
256 std::ifstream file1(filename1.value().c_str(), 171 std::ifstream file1(filename1.value().c_str(),
257 std::ios::in | std::ios::binary); 172 std::ios::in | std::ios::binary);
258 std::ifstream file2(filename2.value().c_str(), 173 std::ifstream file2(filename2.value().c_str(),
259 std::ios::in | std::ios::binary); 174 std::ios::in | std::ios::binary);
260 175
261 // Even if both files aren't openable (and thus, in some sense, "equal"), 176 // Even if both files aren't openable (and thus, in some sense, "equal"),
262 // any unusable file yields a result of "false". 177 // any unusable file yields a result of "false".
263 if (!file1.is_open() || !file2.is_open()) 178 if (!file1.is_open() || !file2.is_open())
264 return false; 179 return false;
265 180
266 const int BUFFER_SIZE = 2056; 181 const int BUFFER_SIZE = 2056;
267 char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE]; 182 char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE];
268 do { 183 do {
269 file1.read(buffer1, BUFFER_SIZE); 184 file1.read(buffer1, BUFFER_SIZE);
270 file2.read(buffer2, BUFFER_SIZE); 185 file2.read(buffer2, BUFFER_SIZE);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 231
317 // Deprecated functions ---------------------------------------------------- 232 // Deprecated functions ----------------------------------------------------
318 233
319 bool AbsolutePath(std::wstring* path_str) { 234 bool AbsolutePath(std::wstring* path_str) {
320 FilePath path(FilePath::FromWStringHack(*path_str)); 235 FilePath path(FilePath::FromWStringHack(*path_str));
321 if (!AbsolutePath(&path)) 236 if (!AbsolutePath(&path))
322 return false; 237 return false;
323 *path_str = path.ToWStringHack(); 238 *path_str = path.ToWStringHack();
324 return true; 239 return true;
325 } 240 }
326 bool Delete(const std::wstring& path, bool recursive) { 241 void AppendToPath(std::wstring* path, const std::wstring& new_ending) {
327 return Delete(FilePath::FromWStringHack(path), recursive); 242 if (!path) {
328 } 243 NOTREACHED();
329 bool EndsWithSeparator(std::wstring* path) { 244 return; // Don't crash in this function in release builds.
330 return EndsWithSeparator(FilePath::FromWStringHack(*path)); 245 }
331 } 246
332 bool EndsWithSeparator(const std::wstring& path) { 247 if (!EndsWithSeparator(path))
333 return EndsWithSeparator(FilePath::FromWStringHack(path)); 248 path->push_back(FilePath::kSeparators[0]);
334 } 249 path->append(new_ending);
335 bool Move(const std::wstring& from_path, const std::wstring& to_path) {
336 return Move(FilePath::FromWStringHack(from_path),
337 FilePath::FromWStringHack(to_path));
338 }
339 bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
340 return CopyFile(FilePath::FromWStringHack(from_path),
341 FilePath::FromWStringHack(to_path));
342 } 250 }
343 bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path, 251 bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
344 bool recursive) { 252 bool recursive) {
345 return CopyDirectory(FilePath::FromWStringHack(from_path), 253 return CopyDirectory(FilePath::FromWStringHack(from_path),
346 FilePath::FromWStringHack(to_path), 254 FilePath::FromWStringHack(to_path),
347 recursive); 255 recursive);
348 } 256 }
349 bool PathExists(const std::wstring& path) {
350 return PathExists(FilePath::FromWStringHack(path));
351 }
352 bool DirectoryExists(const std::wstring& path) {
353 return DirectoryExists(FilePath::FromWStringHack(path));
354 }
355 bool ContentsEqual(const std::wstring& filename1, 257 bool ContentsEqual(const std::wstring& filename1,
356 const std::wstring& filename2) { 258 const std::wstring& filename2) {
357 return ContentsEqual(FilePath::FromWStringHack(filename1), 259 return ContentsEqual(FilePath::FromWStringHack(filename1),
358 FilePath::FromWStringHack(filename2)); 260 FilePath::FromWStringHack(filename2));
359 } 261 }
262 bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
263 return CopyFile(FilePath::FromWStringHack(from_path),
264 FilePath::FromWStringHack(to_path));
265 }
360 bool CreateDirectory(const std::wstring& full_path) { 266 bool CreateDirectory(const std::wstring& full_path) {
361 return CreateDirectory(FilePath::FromWStringHack(full_path)); 267 return CreateDirectory(FilePath::FromWStringHack(full_path));
362 } 268 }
363 bool CreateTemporaryFileName(std::wstring* temp_file) { 269 bool CreateTemporaryFileName(std::wstring* temp_file) {
364 FilePath temp_file_path; 270 FilePath temp_file_path;
365 if (!CreateTemporaryFileName(&temp_file_path)) 271 if (!CreateTemporaryFileName(&temp_file_path))
366 return false; 272 return false;
367 *temp_file = temp_file_path.ToWStringHack(); 273 *temp_file = temp_file_path.ToWStringHack();
368 return true; 274 return true;
369 } 275 }
276 bool Delete(const std::wstring& path, bool recursive) {
277 return Delete(FilePath::FromWStringHack(path), recursive);
278 }
279 bool DirectoryExists(const std::wstring& path) {
280 return DirectoryExists(FilePath::FromWStringHack(path));
281 }
282 bool EndsWithSeparator(std::wstring* path) {
283 return EndsWithSeparator(FilePath::FromWStringHack(*path));
284 }
285 bool EndsWithSeparator(const std::wstring& path) {
286 return EndsWithSeparator(FilePath::FromWStringHack(path));
287 }
370 bool GetCurrentDirectory(std::wstring* path_str) { 288 bool GetCurrentDirectory(std::wstring* path_str) {
371 FilePath path; 289 FilePath path;
372 if (!GetCurrentDirectory(&path)) 290 if (!GetCurrentDirectory(&path))
373 return false; 291 return false;
374 *path_str = path.ToWStringHack(); 292 *path_str = path.ToWStringHack();
375 return true; 293 return true;
376 } 294 }
377 bool GetFileInfo(const std::wstring& file_path, FileInfo* results) { 295 bool GetFileInfo(const std::wstring& file_path, FileInfo* results) {
378 return GetFileInfo(FilePath::FromWStringHack(file_path), results); 296 return GetFileInfo(FilePath::FromWStringHack(file_path), results);
379 } 297 }
380 bool GetFileSize(const std::wstring& file_path, int64* file_size) { 298 bool GetFileSize(const std::wstring& file_path, int64* file_size) {
381 return GetFileSize(FilePath::FromWStringHack(file_path), file_size); 299 return GetFileSize(FilePath::FromWStringHack(file_path), file_size);
382 } 300 }
383 bool GetTempDir(std::wstring* path_str) { 301 bool GetTempDir(std::wstring* path_str) {
384 FilePath path; 302 FilePath path;
385 if (!GetTempDir(&path)) 303 if (!GetTempDir(&path))
386 return false; 304 return false;
387 *path_str = path.ToWStringHack(); 305 *path_str = path.ToWStringHack();
388 return true; 306 return true;
389 } 307 }
308 bool Move(const std::wstring& from_path, const std::wstring& to_path) {
309 return Move(FilePath::FromWStringHack(from_path),
310 FilePath::FromWStringHack(to_path));
311 }
390 FILE* OpenFile(const std::wstring& filename, const char* mode) { 312 FILE* OpenFile(const std::wstring& filename, const char* mode) {
391 return OpenFile(FilePath::FromWStringHack(filename), mode); 313 return OpenFile(FilePath::FromWStringHack(filename), mode);
392 } 314 }
315 bool PathExists(const std::wstring& path) {
316 return PathExists(FilePath::FromWStringHack(path));
317 }
393 bool SetCurrentDirectory(const std::wstring& directory) { 318 bool SetCurrentDirectory(const std::wstring& directory) {
394 return SetCurrentDirectory(FilePath::FromWStringHack(directory)); 319 return SetCurrentDirectory(FilePath::FromWStringHack(directory));
395 } 320 }
321 void TrimFilename(std::wstring* path) {
322 if (EndsWithSeparator(path)) {
323 TrimTrailingSeparator(path);
324 } else {
325 *path = FilePath::FromWStringHack(*path).DirName().ToWStringHack();
326 }
327 }
328 void UpOneDirectory(std::wstring* dir) {
329 FilePath path = FilePath::FromWStringHack(*dir);
330 *dir = path.DirName().ToWStringHack();
331 }
332 void UpOneDirectoryOrEmpty(std::wstring* dir) {
333 FilePath path = FilePath::FromWStringHack(*dir);
334 FilePath directory = path.DirName();
396 335
336 if (directory == path)
337 dir->clear();
338 else
339 *dir = directory.ToWStringHack();
340 }
397 } // namespace 341 } // namespace
398 342
OLDNEW
« no previous file with comments | « base/file_util.h ('k') | base/file_util_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698