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

Side by Side Diff: net/base/directory_lister.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months 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
« no previous file with comments | « net/base/directory_lister.h ('k') | net/base/directory_lister_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/directory_lister.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/files/file_enumerator.h"
11 #include "base/files/file_util.h"
12 #include "base/i18n/file_util_icu.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "base/threading/worker_pool.h"
17 #include "net/base/net_errors.h"
18
19 namespace net {
20
21 namespace {
22
23 bool IsDotDot(const base::FilePath& path) {
24 return FILE_PATH_LITERAL("..") == path.BaseName().value();
25 }
26
27 // Comparator for sorting lister results. This uses the locale aware filename
28 // comparison function on the filenames for sorting in the user's locale.
29 // Static.
30 bool CompareAlphaDirsFirst(const DirectoryLister::DirectoryListerData& a,
31 const DirectoryLister::DirectoryListerData& b) {
32 // Parent directory before all else.
33 if (IsDotDot(a.info.GetName()))
34 return true;
35 if (IsDotDot(b.info.GetName()))
36 return false;
37
38 // Directories before regular files.
39 bool a_is_directory = a.info.IsDirectory();
40 bool b_is_directory = b.info.IsDirectory();
41 if (a_is_directory != b_is_directory)
42 return a_is_directory;
43
44 return base::i18n::LocaleAwareCompareFilenames(a.info.GetName(),
45 b.info.GetName());
46 }
47
48 bool CompareDate(const DirectoryLister::DirectoryListerData& a,
49 const DirectoryLister::DirectoryListerData& b) {
50 // Parent directory before all else.
51 if (IsDotDot(a.info.GetName()))
52 return true;
53 if (IsDotDot(b.info.GetName()))
54 return false;
55
56 // Directories before regular files.
57 bool a_is_directory = a.info.IsDirectory();
58 bool b_is_directory = b.info.IsDirectory();
59 if (a_is_directory != b_is_directory)
60 return a_is_directory;
61 return a.info.GetLastModifiedTime() > b.info.GetLastModifiedTime();
62 }
63
64 // Comparator for sorting find result by paths. This uses the locale-aware
65 // comparison function on the filenames for sorting in the user's locale.
66 // Static.
67 bool CompareFullPath(const DirectoryLister::DirectoryListerData& a,
68 const DirectoryLister::DirectoryListerData& b) {
69 return base::i18n::LocaleAwareCompareFilenames(a.path, b.path);
70 }
71
72 void SortData(std::vector<DirectoryLister::DirectoryListerData>* data,
73 DirectoryLister::SortType sort_type) {
74 // Sort the results. See the TODO below (this sort should be removed and we
75 // should do it from JS).
76 if (sort_type == DirectoryLister::DATE) {
77 std::sort(data->begin(), data->end(), CompareDate);
78 } else if (sort_type == DirectoryLister::FULL_PATH) {
79 std::sort(data->begin(), data->end(), CompareFullPath);
80 } else if (sort_type == DirectoryLister::ALPHA_DIRS_FIRST) {
81 std::sort(data->begin(), data->end(), CompareAlphaDirsFirst);
82 } else {
83 DCHECK_EQ(DirectoryLister::NO_SORT, sort_type);
84 }
85 }
86
87 } // namespace
88
89 DirectoryLister::DirectoryLister(const base::FilePath& dir,
90 DirectoryListerDelegate* delegate)
91 : delegate_(delegate) {
92 core_ = new Core(dir, false, ALPHA_DIRS_FIRST, this);
93 DCHECK(delegate_);
94 DCHECK(!dir.value().empty());
95 }
96
97 DirectoryLister::DirectoryLister(const base::FilePath& dir,
98 bool recursive,
99 SortType sort,
100 DirectoryListerDelegate* delegate)
101 : delegate_(delegate) {
102 core_ = new Core(dir, recursive, sort, this);
103 DCHECK(delegate_);
104 DCHECK(!dir.value().empty());
105 }
106
107 DirectoryLister::~DirectoryLister() {
108 Cancel();
109 }
110
111 bool DirectoryLister::Start() {
112 return base::WorkerPool::PostTask(
113 FROM_HERE,
114 base::Bind(&Core::Start, core_),
115 true);
116 }
117
118 void DirectoryLister::Cancel() {
119 core_->CancelOnOriginThread();
120 }
121
122 DirectoryLister::Core::Core(const base::FilePath& dir,
123 bool recursive,
124 SortType sort,
125 DirectoryLister* lister)
126 : dir_(dir),
127 recursive_(recursive),
128 sort_(sort),
129 origin_loop_(base::MessageLoopProxy::current()),
130 lister_(lister),
131 cancelled_(0) {
132 DCHECK(lister_);
133 }
134
135 DirectoryLister::Core::~Core() {}
136
137 void DirectoryLister::Core::CancelOnOriginThread() {
138 DCHECK(origin_loop_->BelongsToCurrentThread());
139
140 base::subtle::NoBarrier_Store(&cancelled_, 1);
141 // Core must not call into |lister_| after cancellation, as the |lister_| may
142 // have been destroyed. Setting |lister_| to NULL ensures any such access will
143 // cause a crash.
144 lister_ = nullptr;
145 }
146
147 void DirectoryLister::Core::Start() {
148 scoped_ptr<DirectoryList> directory_list(new DirectoryList());
149
150 if (!base::DirectoryExists(dir_)) {
151 origin_loop_->PostTask(
152 FROM_HERE,
153 base::Bind(&Core::DoneOnOriginThread, this,
154 base::Passed(directory_list.Pass()), ERR_FILE_NOT_FOUND));
155 return;
156 }
157
158 int types = base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES;
159 if (!recursive_)
160 types |= base::FileEnumerator::INCLUDE_DOT_DOT;
161
162 base::FileEnumerator file_enum(dir_, recursive_, types);
163
164 base::FilePath path;
165 while (!(path = file_enum.Next()).empty()) {
166 // Abort on cancellation. This is purely for performance reasons.
167 // Correctness guarantees are made by checks in DoneOnOriginThread.
168 if (IsCancelled())
169 return;
170
171 DirectoryListerData data;
172 data.info = file_enum.GetInfo();
173 data.path = path;
174 directory_list->push_back(data);
175
176 /* TODO(brettw) bug 24107: It would be nice to send incremental updates.
177 We gather them all so they can be sorted, but eventually the sorting
178 should be done from JS to give more flexibility in the page. When we do
179 that, we can uncomment this to send incremental updates to the page.
180
181 const int kFilesPerEvent = 8;
182 if (file_data.size() < kFilesPerEvent)
183 continue;
184
185 origin_loop_->PostTask(
186 FROM_HERE,
187 base::Bind(&DirectoryLister::Core::SendData, file_data));
188 file_data.clear();
189 */
190 }
191
192 SortData(directory_list.get(), sort_);
193
194 origin_loop_->PostTask(
195 FROM_HERE,
196 base::Bind(&Core::DoneOnOriginThread, this,
197 base::Passed(directory_list.Pass()), OK));
198 }
199
200 bool DirectoryLister::Core::IsCancelled() const {
201 return !!base::subtle::NoBarrier_Load(&cancelled_);
202 }
203
204 void DirectoryLister::Core::DoneOnOriginThread(
205 scoped_ptr<DirectoryList> directory_list, int error) const {
206 DCHECK(origin_loop_->BelongsToCurrentThread());
207
208 // Need to check if the operation was before first callback.
209 if (IsCancelled())
210 return;
211
212 for (const auto& lister_data : *directory_list) {
213 lister_->OnListFile(lister_data);
214 // Need to check if the operation was cancelled during the callback.
215 if (IsCancelled())
216 return;
217 }
218 lister_->OnListDone(error);
219 }
220
221 void DirectoryLister::OnListFile(const DirectoryListerData& data) {
222 delegate_->OnListFile(data);
223 }
224
225 void DirectoryLister::OnListDone(int error) {
226 delegate_->OnListDone(error);
227 }
228
229 } // namespace net
OLDNEW
« no previous file with comments | « net/base/directory_lister.h ('k') | net/base/directory_lister_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698