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

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: Macos and Android version. 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
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 223
224 static CObject* DirectoryListRequest(const CObjectArray& request, 224 static CObject* DirectoryListStartRequest(const CObjectArray& request) {
225 Dart_Port response_port) {
226 if (request.Length() == 4 && 225 if (request.Length() == 4 &&
227 request[1]->IsString() && 226 request[1]->IsString() &&
228 request[2]->IsBool() && 227 request[2]->IsBool() &&
229 request[3]->IsBool()) { 228 request[3]->IsBool()) {
230 AsyncDirectoryListing* dir_listing =
231 new AsyncDirectoryListing(response_port);
232 CObjectString path(request[1]); 229 CObjectString path(request[1]);
233 CObjectBool recursive(request[2]); 230 CObjectBool recursive(request[2]);
234 CObjectBool follow_links(request[3]); 231 CObjectBool follow_links(request[3]);
235 bool completed = Directory::List( 232 AsyncDirectoryListing* dir_listing =
236 path.CString(), recursive.Value(), follow_links.Value(), dir_listing); 233 new AsyncDirectoryListing(path.CString(),
237 delete dir_listing; 234 recursive.Value(),
238 CObjectArray* response = new CObjectArray(CObject::NewArray(2)); 235 follow_links.Value());
239 response->SetAt( 236 return new CObjectIntptr(CObject::NewIntptr(
240 0, 237 reinterpret_cast<intptr_t>(dir_listing)));
241 new CObjectInt32(CObject::NewInt32(AsyncDirectoryListing::kListDone))); 238 }
242 response->SetAt(1, CObject::Bool(completed)); 239 // Respond with an illegal argument list error message.
240 CObjectArray* response = new CObjectArray(CObject::NewArray(3));
241 response->SetAt(0, new CObjectInt32(
242 CObject::NewInt32(AsyncDirectoryListing::kListError)));
243 response->SetAt(1, CObject::Null());
244 response->SetAt(2, CObject::IllegalArgumentError());
245 return response;
246 }
247
248
249 static CObject* DirectoryListNextRequest(const CObjectArray& request) {
250 if (request.Length() == 2 &&
251 request[1]->IsIntptr()) {
252 CObjectIntptr ptr(request[1]);
253 AsyncDirectoryListing* dir_listing =
254 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
255 const int kArraySize = 128;
256 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize));
257 dir_listing->SetArray(response, kArraySize);
258 Directory::List(dir_listing);
259 response->AsApiCObject()->value.as_array.length = dir_listing->index();
243 return response; 260 return response;
244 } 261 }
245 // Respond with an illegal argument list error message. 262 // Respond with an illegal argument list error message.
246 CObjectArray* response = new CObjectArray(CObject::NewArray(3)); 263 CObjectArray* response = new CObjectArray(CObject::NewArray(3));
247 response->SetAt(0, new CObjectInt32( 264 response->SetAt(0, new CObjectInt32(
248 CObject::NewInt32(AsyncDirectoryListing::kListError))); 265 CObject::NewInt32(AsyncDirectoryListing::kListError)));
249 response->SetAt(1, CObject::Null()); 266 response->SetAt(1, CObject::Null());
250 response->SetAt(2, CObject::IllegalArgumentError()); 267 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; 268 return response;
258 } 269 }
259 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 // Respond with an illegal argument list error message.
281 CObjectArray* response = new CObjectArray(CObject::NewArray(3));
282 response->SetAt(0, new CObjectInt32(
283 CObject::NewInt32(AsyncDirectoryListing::kListError)));
284 response->SetAt(1, CObject::Null());
285 response->SetAt(2, CObject::IllegalArgumentError());
286 return response;
287 }
288
260 289
261 static CObject* DirectoryRenameRequest(const CObjectArray& request, 290 static CObject* DirectoryRenameRequest(const CObjectArray& request,
262 Dart_Port response_port) { 291 Dart_Port response_port) {
263 if (request.Length() == 3 && 292 if (request.Length() == 3 &&
264 request[1]->IsString() && 293 request[1]->IsString() &&
265 request[2]->IsString()) { 294 request[2]->IsString()) {
266 CObjectString path(request[1]); 295 CObjectString path(request[1]);
267 CObjectString new_path(request[2]); 296 CObjectString new_path(request[2]);
268 bool completed = Directory::Rename(path.CString(), new_path.CString()); 297 bool completed = Directory::Rename(path.CString(), new_path.CString());
269 if (completed) return CObject::True(); 298 if (completed) return CObject::True();
(...skipping 17 matching lines...) Expand all
287 break; 316 break;
288 case Directory::kDeleteRequest: 317 case Directory::kDeleteRequest:
289 response = DirectoryDeleteRequest(request); 318 response = DirectoryDeleteRequest(request);
290 break; 319 break;
291 case Directory::kExistsRequest: 320 case Directory::kExistsRequest:
292 response = DirectoryExistsRequest(request); 321 response = DirectoryExistsRequest(request);
293 break; 322 break;
294 case Directory::kCreateTempRequest: 323 case Directory::kCreateTempRequest:
295 response = DirectoryCreateTempRequest(request); 324 response = DirectoryCreateTempRequest(request);
296 break; 325 break;
297 case Directory::kListRequest: 326 case Directory::kListStartRequest:
298 response = DirectoryListRequest(request, reply_port_id); 327 response = DirectoryListStartRequest(request);
328 break;
329 case Directory::kListNextRequest:
330 response = DirectoryListNextRequest(request);
331 break;
332 case Directory::kListStopRequest:
333 response = DirectoryListStopRequest(request);
299 break; 334 break;
300 case Directory::kRenameRequest: 335 case Directory::kRenameRequest:
301 response = DirectoryRenameRequest(request, reply_port_id); 336 response = DirectoryRenameRequest(request, reply_port_id);
302 break; 337 break;
303 default: 338 default:
304 UNREACHABLE(); 339 UNREACHABLE();
305 } 340 }
306 } 341 }
307 } 342 }
308 343
(...skipping 12 matching lines...) Expand all
321 Dart_Port service_port = Directory::GetServicePort(); 356 Dart_Port service_port = Directory::GetServicePort();
322 if (service_port != ILLEGAL_PORT) { 357 if (service_port != ILLEGAL_PORT) {
323 // Return a send port for the service port. 358 // Return a send port for the service port.
324 Dart_Handle send_port = Dart_NewSendPort(service_port); 359 Dart_Handle send_port = Dart_NewSendPort(service_port);
325 Dart_SetReturnValue(args, send_port); 360 Dart_SetReturnValue(args, send_port);
326 } 361 }
327 Dart_ExitScope(); 362 Dart_ExitScope();
328 } 363 }
329 364
330 365
331 CObjectArray* AsyncDirectoryListing::NewResponse(Response type, char* arg) { 366 bool AsyncDirectoryListing::NewResponse(Response type, char* arg) {
Søren Gjesse 2013/06/13 11:59:20 How about calling this AddToResponse or AddFileSys
Anders Johnsen 2013/06/13 14:38:25 Done.
332 CObjectArray* response = new CObjectArray(CObject::NewArray(2)); 367 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type)));
333 response->SetAt(0, new CObjectInt32(CObject::NewInt32(type))); 368 if (arg != NULL) {
334 response->SetAt(1, new CObjectString(CObject::NewString(arg))); 369 array_->SetAt(index_++, new CObjectString(CObject::NewString(arg)));
335 return response; 370 } else {
371 array_->SetAt(index_++, CObject::Null());
372 }
373 return index_ < length_;
336 } 374 }
337 375
338 376
339 bool AsyncDirectoryListing::HandleDirectory(char* dir_name) { 377 bool AsyncDirectoryListing::HandleDirectory(char* dir_name) {
340 CObjectArray* response = NewResponse(kListDirectory, dir_name); 378 return NewResponse(kListDirectory, dir_name);
341 return Dart_PostCObject(response_port_, response->AsApiCObject());
342 } 379 }
343 380
344 381
345 bool AsyncDirectoryListing::HandleFile(char* file_name) { 382 bool AsyncDirectoryListing::HandleFile(char* file_name) {
346 CObjectArray* response = NewResponse(kListFile, file_name); 383 return NewResponse(kListFile, file_name);
347 return Dart_PostCObject(response_port_, response->AsApiCObject());
348 } 384 }
349 385
350 386
351 bool AsyncDirectoryListing::HandleLink(char* link_name) { 387 bool AsyncDirectoryListing::HandleLink(char* link_name) {
352 CObjectArray* response = NewResponse(kListLink, link_name); 388 return NewResponse(kListLink, link_name);
353 return Dart_PostCObject(response_port_, response->AsApiCObject()); 389 }
390
391 void AsyncDirectoryListing::HandleDone() {
392 NewResponse(kListDone, NULL);
354 } 393 }
355 394
356 395
357 bool AsyncDirectoryListing::HandleError(const char* dir_name) { 396 bool AsyncDirectoryListing::HandleError(const char* dir_name) {
397 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(kListError)));
358 CObject* err = CObject::NewOSError(); 398 CObject* err = CObject::NewOSError();
359 CObjectArray* response = new CObjectArray(CObject::NewArray(3)); 399 CObjectArray* response = new CObjectArray(CObject::NewArray(3));
360 response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError))); 400 response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError)));
361 response->SetAt(1, new CObjectString(CObject::NewString(dir_name))); 401 response->SetAt(1, new CObjectString(CObject::NewString(dir_name)));
362 response->SetAt(2, err); 402 response->SetAt(2, err);
363 return Dart_PostCObject(response_port_, response->AsApiCObject()); 403 array_->SetAt(index_++, response);
404 return index_ < length_;
364 } 405 }
365 406
366 bool SyncDirectoryListing::HandleDirectory(char* dir_name) { 407 bool SyncDirectoryListing::HandleDirectory(char* dir_name) {
367 Dart_Handle dir_name_dart = DartUtils::NewString(dir_name); 408 Dart_Handle dir_name_dart = DartUtils::NewString(dir_name);
368 Dart_Handle dir = 409 Dart_Handle dir =
369 Dart_New(directory_class_, Dart_Null(), 1, &dir_name_dart); 410 Dart_New(directory_class_, Dart_Null(), 1, &dir_name_dart);
370 Dart_Invoke(results_, add_string_, 1, &dir); 411 Dart_Invoke(results_, add_string_, 1, &dir);
371 return true; 412 return true;
372 } 413 }
373 414
(...skipping 20 matching lines...) Expand all
394 args[1] = DartUtils::NewString(dir_name); 435 args[1] = DartUtils::NewString(dir_name);
395 args[2] = dart_os_error; 436 args[2] = dart_os_error;
396 Dart_ThrowException(Dart_New( 437 Dart_ThrowException(Dart_New(
397 DartUtils::GetDartClass(DartUtils::kIOLibURL, "DirectoryException"), 438 DartUtils::GetDartClass(DartUtils::kIOLibURL, "DirectoryException"),
398 Dart_Null(), 439 Dart_Null(),
399 3, 440 3,
400 args)); 441 args));
401 return true; 442 return true;
402 } 443 }
403 444
445
446 static bool ListNext(DirectoryListing* listing) {
447 switch (listing->top()->Next(listing)) {
448 case kListFile:
449 return listing->HandleFile(listing->CurrentPath());
Søren Gjesse 2013/06/13 11:59:20 This implies wide to UTF-8 conversion of the full
Anders Johnsen 2013/06/13 14:38:25 We should look into passing wide strings directly
450
451 case kListLink:
452 return listing->HandleLink(listing->CurrentPath());
453
454 case kListDirectory:
455 if (listing->recursive()) {
456 listing->Push(new DirectoryListingEntry(listing->top()->link()));
457 }
458 return listing->HandleDirectory(listing->CurrentPath());
459
460 case kListError:
461 return listing->HandleError(listing->CurrentPath());
462
463 case kListDone:
464 listing->Pop();
465 if (listing->IsEmpty()) {
466 listing->HandleDone();
467 return false;
468 } else {
469 return true;
470 }
471
472 default:
473 UNREACHABLE();
474 }
475 return false;
476 }
477
478 void Directory::List(DirectoryListing* listing) {
479 if (listing->error()) {
480 listing->HandleError("Invalid path");
481 listing->HandleDone();
482 } else {
483 while (ListNext(listing)) {}
484 }
485 }
486
404 } // namespace bin 487 } // namespace bin
405 } // namespace dart 488 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698