Index: net/base/directory_lister.cc |
=================================================================== |
--- net/base/directory_lister.cc (revision 28217) |
+++ net/base/directory_lister.cc (working copy) |
@@ -1,10 +1,14 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
#include "net/base/directory_lister.h" |
+#include <algorithm> |
+#include <vector> |
+ |
#include "base/file_util.h" |
+#include "base/i18n/file_util_icu.h" |
#include "base/message_loop.h" |
#include "base/platform_thread.h" |
#include "net/base/net_errors.h" |
@@ -15,23 +19,37 @@ |
class DirectoryDataEvent : public Task { |
public: |
- explicit DirectoryDataEvent(DirectoryLister* d) |
- : lister(d), count(0), error(0) { |
+ explicit DirectoryDataEvent(DirectoryLister* d) : lister(d), error(0) { |
+ // Allocations of the FindInfo aren't super cheap, so reserve space. |
+ data.reserve(64); |
} |
void Run() { |
- if (count) { |
- lister->OnReceivedData(data, count); |
- } else { |
+ if (data.empty()) { |
lister->OnDone(error); |
+ return; |
} |
+ lister->OnReceivedData(&data[0], static_cast<int>(data.size())); |
} |
scoped_refptr<DirectoryLister> lister; |
- file_util::FileEnumerator::FindInfo data[kFilesPerEvent]; |
- int count, error; |
+ std::vector<file_util::FileEnumerator::FindInfo> data; |
+ int error; |
}; |
+// Comparator for sorting FindInfo's. This uses the locale aware filename |
+// comparison function on the filenames for sorting in the user's locale. |
+static bool CompareFindInfo(const file_util::FileEnumerator::FindInfo& a, |
+ const file_util::FileEnumerator::FindInfo& b) { |
+#if defined(OS_WIN) |
+ return file_util::LocaleAwareCompareFilenames(FilePath(a.cFileName), |
+ FilePath(b.cFileName)); |
+#elif defined(OS_POSIX) |
+ return file_util::LocaleAwareCompareFilenames(FilePath(a.filename), |
+ FilePath(b.filename)); |
+#endif |
+} |
+ |
DirectoryLister::DirectoryLister(const FilePath& dir, |
DirectoryListerDelegate* delegate) |
: dir_(dir), |
@@ -91,15 +109,25 @@ |
file_util::FileEnumerator::INCLUDE_DOT_DOT)); |
while (!canceled_ && !(file_enum.Next().value().empty())) { |
- file_enum.GetFindInfo(&e->data[e->count]); |
+ e->data.push_back(file_util::FileEnumerator::FindInfo()); |
+ file_enum.GetFindInfo(&e->data[e->data.size() - 1]); |
+ /* 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 |
+ that, we can uncomment this to send incremental updates to the page. |
if (++e->count == kFilesPerEvent) { |
message_loop_->PostTask(FROM_HERE, e); |
e = new DirectoryDataEvent(this); |
} |
+ */ |
} |
- if (e->count > 0) { |
+ if (!e->data.empty()) { |
+ // Sort the results. See the TODO above (this sort should be removed and we |
+ // should do it from JS). |
+ std::sort(e->data.begin(), e->data.end(), CompareFindInfo); |
+ |
message_loop_->PostTask(FROM_HERE, e); |
e = new DirectoryDataEvent(this); |
} |