Move file enumeration to filepaths.
Review URL: http://codereview.chromium.org/13315
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6784 0039d316-1c4b-4281-b951-d872f2087c98
CrOS-Libchrome-Original-Commit: 0b733220c5fbef986647fce040c1b5d5e48be2b6
diff --git a/base/file_path.cc b/base/file_path.cc
index 0856029..a938ca6 100644
--- a/base/file_path.cc
+++ b/base/file_path.cc
@@ -77,7 +77,7 @@
// adhere to their behavior.
FilePath FilePath::DirName() const {
FilePath new_path(path_);
- new_path.StripTrailingSeparators();
+ new_path.StripTrailingSeparatorsInternal();
// The drive letter, if any, always needs to remain in the output. If there
// is no drive letter, as will always be the case on platforms which do not
@@ -104,7 +104,7 @@
new_path.path_.resize(last_separator);
}
- new_path.StripTrailingSeparators();
+ new_path.StripTrailingSeparatorsInternal();
if (!new_path.path_.length())
new_path.path_ = kCurrentDirectory;
@@ -113,7 +113,7 @@
FilePath FilePath::BaseName() const {
FilePath new_path(path_);
- new_path.StripTrailingSeparators();
+ new_path.StripTrailingSeparatorsInternal();
// The drive letter, if any, is always stripped.
StringType::size_type letter = FindDriveLetter(new_path.path_);
@@ -148,7 +148,7 @@
}
FilePath new_path(path_);
- new_path.StripTrailingSeparators();
+ new_path.StripTrailingSeparatorsInternal();
// Don't append a separator if the path is empty (indicating the current
// directory) or if the path component is empty (indicating nothing to
@@ -201,7 +201,14 @@
}
#endif
-void FilePath::StripTrailingSeparators() {
+FilePath FilePath::StripTrailingSeparators() const {
+ FilePath new_path(path_);
+ new_path.StripTrailingSeparatorsInternal();
+
+ return new_path;
+}
+
+void FilePath::StripTrailingSeparatorsInternal() {
// If there is no drive letter, start will be 1, which will prevent stripping
// the leading separator if there is only one separator. If there is a drive
// letter, start will be set appropriately to prevent stripping the first
diff --git a/base/file_path.h b/base/file_path.h
index fb2cc57..9049176 100644
--- a/base/file_path.h
+++ b/base/file_path.h
@@ -67,8 +67,8 @@
#include <string>
-#include "base/compiler_specific.h"
#include "base/basictypes.h"
+#include "base/compiler_specific.h"
// Windows-style drive letter support and pathname separator characters can be
// enabled and disabled independently, to aid testing. These #defines are
@@ -121,6 +121,11 @@
return path_ == that.path_;
}
+ // Required for some STL containers and operations
+ bool operator<(const FilePath& that) const {
+ return path_ < that.path_;
+ }
+
const StringType& value() const { return path_; }
// Returns true if |character| is in kSeparators.
@@ -154,6 +159,10 @@
// platforms, an absolute path begins with a separator character.
bool IsAbsolute() const;
+ // Returns a copy of this FilePath that does not end with a trailing
+ // separator.
+ FilePath StripTrailingSeparators() const;
+
// Older Chromium code assumes that paths are always wstrings.
// This function converts a wstring to a FilePath, and is useful to smooth
// porting that old code to the FilePath API.
@@ -174,7 +183,7 @@
// directory, so "////" will become "/", not "". A leading pair of
// separators is never stripped, to support alternate roots. This is used to
// support UNC paths on Windows.
- void StripTrailingSeparators();
+ void StripTrailingSeparatorsInternal();
StringType path_;
};
diff --git a/base/file_util.h b/base/file_util.h
index 41bc70b..7bc7e82 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -51,6 +51,8 @@
bool EnsureEndsWithSeparator(FilePath* path);
// Modifies a string by trimming all trailing separators from the end.
+// Deprecated. FilePath does this automatically, and if it's constructed from a
+// path with a trailing separator, StripTrailingSeparators() may be used.
void TrimTrailingSeparator(std::wstring* dir);
// Strips the topmost directory from the end of 'dir'. Assumes 'dir' does not
@@ -373,26 +375,26 @@
// NOTE: the pattern only matches the contents of root_path, not files in
// recursive subdirectories.
// TODO(erikkay): Fix the pattern matching to work at all levels.
- FileEnumerator(const std::wstring& root_path,
+ FileEnumerator(const FilePath& root_path,
bool recursive,
FileEnumerator::FILE_TYPE file_type);
- FileEnumerator(const std::wstring& root_path,
+ FileEnumerator(const FilePath& root_path,
bool recursive,
FileEnumerator::FILE_TYPE file_type,
- const std::wstring& pattern);
+ const FilePath::StringType& pattern);
~FileEnumerator();
// Returns an empty string if there are no more results.
- std::wstring Next();
+ FilePath Next();
// Write the file info into |info|.
void GetFindInfo(FindInfo* info);
private:
- std::wstring root_path_;
+ FilePath root_path_;
bool recursive_;
FILE_TYPE file_type_;
- std::wstring pattern_; // Empty when we want to find everything.
+ FilePath pattern_; // Empty when we want to find everything.
// Set to true when there is a find operation open. This way, we can lazily
// start the operations when the caller calls Next().
@@ -400,7 +402,7 @@
// A stack that keeps track of which subdirectories we still need to
// enumerate in the breadth-first search.
- std::stack<std::wstring> pending_paths_;
+ std::stack<FilePath> pending_paths_;
#if defined(OS_WIN)
WIN32_FIND_DATA find_data_;
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 5760a68..153f70a 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -378,7 +378,7 @@
return !ret;
}
-FileEnumerator::FileEnumerator(const std::wstring& root_path,
+FileEnumerator::FileEnumerator(const FilePath& root_path,
bool recursive,
FileEnumerator::FILE_TYPE file_type)
: recursive_(recursive),
@@ -388,19 +388,19 @@
pending_paths_.push(root_path);
}
-FileEnumerator::FileEnumerator(const std::wstring& root_path,
+FileEnumerator::FileEnumerator(const FilePath& root_path,
bool recursive,
FileEnumerator::FILE_TYPE file_type,
- const std::wstring& pattern)
+ const FilePath::StringType& pattern)
: recursive_(recursive),
file_type_(file_type),
- pattern_(root_path),
+ pattern_(root_path.value()),
is_in_find_op_(false),
fts_(NULL) {
// The Windows version of this code only matches against items in the top-most
// directory, and we're comparing fnmatch against full paths, so this is the
// easiest way to get the right pattern.
- AppendToPath(&pattern_, pattern);
+ pattern_ = pattern_.Append(pattern);
pending_paths_.push(root_path);
}
@@ -423,20 +423,20 @@
// the fts enumeration doesn't match (type, pattern, etc.). In the case of
// large directories with many files this can be quite deep.
// TODO(erikkay) - get rid of this recursive pattern
-std::wstring FileEnumerator::Next() {
+FilePath FileEnumerator::Next() {
if (!is_in_find_op_) {
if (pending_paths_.empty())
- return std::wstring();
+ return FilePath();
// The last find FindFirstFile operation is done, prepare a new one.
root_path_ = pending_paths_.top();
- TrimTrailingSeparator(&root_path_);
+ root_path_ = root_path_.StripTrailingSeparators();
pending_paths_.pop();
// Start a new find operation.
int ftsflags = FTS_LOGICAL;
char top_dir[PATH_MAX];
- base::strlcpy(top_dir, WideToUTF8(root_path_).c_str(), sizeof(top_dir));
+ base::strlcpy(top_dir, root_path_.value().c_str(), sizeof(top_dir));
char* dir_list[2] = { top_dir, NULL };
fts_ = fts_open(dir_list, ftsflags, NULL);
if (!fts_)
@@ -458,15 +458,15 @@
// Patterns are only matched on the items in the top-most directory.
// (see Windows implementation)
- if (fts_ent_->fts_level == 1 && pattern_.length() > 0) {
- if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent_->fts_path, 0) != 0) {
+ if (fts_ent_->fts_level == 1 && pattern_.value().length() > 0) {
+ if (fnmatch(pattern_.value().c_str(), fts_ent_->fts_path, 0) != 0) {
if (fts_ent_->fts_info == FTS_D)
fts_set(fts_, fts_ent_, FTS_SKIP);
return Next();
}
}
- std::wstring cur_file(UTF8ToWide(fts_ent_->fts_path));
+ FilePath cur_file(fts_ent_->fts_path);
if (fts_ent_->fts_info == FTS_D) {
// If not recursive, then prune children.
if (!recursive_)
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 4c7743a..a8855e9 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -55,9 +55,9 @@
class FindResultCollector {
public:
FindResultCollector(file_util::FileEnumerator& enumerator) {
- std::wstring cur_file;
- while (!(cur_file = enumerator.Next()).empty()) {
- FilePath::StringType path = FilePath::FromWStringHack(cur_file).value();
+ FilePath cur_file;
+ while (!(cur_file = enumerator.Next()).value().empty()) {
+ FilePath::StringType path = cur_file.value();
// The file should not be returned twice.
EXPECT_TRUE(files_.end() == files_.find(path))
<< "Same file returned twice";
@@ -830,10 +830,10 @@
TEST_F(FileUtilTest, FileEnumeratorTest) {
// Test an empty directory.
- file_util::FileEnumerator f0(test_dir_.ToWStringHack(), true,
+ file_util::FileEnumerator f0(test_dir_, true,
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
- EXPECT_EQ(f0.Next(), L"");
- EXPECT_EQ(f0.Next(), L"");
+ EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL(""));
+ EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL(""));
// create the directories
FilePath dir1 = test_dir_.Append(FILE_PATH_LITERAL("dir1"));
@@ -857,7 +857,7 @@
FilePath file2_abs = test_dir_.Append(FILE_PATH_LITERAL("file2.txt"));
// Only enumerate files.
- file_util::FileEnumerator f1(test_dir_.ToWStringHack(), true,
+ file_util::FileEnumerator f1(test_dir_, true,
file_util::FileEnumerator::FILES);
FindResultCollector c1(f1);
EXPECT_TRUE(c1.HasFile(file1));
@@ -867,7 +867,7 @@
EXPECT_EQ(c1.size(), 4);
// Only enumerate directories.
- file_util::FileEnumerator f2(test_dir_.ToWStringHack(), true,
+ file_util::FileEnumerator f2(test_dir_, true,
file_util::FileEnumerator::DIRECTORIES);
FindResultCollector c2(f2);
EXPECT_TRUE(c2.HasFile(dir1));
@@ -877,14 +877,14 @@
// Only enumerate directories non-recursively.
file_util::FileEnumerator f2_non_recursive(
- test_dir_.ToWStringHack(), false, file_util::FileEnumerator::DIRECTORIES);
+ test_dir_, false, file_util::FileEnumerator::DIRECTORIES);
FindResultCollector c2_non_recursive(f2_non_recursive);
EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
EXPECT_EQ(c2_non_recursive.size(), 2);
// Enumerate files and directories.
- file_util::FileEnumerator f3(test_dir_.ToWStringHack(), true,
+ file_util::FileEnumerator f3(test_dir_, true,
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
FindResultCollector c3(f3);
EXPECT_TRUE(c3.HasFile(dir1));
@@ -897,7 +897,7 @@
EXPECT_EQ(c3.size(), 7);
// Non-recursive operation.
- file_util::FileEnumerator f4(test_dir_.ToWStringHack(), false,
+ file_util::FileEnumerator f4(test_dir_, false,
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
FindResultCollector c4(f4);
EXPECT_TRUE(c4.HasFile(dir2));
@@ -907,8 +907,9 @@
EXPECT_EQ(c4.size(), 4);
// Enumerate with a pattern.
- file_util::FileEnumerator f5(test_dir_.ToWStringHack(), true,
- file_util::FileEnumerator::FILES_AND_DIRECTORIES, L"dir*");
+ file_util::FileEnumerator f5(test_dir_, true,
+ file_util::FileEnumerator::FILES_AND_DIRECTORIES,
+ FILE_PATH_LITERAL("dir*"));
FindResultCollector c5(f5);
EXPECT_TRUE(c5.HasFile(dir1));
EXPECT_TRUE(c5.HasFile(dir2));
@@ -919,10 +920,10 @@
// Make sure the destructor closes the find handle while in the middle of a
// query to allow TearDown to delete the directory.
- file_util::FileEnumerator f6(test_dir_.ToWStringHack(), true,
+ file_util::FileEnumerator f6(test_dir_, true,
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
- EXPECT_FALSE(f6.Next().empty()); // Should have found something
- // (we don't care what).
+ EXPECT_FALSE(f6.Next().value().empty()); // Should have found something
+ // (we don't care what).
}