OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/drive/search_metadata.h" | 5 #include "chrome/browser/chromeos/drive/search_metadata.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <queue> | 8 #include <queue> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 (query && !FindAndHighlight(entry.base_name(), query, &highlighted))) | 145 (query && !FindAndHighlight(entry.base_name(), query, &highlighted))) |
146 return; | 146 return; |
147 | 147 |
148 // Make space for |entry| when appropriate. | 148 // Make space for |entry| when appropriate. |
149 if (result_candidates->size() == at_most_num_matches) | 149 if (result_candidates->size() == at_most_num_matches) |
150 result_candidates->pop(); | 150 result_candidates->pop(); |
151 result_candidates->push(new MetadataSearchResult(entry, highlighted)); | 151 result_candidates->push(new MetadataSearchResult(entry, highlighted)); |
152 } | 152 } |
153 | 153 |
154 // Implements SearchMetadata(). | 154 // Implements SearchMetadata(). |
155 scoped_ptr<MetadataSearchResultVector> SearchMetadataOnBlockingPool( | 155 FileError SearchMetadataOnBlockingPool(ResourceMetadata* resource_metadata, |
156 ResourceMetadata* resource_metadata, | 156 FileCache* cache, |
157 FileCache* cache, | 157 const std::string& query_text, |
158 const std::string& query_text, | 158 int options, |
159 int options, | 159 int at_most_num_matches, |
160 int at_most_num_matches) { | 160 MetadataSearchResultVector* results) { |
161 ScopedPriorityQueue<MetadataSearchResult, | 161 ScopedPriorityQueue<MetadataSearchResult, |
162 MetadataSearchResultComparator> result_candidates; | 162 MetadataSearchResultComparator> result_candidates; |
163 | 163 |
164 // Prepare data structure for searching. | 164 // Prepare data structure for searching. |
165 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents query( | 165 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents query( |
166 base::UTF8ToUTF16(query_text)); | 166 base::UTF8ToUTF16(query_text)); |
167 | 167 |
168 // Iterate over entries. | 168 // Iterate over entries. |
169 scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata->GetIterator(); | 169 scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata->GetIterator(); |
170 for (; !it->IsAtEnd(); it->Advance()) { | 170 for (; !it->IsAtEnd(); it->Advance()) { |
171 MaybeAddEntryToResult(resource_metadata, cache, | 171 MaybeAddEntryToResult(resource_metadata, cache, |
172 query_text.empty() ? NULL : &query, | 172 query_text.empty() ? NULL : &query, |
173 options, | 173 options, |
174 at_most_num_matches, &result_candidates, it->Get()); | 174 at_most_num_matches, &result_candidates, it->Get()); |
175 } | 175 } |
176 | 176 |
177 // Prepare the result. | 177 // Prepare the result. |
178 scoped_ptr<MetadataSearchResultVector> results( | |
179 new MetadataSearchResultVector); | |
180 for (; !result_candidates.empty(); result_candidates.pop()) { | 178 for (; !result_candidates.empty(); result_candidates.pop()) { |
181 // The path field of entries in result_candidates are empty at this point, | 179 // The path field of entries in result_candidates are empty at this point, |
182 // because we don't want to run the expensive metadata DB look up except for | 180 // because we don't want to run the expensive metadata DB look up except for |
183 // the final results. Hence, here we fill the part. | 181 // the final results. Hence, here we fill the part. |
184 base::FilePath path = resource_metadata->GetFilePath( | 182 base::FilePath path = resource_metadata->GetFilePath( |
185 result_candidates.top()->entry.resource_id()); | 183 result_candidates.top()->entry.resource_id()); |
186 if (path.empty()) | 184 if (path.empty()) |
187 continue; | 185 return FILE_ERROR_FAILED; |
188 results->push_back(*result_candidates.top()); | 186 results->push_back(*result_candidates.top()); |
189 results->back().path = path; | 187 results->back().path = path; |
190 } | 188 } |
191 | 189 |
192 // Reverse the order here because |result_candidates| puts the most | 190 // Reverse the order here because |result_candidates| puts the most |
193 // uninteresting candidate at the top. | 191 // uninteresting candidate at the top. |
194 std::reverse(results->begin(), results->end()); | 192 std::reverse(results->begin(), results->end()); |
195 | 193 |
196 return results.Pass(); | 194 return FILE_ERROR_OK; |
197 } | 195 } |
| 196 |
| 197 void RunSearchMetadataCallback(const SearchMetadataCallback& callback, |
| 198 scoped_ptr<MetadataSearchResultVector> results, |
| 199 FileError error) { |
| 200 if (error != FILE_ERROR_OK) |
| 201 results.reset(); |
| 202 callback.Run(error, results.Pass()); |
| 203 } |
| 204 |
198 } // namespace | 205 } // namespace |
199 | 206 |
200 void SearchMetadata( | 207 void SearchMetadata( |
201 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, | 208 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, |
202 ResourceMetadata* resource_metadata, | 209 ResourceMetadata* resource_metadata, |
203 FileCache* cache, | 210 FileCache* cache, |
204 const std::string& query, | 211 const std::string& query, |
205 int options, | 212 int options, |
206 int at_most_num_matches, | 213 int at_most_num_matches, |
207 const SearchMetadataCallback& callback) { | 214 const SearchMetadataCallback& callback) { |
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
209 DCHECK_LE(0, at_most_num_matches); | 216 DCHECK_LE(0, at_most_num_matches); |
210 DCHECK(!callback.is_null()); | 217 DCHECK(!callback.is_null()); |
211 | 218 |
212 // TODO(hashimoto): Report error code from ResourceMetadata::IterateEntries | 219 scoped_ptr<MetadataSearchResultVector> results( |
213 // and stop binding FILE_ERROR_OK to |callback|. | 220 new MetadataSearchResultVector); |
| 221 MetadataSearchResultVector* results_ptr = results.get(); |
214 base::PostTaskAndReplyWithResult(blocking_task_runner.get(), | 222 base::PostTaskAndReplyWithResult(blocking_task_runner.get(), |
215 FROM_HERE, | 223 FROM_HERE, |
216 base::Bind(&SearchMetadataOnBlockingPool, | 224 base::Bind(&SearchMetadataOnBlockingPool, |
217 resource_metadata, | 225 resource_metadata, |
218 cache, | 226 cache, |
219 query, | 227 query, |
220 options, | 228 options, |
221 at_most_num_matches), | 229 at_most_num_matches, |
222 base::Bind(callback, FILE_ERROR_OK)); | 230 results_ptr), |
| 231 base::Bind(&RunSearchMetadataCallback, |
| 232 callback, |
| 233 base::Passed(&results))); |
223 } | 234 } |
224 | 235 |
225 bool FindAndHighlight( | 236 bool FindAndHighlight( |
226 const std::string& text, | 237 const std::string& text, |
227 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query, | 238 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query, |
228 std::string* highlighted_text) { | 239 std::string* highlighted_text) { |
229 DCHECK(query); | 240 DCHECK(query); |
230 DCHECK(highlighted_text); | 241 DCHECK(highlighted_text); |
231 highlighted_text->clear(); | 242 highlighted_text->clear(); |
232 | 243 |
233 string16 text16 = base::UTF8ToUTF16(text); | 244 string16 text16 = base::UTF8ToUTF16(text); |
234 size_t match_start = 0; | 245 size_t match_start = 0; |
235 size_t match_length = 0; | 246 size_t match_length = 0; |
236 if (!query->Search(text16, &match_start, &match_length)) | 247 if (!query->Search(text16, &match_start, &match_length)) |
237 return false; | 248 return false; |
238 | 249 |
239 string16 pre = text16.substr(0, match_start); | 250 string16 pre = text16.substr(0, match_start); |
240 string16 match = text16.substr(match_start, match_length); | 251 string16 match = text16.substr(match_start, match_length); |
241 string16 post = text16.substr(match_start + match_length); | 252 string16 post = text16.substr(match_start + match_length); |
242 highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(pre))); | 253 highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(pre))); |
243 highlighted_text->append("<b>"); | 254 highlighted_text->append("<b>"); |
244 highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(match))); | 255 highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(match))); |
245 highlighted_text->append("</b>"); | 256 highlighted_text->append("</b>"); |
246 highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(post))); | 257 highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(post))); |
247 return true; | 258 return true; |
248 } | 259 } |
249 | 260 |
250 } // namespace internal | 261 } // namespace internal |
251 } // namespace drive | 262 } // namespace drive |
OLD | NEW |