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

Side by Side Diff: runtime/bin/directory.cc

Issue 16813006: Make Directory.list pull-based, making it possible to pause, resume and cancel directory listing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review update. Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/directory.h ('k') | runtime/bin/directory_android.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/directory.h" 5 #include "bin/directory.h"
6 6
7 #include "bin/dartutils.h" 7 #include "bin/dartutils.h"
8 #include "bin/thread.h" 8 #include "bin/thread.h"
9 #include "include/dart_api.h" 9 #include "include/dart_api.h"
10 #include "platform/assert.h" 10 #include "platform/assert.h"
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // Create the list to hold the directory listing here, and pass it to the 143 // Create the list to hold the directory listing here, and pass it to the
144 // SyncDirectoryListing object, which adds elements to it. 144 // SyncDirectoryListing object, which adds elements to it.
145 Dart_Handle follow_links = Dart_GetNativeArgument(args, 2); 145 Dart_Handle follow_links = Dart_GetNativeArgument(args, 2);
146 // Create the list to hold the directory listing here, and pass it to the 146 // Create the list to hold the directory listing here, and pass it to the
147 // SyncDirectoryListing object, which adds elements to it. 147 // SyncDirectoryListing object, which adds elements to it.
148 Dart_Handle results = 148 Dart_Handle results =
149 Dart_New(DartUtils::GetDartClass(DartUtils::kCoreLibURL, "List"), 149 Dart_New(DartUtils::GetDartClass(DartUtils::kCoreLibURL, "List"),
150 Dart_Null(), 150 Dart_Null(),
151 0, 151 0,
152 NULL); 152 NULL);
153 SyncDirectoryListing sync_listing(results); 153 SyncDirectoryListing sync_listing(results,
154 Directory::List(DartUtils::GetStringValue(path), 154 DartUtils::GetStringValue(path),
155 DartUtils::GetBooleanValue(recursive), 155 DartUtils::GetBooleanValue(recursive),
156 DartUtils::GetBooleanValue(follow_links), 156 DartUtils::GetBooleanValue(follow_links));
157 &sync_listing); 157 Directory::List(&sync_listing);
158 Dart_SetReturnValue(args, results); 158 Dart_SetReturnValue(args, results);
159 Dart_ExitScope(); 159 Dart_ExitScope();
160 } 160 }
161 161
162 162
163 static CObject* DirectoryCreateRequest(const CObjectArray& request) { 163 static CObject* DirectoryCreateRequest(const CObjectArray& request) {
164 if (request.Length() == 2 && request[1]->IsString()) { 164 if (request.Length() == 2 && request[1]->IsString()) {
165 CObjectString path(request[1]); 165 CObjectString path(request[1]);
166 if (Directory::Create(path.CString())) { 166 if (Directory::Create(path.CString())) {
167 return CObject::True(); 167 return CObject::True();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 CObject* temp_dir = new CObjectString(CObject::NewString(result)); 213 CObject* temp_dir = new CObjectString(CObject::NewString(result));
214 free(result); 214 free(result);
215 return temp_dir; 215 return temp_dir;
216 } else { 216 } else {
217 return CObject::NewOSError(); 217 return CObject::NewOSError();
218 } 218 }
219 } 219 }
220 return CObject::IllegalArgumentError(); 220 return CObject::IllegalArgumentError();
221 } 221 }
222 222
223 static CObject* CreateIllegalArgumentError() {
224 // Respond with an illegal argument list error message.
225 CObjectArray* error = new CObjectArray(CObject::NewArray(3));
226 error->SetAt(0, new CObjectInt32(
227 CObject::NewInt32(AsyncDirectoryListing::kListError)));
228 error->SetAt(1, CObject::Null());
229 error->SetAt(2, CObject::IllegalArgumentError());
230 return error;
231 }
223 232
224 static CObject* DirectoryListRequest(const CObjectArray& request, 233 static CObject* DirectoryListStartRequest(const CObjectArray& request) {
225 Dart_Port response_port) {
226 if (request.Length() == 4 && 234 if (request.Length() == 4 &&
227 request[1]->IsString() && 235 request[1]->IsString() &&
228 request[2]->IsBool() && 236 request[2]->IsBool() &&
229 request[3]->IsBool()) { 237 request[3]->IsBool()) {
230 AsyncDirectoryListing* dir_listing =
231 new AsyncDirectoryListing(response_port);
232 CObjectString path(request[1]); 238 CObjectString path(request[1]);
233 CObjectBool recursive(request[2]); 239 CObjectBool recursive(request[2]);
234 CObjectBool follow_links(request[3]); 240 CObjectBool follow_links(request[3]);
235 bool completed = Directory::List( 241 AsyncDirectoryListing* dir_listing =
236 path.CString(), recursive.Value(), follow_links.Value(), dir_listing); 242 new AsyncDirectoryListing(path.CString(),
237 delete dir_listing; 243 recursive.Value(),
238 CObjectArray* response = new CObjectArray(CObject::NewArray(2)); 244 follow_links.Value());
239 response->SetAt( 245 // TODO(ajohnsen): Consider returning the first few results.
240 0, 246 return new CObjectIntptr(CObject::NewIntptr(
241 new CObjectInt32(CObject::NewInt32(AsyncDirectoryListing::kListDone))); 247 reinterpret_cast<intptr_t>(dir_listing)));
242 response->SetAt(1, CObject::Bool(completed));
243 return response;
244 } 248 }
245 // Respond with an illegal argument list error message. 249 return CreateIllegalArgumentError();
246 CObjectArray* response = new CObjectArray(CObject::NewArray(3));
247 response->SetAt(0, new CObjectInt32(
248 CObject::NewInt32(AsyncDirectoryListing::kListError)));
249 response->SetAt(1, CObject::Null());
250 response->SetAt(2, CObject::IllegalArgumentError());
251 Dart_PostCObject(response_port, response->AsApiCObject());
252
253 response = new CObjectArray(CObject::NewArray(2));
254 response->SetAt(
255 0, new CObjectInt32(CObject::NewInt32(AsyncDirectoryListing::kListDone)));
256 response->SetAt(1, CObject::False());
257 return response;
258 } 250 }
259 251
260 252
253 static CObject* DirectoryListNextRequest(const CObjectArray& request) {
254 if (request.Length() == 2 &&
255 request[1]->IsIntptr()) {
256 CObjectIntptr ptr(request[1]);
257 AsyncDirectoryListing* dir_listing =
258 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
259 const int kArraySize = 128;
260 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize));
261 dir_listing->SetArray(response, kArraySize);
262 Directory::List(dir_listing);
263 // In case the listing ended before it hit the buffer length, we need to
264 // override the array length.
265 response->AsApiCObject()->value.as_array.length = dir_listing->index();
266 return response;
267 }
268 return CreateIllegalArgumentError();
269 }
270
271
272 static CObject* DirectoryListStopRequest(const CObjectArray& request) {
273 if (request.Length() == 2 && request[1]->IsIntptr()) {
274 CObjectIntptr ptr(request[1]);
275 AsyncDirectoryListing* dir_listing =
276 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
277 delete dir_listing;
278 return new CObjectBool(CObject::Bool(true));
279 }
280 return CreateIllegalArgumentError();
281 }
282
283
261 static CObject* DirectoryRenameRequest(const CObjectArray& request, 284 static CObject* DirectoryRenameRequest(const CObjectArray& request,
262 Dart_Port response_port) { 285 Dart_Port response_port) {
263 if (request.Length() == 3 && 286 if (request.Length() == 3 &&
264 request[1]->IsString() && 287 request[1]->IsString() &&
265 request[2]->IsString()) { 288 request[2]->IsString()) {
266 CObjectString path(request[1]); 289 CObjectString path(request[1]);
267 CObjectString new_path(request[2]); 290 CObjectString new_path(request[2]);
268 bool completed = Directory::Rename(path.CString(), new_path.CString()); 291 bool completed = Directory::Rename(path.CString(), new_path.CString());
269 if (completed) return CObject::True(); 292 if (completed) return CObject::True();
270 return CObject::NewOSError(); 293 return CObject::NewOSError();
(...skipping 16 matching lines...) Expand all
287 break; 310 break;
288 case Directory::kDeleteRequest: 311 case Directory::kDeleteRequest:
289 response = DirectoryDeleteRequest(request); 312 response = DirectoryDeleteRequest(request);
290 break; 313 break;
291 case Directory::kExistsRequest: 314 case Directory::kExistsRequest:
292 response = DirectoryExistsRequest(request); 315 response = DirectoryExistsRequest(request);
293 break; 316 break;
294 case Directory::kCreateTempRequest: 317 case Directory::kCreateTempRequest:
295 response = DirectoryCreateTempRequest(request); 318 response = DirectoryCreateTempRequest(request);
296 break; 319 break;
297 case Directory::kListRequest: 320 case Directory::kListStartRequest:
298 response = DirectoryListRequest(request, reply_port_id); 321 response = DirectoryListStartRequest(request);
322 break;
323 case Directory::kListNextRequest:
324 response = DirectoryListNextRequest(request);
325 break;
326 case Directory::kListStopRequest:
327 response = DirectoryListStopRequest(request);
299 break; 328 break;
300 case Directory::kRenameRequest: 329 case Directory::kRenameRequest:
301 response = DirectoryRenameRequest(request, reply_port_id); 330 response = DirectoryRenameRequest(request, reply_port_id);
302 break; 331 break;
303 default: 332 default:
304 UNREACHABLE(); 333 UNREACHABLE();
305 } 334 }
306 } 335 }
307 } 336 }
308 337
(...skipping 12 matching lines...) Expand all
321 Dart_Port service_port = Directory::GetServicePort(); 350 Dart_Port service_port = Directory::GetServicePort();
322 if (service_port != ILLEGAL_PORT) { 351 if (service_port != ILLEGAL_PORT) {
323 // Return a send port for the service port. 352 // Return a send port for the service port.
324 Dart_Handle send_port = Dart_NewSendPort(service_port); 353 Dart_Handle send_port = Dart_NewSendPort(service_port);
325 Dart_SetReturnValue(args, send_port); 354 Dart_SetReturnValue(args, send_port);
326 } 355 }
327 Dart_ExitScope(); 356 Dart_ExitScope();
328 } 357 }
329 358
330 359
331 CObjectArray* AsyncDirectoryListing::NewResponse(Response type, char* arg) { 360 bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type,
332 CObjectArray* response = new CObjectArray(CObject::NewArray(2)); 361 char* arg) {
333 response->SetAt(0, new CObjectInt32(CObject::NewInt32(type))); 362 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type)));
334 response->SetAt(1, new CObjectString(CObject::NewString(arg))); 363 if (arg != NULL) {
335 return response; 364 array_->SetAt(index_++, new CObjectString(CObject::NewString(arg)));
365 } else {
366 array_->SetAt(index_++, CObject::Null());
367 }
368 return index_ < length_;
336 } 369 }
337 370
338 371
339 bool AsyncDirectoryListing::HandleDirectory(char* dir_name) { 372 bool AsyncDirectoryListing::HandleDirectory(char* dir_name) {
340 CObjectArray* response = NewResponse(kListDirectory, dir_name); 373 return AddFileSystemEntityToResponse(kListDirectory, dir_name);
341 return Dart_PostCObject(response_port_, response->AsApiCObject());
342 } 374 }
343 375
344 376
345 bool AsyncDirectoryListing::HandleFile(char* file_name) { 377 bool AsyncDirectoryListing::HandleFile(char* file_name) {
346 CObjectArray* response = NewResponse(kListFile, file_name); 378 return AddFileSystemEntityToResponse(kListFile, file_name);
347 return Dart_PostCObject(response_port_, response->AsApiCObject());
348 } 379 }
349 380
350 381
351 bool AsyncDirectoryListing::HandleLink(char* link_name) { 382 bool AsyncDirectoryListing::HandleLink(char* link_name) {
352 CObjectArray* response = NewResponse(kListLink, link_name); 383 return AddFileSystemEntityToResponse(kListLink, link_name);
353 return Dart_PostCObject(response_port_, response->AsApiCObject()); 384 }
385
386 void AsyncDirectoryListing::HandleDone() {
387 AddFileSystemEntityToResponse(kListDone, NULL);
354 } 388 }
355 389
356 390
357 bool AsyncDirectoryListing::HandleError(const char* dir_name) { 391 bool AsyncDirectoryListing::HandleError(const char* dir_name) {
392 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(kListError)));
358 CObject* err = CObject::NewOSError(); 393 CObject* err = CObject::NewOSError();
359 CObjectArray* response = new CObjectArray(CObject::NewArray(3)); 394 CObjectArray* response = new CObjectArray(CObject::NewArray(3));
360 response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError))); 395 response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError)));
361 response->SetAt(1, new CObjectString(CObject::NewString(dir_name))); 396 response->SetAt(1, new CObjectString(CObject::NewString(dir_name)));
362 response->SetAt(2, err); 397 response->SetAt(2, err);
363 return Dart_PostCObject(response_port_, response->AsApiCObject()); 398 array_->SetAt(index_++, response);
399 return index_ < length_;
364 } 400 }
365 401
366 bool SyncDirectoryListing::HandleDirectory(char* dir_name) { 402 bool SyncDirectoryListing::HandleDirectory(char* dir_name) {
367 Dart_Handle dir_name_dart = DartUtils::NewString(dir_name); 403 Dart_Handle dir_name_dart = DartUtils::NewString(dir_name);
368 Dart_Handle dir = 404 Dart_Handle dir =
369 Dart_New(directory_class_, Dart_Null(), 1, &dir_name_dart); 405 Dart_New(directory_class_, Dart_Null(), 1, &dir_name_dart);
370 Dart_Invoke(results_, add_string_, 1, &dir); 406 Dart_Invoke(results_, add_string_, 1, &dir);
371 return true; 407 return true;
372 } 408 }
373 409
(...skipping 20 matching lines...) Expand all
394 args[1] = DartUtils::NewString(dir_name); 430 args[1] = DartUtils::NewString(dir_name);
395 args[2] = dart_os_error; 431 args[2] = dart_os_error;
396 Dart_ThrowException(Dart_New( 432 Dart_ThrowException(Dart_New(
397 DartUtils::GetDartClass(DartUtils::kIOLibURL, "DirectoryException"), 433 DartUtils::GetDartClass(DartUtils::kIOLibURL, "DirectoryException"),
398 Dart_Null(), 434 Dart_Null(),
399 3, 435 3,
400 args)); 436 args));
401 return true; 437 return true;
402 } 438 }
403 439
440
441 static bool ListNext(DirectoryListing* listing) {
442 switch (listing->top()->Next(listing)) {
443 case kListFile:
444 return listing->HandleFile(listing->CurrentPath());
445
446 case kListLink:
447 return listing->HandleLink(listing->CurrentPath());
448
449 case kListDirectory:
450 if (listing->recursive()) {
451 listing->Push(new DirectoryListingEntry(listing->top()));
452 }
453 return listing->HandleDirectory(listing->CurrentPath());
454
455 case kListError:
456 return listing->HandleError(listing->CurrentPath());
457
458 case kListDone:
459 listing->Pop();
460 if (listing->IsEmpty()) {
461 listing->HandleDone();
462 return false;
463 } else {
464 return true;
465 }
466
467 default:
468 UNREACHABLE();
469 }
470 return false;
471 }
472
473 void Directory::List(DirectoryListing* listing) {
474 if (listing->error()) {
475 listing->HandleError("Invalid path");
476 listing->HandleDone();
477 } else {
478 while (ListNext(listing)) {}
479 }
480 }
481
404 } // namespace bin 482 } // namespace bin
405 } // namespace dart 483 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/directory.h ('k') | runtime/bin/directory_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698