diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/file_util.cc | 66 | ||||
-rw-r--r-- | base/file_util.h | 22 | ||||
-rw-r--r-- | base/file_util_unittest.cc | 120 | ||||
-rw-r--r-- | base/file_util_win.cc | 75 |
4 files changed, 142 insertions, 141 deletions
diff --git a/base/file_util.cc b/base/file_util.cc index 187e7b0..10e08d5 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -16,6 +16,12 @@ #include "base/string_piece.h" #include "base/sys_string_conversions.h" +namespace { + +const FilePath::CharType kExtensionSeparator = FILE_PATH_LITERAL('.'); + +} + namespace file_util { void PathComponents(const FilePath& path, @@ -73,13 +79,6 @@ void TrimTrailingSeparator(std::wstring* dir) { dir->resize(dir->length() - 1); } -std::wstring GetFilenameFromPath(const std::wstring& path) { - // TODO(erikkay): fix this - it's not using kPathSeparator, but win unit test - // are exercising '/' as a path separator as well. - std::wstring::size_type pos = path.find_last_of(L"\\/"); - return std::wstring(path, pos == std::wstring::npos ? 0 : pos + 1); -} - std::wstring GetFileExtensionFromPath(const std::wstring& path) { std::wstring file_name = GetFilenameFromPath(path); std::wstring::size_type last_dot = file_name.rfind(L'.'); @@ -94,6 +93,53 @@ std::wstring GetFilenameWithoutExtensionFromPath(const std::wstring& path) { return file_name.substr(0, last_dot); } +void InsertBeforeExtension(FilePath* path, const FilePath::StringType& suffix) { + FilePath::StringType& value = + const_cast<FilePath::StringType&>(path->value()); + + const FilePath::StringType::size_type last_dot = + value.rfind(kExtensionSeparator); + const FilePath::StringType::size_type last_separator = + value.find_last_of(FilePath::StringType(FilePath::kSeparators)); + + if (last_dot == FilePath::StringType::npos || + (last_separator != std::wstring::npos && last_dot < last_separator)) { + // The path looks something like "C:\pics.old\jojo" or "C:\pics\jojo". + // We should just append the suffix to the entire path. + value.append(suffix); + return; + } + + value.insert(last_dot, suffix); +} + +void ReplaceExtension(FilePath* path, const FilePath::StringType& extension) { + FilePath::StringType clean_extension; + // If the new extension is "" or ".", then we will just remove the current + // extension. + if (!extension.empty() && + extension != FilePath::StringType(&kExtensionSeparator, 1)) { + if (extension[0] != kExtensionSeparator) + clean_extension.append(&kExtensionSeparator, 1); + clean_extension.append(extension); + } + + FilePath::StringType& value = + const_cast<FilePath::StringType&>(path->value()); + const FilePath::StringType::size_type last_dot = + value.rfind(kExtensionSeparator); + const FilePath::StringType::size_type last_separator = + value.find_last_of(FilePath::StringType(FilePath::kSeparators)); + + // Erase the current extension, if any. + if ((last_dot > last_separator || + last_separator == FilePath::StringType::npos) && + last_dot != FilePath::StringType::npos) + value.erase(last_dot); + + value.append(clean_extension); +} + void ReplaceIllegalCharacters(std::wstring* file_name, int replace_char) { DCHECK(file_name); @@ -295,6 +341,12 @@ bool GetCurrentDirectory(std::wstring* path_str) { bool GetFileInfo(const std::wstring& file_path, FileInfo* results) { return GetFileInfo(FilePath::FromWStringHack(file_path), results); } +std::wstring GetFilenameFromPath(const std::wstring& path) { + if (path.empty() || EndsWithSeparator(path)) + return std::wstring(); + + return FilePath::FromWStringHack(path).BaseName().ToWStringHack(); +} bool GetFileSize(const std::wstring& file_path, int64* file_size) { return GetFileSize(FilePath::FromWStringHack(file_path), file_size); } diff --git a/base/file_util.h b/base/file_util.h index eebf3af..41bc70b 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -29,16 +29,6 @@ namespace file_util { //----------------------------------------------------------------------------- -// Constants - -#if defined(OS_WIN) -// The use of this constant is deprecated. Instead use file_util or FilePath -// functions (Append, TrimTrailingSeparator, etc.), or use -// FilePath::kSeparator[0]. -extern const wchar_t kPathSeparator; -#endif - -//----------------------------------------------------------------------------- // Functions that operate purely on a path string w/o touching the filesystem: // Returns a vector of all of the components of the provided path. @@ -80,6 +70,7 @@ void UpOneDirectoryOrEmpty(std::wstring* dir); void TrimFilename(std::wstring* path); // Returns the filename portion of 'path', without any leading \'s or /'s. +// Deprecated. Use FilePath::BaseName instead. std::wstring GetFilenameFromPath(const std::wstring& path); // Returns "jpg" for path "C:\pics\jojo.jpg", or an empty string if @@ -109,9 +100,6 @@ bool AbsolutePath(FilePath* path); // Deprecated temporary compatibility function. bool AbsolutePath(std::wstring* path); -// TODO(port): create FilePath versions of these functions, and remove this -// platform define. -#if defined(OS_WIN) // Inserts |suffix| after the file name portion of |path| but before the // extension. // Examples: @@ -119,11 +107,17 @@ bool AbsolutePath(std::wstring* path); // path == "jojo.jpg" suffix == " (1)", returns "jojo (1).jpg" // path == "C:\pics\jojo" suffix == " (1)", returns "C:\pics\jojo (1)" // path == "C:\pics.old\jojo" suffix == " (1)", returns "C:\pics.old\jojo (1)" -void InsertBeforeExtension(std::wstring* path, const std::wstring& suffix); +void InsertBeforeExtension(FilePath* path, const FilePath::StringType& suffix); // Replaces the extension of |file_name| with |extension|. If |file_name| // does not have an extension, them |extension| is added. If |extension| is // empty, then the extension is removed from |file_name|. +void ReplaceExtension(FilePath* file_name, + const FilePath::StringType& extension); + +#if defined(OS_WIN) +// Deprecated temporary compatibility functions. +void InsertBeforeExtension(std::wstring* path, const std::wstring& suffix); void ReplaceExtension(std::wstring* file_name, const std::wstring& extension); #endif diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc index 3a4962d..4c7743a 100644 --- a/base/file_util_unittest.cc +++ b/base/file_util_unittest.cc @@ -147,29 +147,27 @@ TEST_F(FileUtilTest, AppendToPath) { #endif } -// TODO(port): enable this test for non-Windows. -#if defined(OS_WIN) static const struct InsertBeforeExtensionCase { std::wstring path; - std::wstring suffix; + FilePath::StringType suffix; std::wstring result; } kInsertBeforeExtension[] = { - {L"", L"", L""}, - {L"", L"txt", L"txt"}, - {L".", L"txt", L"txt."}, - {L".", L"", L"."}, - {L"foo.dll", L"txt", L"footxt.dll"}, - {L"foo.dll", L".txt", L"foo.txt.dll"}, - {L"foo", L"txt", L"footxt"}, - {L"foo", L".txt", L"foo.txt"}, - {L"foo.baz.dll", L"txt", L"foo.baztxt.dll"}, - {L"foo.baz.dll", L".txt", L"foo.baz.txt.dll"}, - {L"foo.dll", L"", L"foo.dll"}, - {L"foo.dll", L".", L"foo..dll"}, - {L"foo", L"", L"foo"}, - {L"foo", L".", L"foo."}, - {L"foo.baz.dll", L"", L"foo.baz.dll"}, - {L"foo.baz.dll", L".", L"foo.baz..dll"}, + {L"", FILE_PATH_LITERAL(""), L""}, + {L"", FILE_PATH_LITERAL("txt"), L"txt"}, + {L".", FILE_PATH_LITERAL("txt"), L"txt."}, + {L".", FILE_PATH_LITERAL(""), L"."}, + {L"foo.dll", FILE_PATH_LITERAL("txt"), L"footxt.dll"}, + {L"foo.dll", FILE_PATH_LITERAL(".txt"), L"foo.txt.dll"}, + {L"foo", FILE_PATH_LITERAL("txt"), L"footxt"}, + {L"foo", FILE_PATH_LITERAL(".txt"), L"foo.txt"}, + {L"foo.baz.dll", FILE_PATH_LITERAL("txt"), L"foo.baztxt.dll"}, + {L"foo.baz.dll", FILE_PATH_LITERAL(".txt"), L"foo.baz.txt.dll"}, + {L"foo.dll", FILE_PATH_LITERAL(""), L"foo.dll"}, + {L"foo.dll", FILE_PATH_LITERAL("."), L"foo..dll"}, + {L"foo", FILE_PATH_LITERAL(""), L"foo"}, + {L"foo", FILE_PATH_LITERAL("."), L"foo."}, + {L"foo.baz.dll", FILE_PATH_LITERAL(""), L"foo.baz.dll"}, + {L"foo.baz.dll", FILE_PATH_LITERAL("."), L"foo.baz..dll"}, #if defined(OS_WIN) {L"\\", L"", L"\\"}, {L"\\", L"txt", L"\\txt"}, @@ -184,29 +182,28 @@ static const struct InsertBeforeExtensionCase { {L"C:\\bar.baz\\foo.dll.exe", L"", L"C:\\bar.baz\\foo.dll.exe"}, {L"C:\\bar\\baz\\foo.exe", L" (1)", L"C:\\bar\\baz\\foo (1).exe"}, #elif defined(OS_POSIX) - {L"/", L"", L"/"}, - {L"/", L"txt", L"/txt"}, - {L"/.", L"txt", L"/txt."}, - {L"/.", L"", L"/."}, - {L"/bar/foo.dll", L"txt", L"/bar/footxt.dll"}, - {L"/bar.baz/foodll", L"txt", L"/bar.baz/foodlltxt"}, - {L"/bar.baz/foo.dll", L"txt", L"/bar.baz/footxt.dll"}, - {L"/bar.baz/foo.dll.exe", L"txt", L"/bar.baz/foo.dlltxt.exe"}, - {L"/bar.baz/foo", L"", L"/bar.baz/foo"}, - {L"/bar.baz/foo.exe", L"", L"/bar.baz/foo.exe"}, - {L"/bar.baz/foo.dll.exe", L"", L"/bar.baz/foo.dll.exe"}, - {L"/bar/baz/foo.exe", L" (1)", L"/bar/baz/foo (1).exe"}, + {L"/", "", L"/"}, + {L"/", "txt", L"/txt"}, + {L"/.", "txt", L"/txt."}, + {L"/.", "", L"/."}, + {L"/bar/foo.dll", "txt", L"/bar/footxt.dll"}, + {L"/bar.baz/foodll", "txt", L"/bar.baz/foodlltxt"}, + {L"/bar.baz/foo.dll", "txt", L"/bar.baz/footxt.dll"}, + {L"/bar.baz/foo.dll.exe", "txt", L"/bar.baz/foo.dlltxt.exe"}, + {L"/bar.baz/foo", "", L"/bar.baz/foo"}, + {L"/bar.baz/foo.exe", "", L"/bar.baz/foo.exe"}, + {L"/bar.baz/foo.dll.exe", "", L"/bar.baz/foo.dll.exe"}, + {L"/bar/baz/foo.exe", " (1)", L"/bar/baz/foo (1).exe"}, #endif }; TEST_F(FileUtilTest, InsertBeforeExtensionTest) { for (unsigned int i = 0; i < arraysize(kInsertBeforeExtension); ++i) { - std::wstring path(kInsertBeforeExtension[i].path); + FilePath path = FilePath::FromWStringHack(kInsertBeforeExtension[i].path); file_util::InsertBeforeExtension(&path, kInsertBeforeExtension[i].suffix); - EXPECT_EQ(path, kInsertBeforeExtension[i].result); + EXPECT_EQ(kInsertBeforeExtension[i].result, path.ToWStringHack()); } } -#endif // defined(OS_WIN) static const struct filename_case { const wchar_t* path; @@ -788,51 +785,48 @@ TEST_F(FileUtilTest, ReplaceIllegalCharactersTest) { } } -// TODO(port): enable this test for non-windows. -#if defined(OS_WIN) static const struct ReplaceExtensionCase { std::wstring file_name; - std::wstring extension; + FilePath::StringType extension; std::wstring result; } kReplaceExtension[] = { - {L"", L"", L""}, - {L"", L"txt", L".txt"}, - {L".", L"txt", L".txt"}, - {L".", L"", L""}, - {L"foo.dll", L"txt", L"foo.txt"}, - {L"foo.dll", L".txt", L"foo.txt"}, - {L"foo", L"txt", L"foo.txt"}, - {L"foo", L".txt", L"foo.txt"}, - {L"foo.baz.dll", L"txt", L"foo.baz.txt"}, - {L"foo.baz.dll", L".txt", L"foo.baz.txt"}, - {L"foo.dll", L"", L"foo"}, - {L"foo.dll", L".", L"foo"}, - {L"foo", L"", L"foo"}, - {L"foo", L".", L"foo"}, - {L"foo.baz.dll", L"", L"foo.baz"}, - {L"foo.baz.dll", L".", L"foo.baz"}, + {L"", FILE_PATH_LITERAL(""), L""}, + {L"", FILE_PATH_LITERAL("txt"), L".txt"}, + {L".", FILE_PATH_LITERAL("txt"), L".txt"}, + {L".", FILE_PATH_LITERAL(""), L""}, + {L"foo.dll", FILE_PATH_LITERAL("txt"), L"foo.txt"}, + {L"foo.dll", FILE_PATH_LITERAL(".txt"), L"foo.txt"}, + {L"foo", FILE_PATH_LITERAL("txt"), L"foo.txt"}, + {L"foo", FILE_PATH_LITERAL(".txt"), L"foo.txt"}, + {L"foo.baz.dll", FILE_PATH_LITERAL("txt"), L"foo.baz.txt"}, + {L"foo.baz.dll", FILE_PATH_LITERAL(".txt"), L"foo.baz.txt"}, + {L"foo.dll", FILE_PATH_LITERAL(""), L"foo"}, + {L"foo.dll", FILE_PATH_LITERAL("."), L"foo"}, + {L"foo", FILE_PATH_LITERAL(""), L"foo"}, + {L"foo", FILE_PATH_LITERAL("."), L"foo"}, + {L"foo.baz.dll", FILE_PATH_LITERAL(""), L"foo.baz"}, + {L"foo.baz.dll", FILE_PATH_LITERAL("."), L"foo.baz"}, }; TEST_F(FileUtilTest, ReplaceExtensionTest) { for (unsigned int i = 0; i < arraysize(kReplaceExtension); ++i) { - std::wstring file_name(kReplaceExtension[i].file_name); - file_util::ReplaceExtension(&file_name, kReplaceExtension[i].extension); - EXPECT_EQ(file_name, kReplaceExtension[i].result); + FilePath path = FilePath::FromWStringHack(kReplaceExtension[i].file_name); + file_util::ReplaceExtension(&path, kReplaceExtension[i].extension); + EXPECT_EQ(kReplaceExtension[i].result, path.ToWStringHack()); } } // Make sure ReplaceExtension doesn't replace an extension that occurs as one of // the directory names of the path. TEST_F(FileUtilTest, ReplaceExtensionTestWithPathSeparators) { - std::wstring path; - file_util::AppendToPath(&path, L"foo.bar"); - file_util::AppendToPath(&path, L"foo"); + FilePath path; + path = path.Append(FILE_PATH_LITERAL("foo.bar")); + path = path.Append(FILE_PATH_LITERAL("foo")); // '/foo.bar/foo' with extension '.baz' - std::wstring result_path = path; - file_util::ReplaceExtension(&result_path, L".baz"); - EXPECT_EQ(path + L".baz", result_path); + FilePath result_path = path; + file_util::ReplaceExtension(&result_path, FILE_PATH_LITERAL(".baz")); + EXPECT_EQ(path.ToWStringHack() + L".baz", result_path.ToWStringHack()); } -#endif // defined(OS_WIN) TEST_F(FileUtilTest, FileEnumeratorTest) { // Test an empty directory. diff --git a/base/file_util_win.cc b/base/file_util_win.cc index c107711..c32c87d 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -18,14 +18,6 @@ namespace file_util { -const wchar_t kPathSeparator = L'\\'; -const wchar_t kExtensionSeparator = L'.'; - -void PathComponents(const std::wstring& path, - std::vector<std::wstring>* components) { - PathComponents(FilePath(path), components); -} - std::wstring GetDirectoryFromPath(const std::wstring& path) { wchar_t path_buffer[MAX_PATH]; wchar_t* file_ptr = NULL; @@ -47,55 +39,6 @@ bool AbsolutePath(FilePath* path) { return true; } -void InsertBeforeExtension(std::wstring* path, const std::wstring& suffix) { - DCHECK(path); - - const std::wstring::size_type last_dot = path->rfind(kExtensionSeparator); - const std::wstring::size_type last_sep = path->rfind(kPathSeparator); - - if (last_dot == std::wstring::npos || - (last_sep != std::wstring::npos && last_dot < last_sep)) { - // The path looks something like "C:\pics.old\jojo" or "C:\pics\jojo". - // We should just append the suffix to the entire path. - path->append(suffix); - return; - } - - path->insert(last_dot, suffix); -} - -// Appends the extension to file adding a '.' if extension doesn't contain one. -// This does nothing if extension is empty or '.'. This is used internally by -// ReplaceExtension. -static void AppendExtension(const std::wstring& extension, - std::wstring* file) { - if (!extension.empty() && extension != L".") { - if (extension[0] != L'.') - file->append(L"."); - file->append(extension); - } -} - -void ReplaceExtension(std::wstring* file_name, const std::wstring& extension) { - const std::wstring::size_type last_dot = file_name->rfind(L'.'); - if (last_dot == std::wstring::npos) { - // No extension, just append the supplied extension. - AppendExtension(extension, file_name); - return; - } - const std::wstring::size_type last_separator = - file_name->rfind(kPathSeparator); - if (last_separator != std::wstring::npos && last_dot < last_separator) { - // File name doesn't have extension, but one of the directories does; don't - // replace it, just append the supplied extension. For example - // 'c:\tmp.bar\foo'. - AppendExtension(extension, file_name); - return; - } - std::wstring result = file_name->substr(0, last_dot); - AppendExtension(extension, &result); - file_name->swap(result); -} int CountFilesCreatedAfter(const std::wstring& path, const FILETIME& comparison_time) { int file_count = 0; @@ -751,4 +694,22 @@ std::wstring FileEnumerator::Next() { } return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); } + +// Deprecated functions ---------------------------------------------------- + +void InsertBeforeExtension(std::wstring* path_str, + const std::wstring& suffix) { + FilePath path(*path_str); + InsertBeforeExtension(&path, suffix); + path_str->assign(path.value()); +} +void PathComponents(const std::wstring& path, + std::vector<std::wstring>* components) { + PathComponents(FilePath(path), components); +} +void ReplaceExtension(std::wstring* file_name, const std::wstring& extension) { + FilePath path(*file_name); + ReplaceExtension(&path, extension); + file_name->assign(path.value()); +} } // namespace file_util |