| Index: net/base/directory_lister.cc
|
| ===================================================================
|
| --- net/base/directory_lister.cc (revision 56913)
|
| +++ net/base/directory_lister.cc (working copy)
|
| @@ -17,8 +17,9 @@
|
|
|
| static const int kFilesPerEvent = 8;
|
|
|
| +// A task which is used to signal the delegate asynchronously.
|
| class DirectoryDataEvent : public Task {
|
| - public:
|
| +public:
|
| explicit DirectoryDataEvent(DirectoryLister* d) : lister(d), error(0) {
|
| // Allocations of the FindInfo aren't super cheap, so reserve space.
|
| data.reserve(64);
|
| @@ -33,70 +34,85 @@
|
| }
|
|
|
| scoped_refptr<DirectoryLister> lister;
|
| - std::vector<file_util::FileEnumerator::FindInfo> data;
|
| + std::vector<DirectoryLister::DirectoryListerData> data;
|
| int error;
|
| };
|
|
|
| -// Comparator for sorting FindInfo's. This uses the locale aware filename
|
| +// Comparator for sorting lister results. This uses the locale aware filename
|
| // comparison function on the filenames for sorting in the user's locale.
|
| -static bool CompareFindInfoAlpha(const file_util::FileEnumerator::FindInfo& a,
|
| - const file_util::FileEnumerator::FindInfo& b) {
|
| +// Static.
|
| +bool DirectoryLister::CompareAlphaDirsFirst(const DirectoryListerData& a,
|
| + const DirectoryListerData& b) {
|
| // Parent directory before all else.
|
| - if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a)))
|
| + if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a.info)))
|
| return true;
|
| - if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b)))
|
| + if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b.info)))
|
| return false;
|
|
|
| // Directories before regular files.
|
| - bool a_is_directory = file_util::FileEnumerator::IsDirectory(a);
|
| - bool b_is_directory = file_util::FileEnumerator::IsDirectory(b);
|
| + bool a_is_directory = file_util::FileEnumerator::IsDirectory(a.info);
|
| + bool b_is_directory = file_util::FileEnumerator::IsDirectory(b.info);
|
| if (a_is_directory != b_is_directory)
|
| return a_is_directory;
|
|
|
| return file_util::LocaleAwareCompareFilenames(
|
| - file_util::FileEnumerator::GetFilename(a),
|
| - file_util::FileEnumerator::GetFilename(b));
|
| + file_util::FileEnumerator::GetFilename(a.info),
|
| + file_util::FileEnumerator::GetFilename(b.info));
|
| }
|
|
|
| -static bool CompareFindInfoDate(const file_util::FileEnumerator::FindInfo& a,
|
| - const file_util::FileEnumerator::FindInfo& b) {
|
| +// Static.
|
| +bool DirectoryLister::CompareDate(const DirectoryListerData& a,
|
| + const DirectoryListerData& b) {
|
| // Parent directory before all else.
|
| - if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a)))
|
| + if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a.info)))
|
| return true;
|
| - if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b)))
|
| + if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b.info)))
|
| return false;
|
|
|
| // Directories before regular files.
|
| - bool a_is_directory = file_util::FileEnumerator::IsDirectory(a);
|
| - bool b_is_directory = file_util::FileEnumerator::IsDirectory(b);
|
| + bool a_is_directory = file_util::FileEnumerator::IsDirectory(a.info);
|
| + bool b_is_directory = file_util::FileEnumerator::IsDirectory(b.info);
|
| if (a_is_directory != b_is_directory)
|
| return a_is_directory;
|
| #if defined(OS_POSIX)
|
| - return a.stat.st_mtime > b.stat.st_mtime;
|
| + return a.info.stat.st_mtime > b.info.stat.st_mtime;
|
| #elif defined(OS_WIN)
|
| - if (a.ftLastWriteTime.dwHighDateTime == b.ftLastWriteTime.dwHighDateTime) {
|
| - return a.ftLastWriteTime.dwLowDateTime > b.ftLastWriteTime.dwLowDateTime;
|
| + if (a.info.ftLastWriteTime.dwHighDateTime ==
|
| + b.info.ftLastWriteTime.dwHighDateTime) {
|
| + return a.info.ftLastWriteTime.dwLowDateTime >
|
| + b.info.ftLastWriteTime.dwLowDateTime;
|
| } else {
|
| - return a.ftLastWriteTime.dwHighDateTime > b.ftLastWriteTime.dwHighDateTime;
|
| + return a.info.ftLastWriteTime.dwHighDateTime >
|
| + b.info.ftLastWriteTime.dwHighDateTime;
|
| }
|
| #endif
|
| }
|
|
|
| +// Comparator for sorting find result by paths. This uses the locale-aware
|
| +// comparison function on the filenames for sorting in the user's locale.
|
| +// Static.
|
| +bool DirectoryLister::CompareFullPath(const DirectoryListerData& a,
|
| + const DirectoryListerData& b) {
|
| + return file_util::LocaleAwareCompareFilenames(a.path, b.path);
|
| +}
|
|
|
| DirectoryLister::DirectoryLister(const FilePath& dir,
|
| DirectoryListerDelegate* delegate)
|
| : dir_(dir),
|
| + recursive_(false),
|
| delegate_(delegate),
|
| - sort_(DEFAULT),
|
| + sort_(ALPHA_DIRS_FIRST),
|
| message_loop_(NULL),
|
| thread_(kNullThreadHandle) {
|
| DCHECK(!dir.value().empty());
|
| }
|
|
|
| DirectoryLister::DirectoryLister(const FilePath& dir,
|
| + bool recursive,
|
| SORT_TYPE sort,
|
| DirectoryListerDelegate* delegate)
|
| : dir_(dir),
|
| + recursive_(false),
|
| delegate_(delegate),
|
| sort_(sort),
|
| message_loop_(NULL),
|
| @@ -145,16 +161,22 @@
|
| Release();
|
| return;
|
| }
|
| - file_util::FileEnumerator file_enum(dir_, false,
|
| - static_cast<file_util::FileEnumerator::FILE_TYPE>(
|
| - file_util::FileEnumerator::FILES |
|
| - file_util::FileEnumerator::DIRECTORIES |
|
| - file_util::FileEnumerator::INCLUDE_DOT_DOT));
|
|
|
| - while (!canceled_.IsSet() && !(file_enum.Next().value().empty())) {
|
| - e->data.push_back(file_util::FileEnumerator::FindInfo());
|
| - file_enum.GetFindInfo(&e->data[e->data.size() - 1]);
|
| + int types = file_util::FileEnumerator::FILES |
|
| + file_util::FileEnumerator::DIRECTORIES;
|
| + if (!recursive_)
|
| + types |= file_util::FileEnumerator::INCLUDE_DOT_DOT;
|
|
|
| + file_util::FileEnumerator file_enum(dir_, recursive_,
|
| + static_cast<file_util::FileEnumerator::FILE_TYPE>(types));
|
| +
|
| + FilePath path;
|
| + while (!canceled_.IsSet() && !(path = file_enum.Next()).empty()) {
|
| + DirectoryListerData data;
|
| + file_enum.GetFindInfo(&data.info);
|
| + data.path = path;
|
| + e->data.push_back(data);
|
| +
|
| /* TODO(brettw) bug 24107: It would be nice to send incremental updates.
|
| We gather them all so they can be sorted, but eventually the sorting
|
| should be done from JS to give more flexibility in the page. When we do
|
| @@ -169,11 +191,14 @@
|
| if (!e->data.empty()) {
|
| // Sort the results. See the TODO above (this sort should be removed and we
|
| // should do it from JS).
|
| - if (sort_ == DATE) {
|
| - std::sort(e->data.begin(), e->data.end(), CompareFindInfoDate);
|
| - } else {
|
| - std::sort(e->data.begin(), e->data.end(), CompareFindInfoAlpha);
|
| - }
|
| + if (sort_ == DATE)
|
| + std::sort(e->data.begin(), e->data.end(), CompareDate);
|
| + else if (sort_ == FULL_PATH)
|
| + std::sort(e->data.begin(), e->data.end(), CompareFullPath);
|
| + else if (sort_ == ALPHA_DIRS_FIRST)
|
| + std::sort(e->data.begin(), e->data.end(), CompareAlphaDirsFirst);
|
| + else
|
| + DCHECK_EQ(NO_SORT, sort_);
|
|
|
| message_loop_->PostTask(FROM_HERE, e);
|
| e = new DirectoryDataEvent(this);
|
| @@ -184,8 +209,8 @@
|
| message_loop_->PostTask(FROM_HERE, e);
|
| }
|
|
|
| -void DirectoryLister::OnReceivedData(
|
| - const file_util::FileEnumerator::FindInfo* data, int count) {
|
| +void DirectoryLister::OnReceivedData(const DirectoryListerData* data,
|
| + int count) {
|
| // Since the delegate can clear itself during the OnListFile callback, we
|
| // need to null check it during each iteration of the loop. Similarly, it is
|
| // necessary to check the canceled_ flag to avoid sending data to a delegate
|
|
|