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

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

Issue 9415043: Port async file operations to be using native ports instead or an isolate (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Implemented all file operations using native ports Created 8 years, 10 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/file.h" 5 #include "bin/file.h"
6 6
7 #include "bin/builtin.h" 7 #include "bin/builtin.h"
8 #include "bin/dartutils.h" 8 #include "bin/dartutils.h"
9 9
10 #include "include/dart_api.h" 10 #include "include/dart_api.h"
(...skipping 22 matching lines...) Expand all
33 if (bytes_read < 0) { 33 if (bytes_read < 0) {
34 return false; 34 return false;
35 } 35 }
36 remaining -= bytes_read; // Reduce the number of remaining bytes. 36 remaining -= bytes_read; // Reduce the number of remaining bytes.
37 current_buffer += bytes_read; // Move the buffer forward. 37 current_buffer += bytes_read; // Move the buffer forward.
38 } 38 }
39 return true; 39 return true;
40 } 40 }
41 41
42 42
43 File::FileOpenMode File::DartModeToFileMode(int mode) {
44 ASSERT(mode == File::kDartRead ||
45 mode == File::kDartWrite ||
46 mode == File::kDartAppend);
47 if (mode == File::kDartWrite) {
48 return File::kWriteTruncate;
49 }
50 if (mode == File::kDartAppend) {
51 return File::kWrite;
52 }
53 return File::kRead;
54 }
55
56
43 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) { 57 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) {
44 // These values have to be kept in sync with the mode values of
45 // FileMode.READ, FileMode.WRITE and FileMode.APPEND in file.dart.
46 static const int kRead = 0;
47 static const int kWrite = 1;
48 static const int kAppend = 2;
49
50 Dart_EnterScope(); 58 Dart_EnterScope();
51 const char* filename = 59 const char* filename =
52 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); 60 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
53 int mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1)); 61 int mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
54 ASSERT(mode == kRead || mode == kWrite || mode == kAppend); 62 File::FileOpenMode file_mode = File::DartModeToFileMode(mode);
55 File::FileOpenMode file_mode = File::kRead;
56 if (mode == kWrite) {
57 file_mode = File::kWriteTruncate;
58 }
59 if (mode == kAppend) {
60 file_mode = File::kWrite;
61 }
62 File* file = File::Open(filename, file_mode); 63 File* file = File::Open(filename, file_mode);
63 Dart_SetReturnValue(args, Dart_NewInteger(reinterpret_cast<intptr_t>(file))); 64 Dart_SetReturnValue(args, Dart_NewInteger(reinterpret_cast<intptr_t>(file)));
64 Dart_ExitScope(); 65 Dart_ExitScope();
65 } 66 }
66 67
67 68
68 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) { 69 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) {
69 Dart_EnterScope(); 70 Dart_EnterScope();
70 const char* filename = 71 const char* filename =
71 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); 72 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } 336 }
336 337
337 338
338 void FUNCTION_NAME(File_GetStdioHandleType)(Dart_NativeArguments args) { 339 void FUNCTION_NAME(File_GetStdioHandleType)(Dart_NativeArguments args) {
339 Dart_EnterScope(); 340 Dart_EnterScope();
340 int fd = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0)); 341 int fd = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0));
341 File::StdioHandleType type = File::GetStdioHandleType(fd); 342 File::StdioHandleType type = File::GetStdioHandleType(fd);
342 Dart_SetReturnValue(args, Dart_NewInteger(type)); 343 Dart_SetReturnValue(args, Dart_NewInteger(type));
343 Dart_ExitScope(); 344 Dart_ExitScope();
344 } 345 }
346
347
348 static int64_t CObjectInt32OrInt64ToInt64(CObject* cobject) {
349 ASSERT(cobject->IsInt32OrInt64());
350 int64_t result;
351 if (cobject->IsInt32()) {
352 CObjectInt32 value(cobject);
353 result = value.Value();
354 } else {
355 CObjectInt64 value(cobject);
356 result = value.Value();
357 }
358 return result;
359 }
360
361
362 template <class T>
363 T* CObjectToPointer(CObject* cobject) {
Mads Ager (google) 2012/02/20 13:50:31 Can't we just have a: static File* CObjectToFileP
Søren Gjesse 2012/02/21 14:22:39 Done.
364 CObjectIntptr value(cobject);
365 return reinterpret_cast<T*>(value.Value());
366 }
367
368
369 static CObject* FileExistsRequest(const CObjectArray& request) {
370 if (request.Length() == 2 && request[1]->IsString()) {
371 CObjectString filename(request[1]);
372 bool result = File::Exists(filename.CString());
373 return CObject::Bool(result);
374 }
375 return CObject::False();
376 }
377
378
379 static CObject* FileCreateRequest(const CObjectArray& request) {
380 if (request.Length() == 2 && request[1]->IsString()) {
381 CObjectString filename(request[1]);
382 bool result = File::Create(filename.CString());
383 return CObject::Bool(result);
384 }
385 return CObject::False();
386 }
387
388
389 static CObject* FileOpenRequest(const CObjectArray& request) {
390 File* file = NULL;
391 if (request.Length() == 3 &&
392 request[1]->IsString() &&
393 request[2]->IsInt32()) {
394 CObjectString filename(request[1]);
395 CObjectInt32 mode(request[2]);
396 File::FileOpenMode file_mode = File::DartModeToFileMode(mode.Value());
397 file = File::Open(filename.CString(), file_mode);
398 }
399 return new CObjectIntptr(
400 CObject::NewIntptr(reinterpret_cast<intptr_t>(file)));
401 }
402
403
404 static CObject* FileDeleteRequest(const CObjectArray& request) {
405 if (request.Length() == 2 && request[1]->IsString()) {
406 CObjectString filename(request[1]);
407 bool result = File::Delete(filename.CString());
408 return CObject::Bool(result);
409 }
410 return CObject::False();
411 }
412
413
414 static CObject* FileFullPathRequest(const CObjectArray& request) {
415 if (request.Length() == 2 && request[1]->IsString()) {
416 CObjectString filename(request[1]);
417 char* path = File::GetCanonicalPath(filename.CString());
418 return new CObjectString(CObject::NewString(path));
419 }
420 return CObject::Null();
421 }
422
423
424 static CObject* FileCloseRequest(const CObjectArray& request) {
425 intptr_t return_value = -1;
426 if (request.Length() == 2 && request[1]->IsIntptr()) {
427 File* file = CObjectToPointer<File>(request[1]);
428 if (file != NULL) {
429 delete file;
430 return_value = 0;
431 }
432 }
433 return new CObjectIntptr(CObject::NewIntptr(return_value));
434 }
435
436
437 static CObject* FilePositionRequest(const CObjectArray& request) {
438 intptr_t return_value = -1;
439 if (request.Length() == 2 && request[1]->IsIntptr()) {
440 File* file = CObjectToPointer<File>(request[1]);
441 if (file != NULL) {
442 return_value = file->Position();
443 }
444 }
445 return new CObjectIntptr(CObject::NewIntptr(return_value));
446 }
447
448
449 static CObject* FileSetPositionRequest(const CObjectArray& request) {
450 bool return_value = false;
451 if (request.Length() == 3 &&
452 request[1]->IsIntptr() &&
453 request[2]->IsInt32OrInt64()) {
454 File* file = CObjectToPointer<File>(request[1]);
455 if (file != NULL) {
456 int64_t position = CObjectInt32OrInt64ToInt64(request[2]);
457 return_value = file->SetPosition(position);
458 }
459 }
460 return CObject::Bool(return_value);
461 }
462
463
464 static CObject* FileTruncateRequest(const CObjectArray& request) {
465 bool return_value = false;
466 if (request.Length() == 3 &&
467 request[1]->IsIntptr() &&
468 request[2]->IsInt32OrInt64()) {
469 File* file = CObjectToPointer<File>(request[1]);
470 if (file != NULL) {
471 int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
472 return_value = file->Truncate(length);
473 }
474 }
475 return CObject::Bool(return_value);
476 }
477
478
479 static CObject* FileLengthRequest(const CObjectArray& request) {
480 intptr_t return_value = -1;
481 if (request.Length() == 2 && request[1]->IsIntptr()) {
482 File* file = CObjectToPointer<File>(request[1]);
483 if (file != NULL) {
484 return_value = file->Length();
485 }
486 }
487 return new CObjectIntptr(CObject::NewIntptr(return_value));
488 }
489
490
491 static CObject* FileFlushRequest(const CObjectArray& request) {
492 intptr_t return_value = -1;
493 if (request.Length() == 2 && request[1]->IsIntptr()) {
494 File* file = CObjectToPointer<File>(request[1]);
495 if (file != NULL) {
496 file->Flush();
497 return_value = 0;
498 }
499 }
500 return new CObjectIntptr(CObject::NewIntptr(return_value));
501 }
502
503
504 static CObject* FileReadByteRequest(const CObjectArray& request) {
505 intptr_t return_value = -1;
506 if (request.Length() == 2 && request[1]->IsIntptr()) {
507 File* file = CObjectToPointer<File>(request[1]);
508 if (file != NULL) {
509 uint8_t buffer;
510 int bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
511 if (bytes_read == 1) {
512 return_value = static_cast<intptr_t>(buffer);
513 } else {
514 return_value = -1;
515 }
516 }
517 }
518 return new CObjectIntptr(CObject::NewIntptr(return_value));
519 }
520
521 static CObject* FileWriteByteRequest(const CObjectArray& request) {
522 intptr_t return_value = -1;
523 if (request.Length() == 3 &&
524 request[1]->IsIntptr() &&
525 request[2]->IsInt32OrInt64()) {
526 File* file = CObjectToPointer<File>(request[1]);
527 if (file != NULL) {
528 int64_t byte = CObjectInt32OrInt64ToInt64(request[2]);
529 uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
530 int bytes_written = file->Write(reinterpret_cast<void*>(&buffer), 1);
531 if (bytes_written >= 0) {
532 return_value = bytes_written;
533 }
534 }
535 }
536 return new CObjectIntptr(CObject::NewIntptr(return_value));
537 }
538
539 static CObject* FileReadListRequest(const CObjectArray& request) {
540 if (request.Length() == 3 &&
541 request[1]->IsIntptr() &&
542 request[2]->IsInt32OrInt64()) {
543 File* file = CObjectToPointer<File>(request[1]);
544 int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
545 CObjectByteArray* byte_array =
546 new CObjectByteArray(CObject::NewByteArray(length));
547 int total_bytes_read =
548 file->Read(reinterpret_cast<void*>(byte_array->Buffer()),
Mads Ager (google) 2012/02/20 13:50:31 It might be more readable to do the casting outsid
Søren Gjesse 2012/02/21 14:22:39 Done.
549 byte_array->Length());
550 CObjectArray* result = new CObjectArray(CObject::NewArray(2));
551 result->SetAt(0, new CObjectIntptr(CObject::NewIntptr(total_bytes_read)));
552 result->SetAt(1, byte_array);
553 return result;
554 }
555 return CObject::Null();
556 }
557
558
559 static CObject* FileWriteListRequest(const CObjectArray& request) {
560 if (request.Length() == 5 &&
561 request[1]->IsIntptr() &&
562 (request[2]->IsByteArray() || request[2]->IsArray()) &&
563 request[3]->IsInt32OrInt64() &&
564 request[4]->IsInt32OrInt64()) {
565 File* file = CObjectToPointer<File>(request[1]);
566 int64_t offset = CObjectInt32OrInt64ToInt64(request[3]);
567 int64_t length = CObjectInt32OrInt64ToInt64(request[4]);
568 uint8_t* buffer_start;
569 if (request[2]->IsByteArray()) {
570 CObjectByteArray byte_array(request[2]);
571 buffer_start = byte_array.Buffer() + offset;
572 } else {
573 CObjectArray array(request[2]);
574 uint8_t* buffer_start = new uint8_t[length];
575 for (int i = 0; i < length; i++) {
576 if (array[i + offset]->IsInt32OrInt64()) {
577 int64_t value = CObjectInt32OrInt64ToInt64(array[i + offset]);
578 buffer_start[i] = value & 0xFF;
579 } else {
580 // TODO(sgjesse): Return error.
Mads Ager (google) 2012/02/20 13:50:31 Is this new or did we handle this the same way bef
Søren Gjesse 2012/02/21 14:22:39 Before we used Dart_ListGetAsBytes and if there is
581 buffer_start[i] = 0;
582 }
583 }
584 offset = 0;
585 }
586 int64_t total_bytes_written =
587 file->Write(reinterpret_cast<void*>(buffer_start), length);
588 ASSERT(total_bytes_written == length);
589 return new CObjectInt64(CObject::NewInt64(total_bytes_written));
590 }
591 return CObject::Null();
592 }
593
594
595 static CObject* FileWriteStringRequest(const CObjectArray& request) {
596 if (request.Length() == 3 &&
597 request[1]->IsIntptr() &&
598 request[2]->IsString()) {
599 File* file = CObjectToPointer<File>(request[1]);
600 CObjectString str(request[2]);
601 int64_t total_bytes_written =
602 file->Write(reinterpret_cast<const void*>(str.CString()),
Mads Ager (google) 2012/02/20 13:50:31 Might be more readable to do the casting on a line
Søren Gjesse 2012/02/21 14:22:39 Done.
603 str.Length());
604 ASSERT(total_bytes_written == str.Length());
605 return new CObjectInt64(CObject::NewInt64(total_bytes_written));
606 }
607 return CObject::Null();
608 }
609
610
611 void FileService(Dart_Port dest_port_id,
612 Dart_Port reply_port_id,
613 Dart_CObject* message) {
614 CObject* response = CObject::False();
615 CObjectArray request(message);
616 if (message->type == Dart_CObject::kArray) {
617 if (request.Length() > 1 && request[0]->IsInt32()) {
618 CObjectInt32 requestType(request[0]);
619 switch (requestType.Value()) {
620 case File::kExistsRequest:
621 response = FileExistsRequest(request);
622 break;
623 case File::kCreateRequest:
624 response = FileCreateRequest(request);
625 break;
626 case File::kOpenRequest:
627 response = FileOpenRequest(request);
628 break;
629 case File::kDeleteRequest:
630 response = FileDeleteRequest(request);
631 break;
632 case File::kFullPathRequest:
633 response = FileFullPathRequest(request);
634 break;
635 case File::kCloseRequest:
636 response = FileCloseRequest(request);
637 break;
638 case File::kPositionRequest:
639 response = FilePositionRequest(request);
640 break;
641 case File::kSetPositionRequest:
642 response = FileSetPositionRequest(request);
643 break;
644 case File::kTruncateRequest:
645 response = FileTruncateRequest(request);
646 break;
647 case File::kLengthRequest:
648 response = FileLengthRequest(request);
649 break;
650 case File::kFlushRequest:
651 response = FileFlushRequest(request);
652 break;
653 case File::kReadByteRequest:
654 response = FileReadByteRequest(request);
655 break;
656 case File::kWriteByteRequest:
657 response = FileWriteByteRequest(request);
658 break;
659 case File::kReadListRequest:
660 response = FileReadListRequest(request);
661 break;
662 case File::kWriteListRequest:
663 response = FileWriteListRequest(request);
664 break;
665 case File::kWriteStringRequest:
666 response = FileWriteStringRequest(request);
667 break;
668 default:
669 UNREACHABLE();
670 }
671 }
672 }
673
674 Dart_PostCObject(reply_port_id, response->AsApiCObject());
675 }
676
677
678 void FUNCTION_NAME(File_NewServicePort)(Dart_NativeArguments args) {
679 Dart_EnterScope();
680 Dart_SetReturnValue(args, Dart_Null());
681 Dart_Port service_port = kIllegalPort;
682 service_port = Dart_NewNativePort("FileService",
Mads Ager (google) 2012/02/20 13:50:31 Are there two spaces after '=' here?
Søren Gjesse 2012/02/21 14:22:39 Yes, removed one.
683 FileService,
684 true);
685 if (service_port != kIllegalPort) {
686 // Return a send port for the service port.
687 Dart_Handle send_port = Dart_NewSendPort(service_port);
688 Dart_SetReturnValue(args, send_port);
689 }
690 Dart_ExitScope();
691 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698