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

Side by Side Diff: runtime/bin/file_impl.dart

Issue 9839053: Add error handling to random access file (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased to r5810 Created 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/file.dart ('k') | runtime/bin/file_linux.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 class _FileInputStream extends _BaseDataInputStream implements InputStream { 5 class _FileInputStream extends _BaseDataInputStream implements InputStream {
6 _FileInputStream(String name) { 6 _FileInputStream(String name) {
7 _file = new File(name); 7 _file = new File(name);
8 _data = []; 8 _data = [];
9 _position = 0; 9 _position = 0;
10 _file.onError = (e) { 10 _file.onError = (e) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 static final kFlushRequest = 11; 220 static final kFlushRequest = 11;
221 static final kReadByteRequest = 12; 221 static final kReadByteRequest = 12;
222 static final kWriteByteRequest = 13; 222 static final kWriteByteRequest = 13;
223 static final kReadListRequest = 14; 223 static final kReadListRequest = 14;
224 static final kWriteListRequest = 15; 224 static final kWriteListRequest = 15;
225 static final kWriteStringRequest = 16; 225 static final kWriteStringRequest = 16;
226 226
227 static final kSuccessResponse = 0; 227 static final kSuccessResponse = 0;
228 static final kIllegalArgumentResponse = 1; 228 static final kIllegalArgumentResponse = 1;
229 static final kOSErrorResponse = 2; 229 static final kOSErrorResponse = 2;
230 static final kFileClosedResponse = 3;
230 231
231 static List ensureFastAndSerializableBuffer( 232 static List ensureFastAndSerializableBuffer(
232 List buffer, int offset, int bytes) { 233 List buffer, int offset, int bytes) {
233 // When using the Dart C API to access raw data, using a ByteArray is 234 // When using the Dart C API to access raw data, using a ByteArray is
234 // currently much faster. This function will make a copy of the 235 // currently much faster. This function will make a copy of the
235 // supplied List to a ByteArray if it isn't already. 236 // supplied List to a ByteArray if it isn't already.
236 List outBuffer; 237 List outBuffer;
237 int outOffset = offset; 238 int outOffset = offset;
238 if (buffer is ByteArray || buffer is ObjectArray) { 239 if (buffer is ByteArray || buffer is ObjectArray) {
239 outBuffer = buffer; 240 outBuffer = buffer;
(...skipping 14 matching lines...) Expand all
254 return [outBuffer, outOffset]; 255 return [outBuffer, outOffset];
255 } 256 }
256 257
257 static exists(String name) native "File_Exists"; 258 static exists(String name) native "File_Exists";
258 static open(String name, int mode) native "File_Open"; 259 static open(String name, int mode) native "File_Open";
259 static create(String name) native "File_Create"; 260 static create(String name) native "File_Create";
260 static delete(String name) native "File_Delete"; 261 static delete(String name) native "File_Delete";
261 static fullPath(String name) native "File_FullPath"; 262 static fullPath(String name) native "File_FullPath";
262 static directory(String name) native "File_Directory"; 263 static directory(String name) native "File_Directory";
263 static int close(int id) native "File_Close"; 264 static int close(int id) native "File_Close";
264 static int readByte(int id) native "File_ReadByte"; 265 static readByte(int id) native "File_ReadByte";
265 static int readList(int id, List<int> buffer, int offset, int bytes) 266 static readList(int id, List<int> buffer, int offset, int bytes)
266 native "File_ReadList"; 267 native "File_ReadList";
267 static int writeByte(int id, int value) native "File_WriteByte"; 268 static writeByte(int id, int value) native "File_WriteByte";
268 static int writeList(int id, List<int> buffer, int offset, int bytes) { 269 static writeList(int id, List<int> buffer, int offset, int bytes) {
269 List result = 270 List result =
270 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); 271 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes);
271 List outBuffer = result[0]; 272 List outBuffer = result[0];
272 int outOffset = result[1]; 273 int outOffset = result[1];
273 return writeListNative(id, outBuffer, outOffset, bytes); 274 return writeListNative(id, outBuffer, outOffset, bytes);
274 } 275 }
275 static int writeListNative(int id, List<int> buffer, int offset, int bytes) 276 static writeListNative(int id, List<int> buffer, int offset, int bytes)
276 native "File_WriteList"; 277 native "File_WriteList";
277 static int writeString(int id, String string) native "File_WriteString"; 278 static writeString(int id, String string) native "File_WriteString";
278 static int position(int id) native "File_Position"; 279 static position(int id) native "File_Position";
279 static bool setPosition(int id, int position) native "File_SetPosition"; 280 static setPosition(int id, int position) native "File_SetPosition";
280 static bool truncate(int id, int length) native "File_Truncate"; 281 static truncate(int id, int length) native "File_Truncate";
281 static int length(int id) native "File_Length"; 282 static length(int id) native "File_Length";
282 static int flush(int id) native "File_Flush"; 283 static flush(int id) native "File_Flush";
283 static int openStdio(int fd) native "File_OpenStdio"; 284 static int openStdio(int fd) native "File_OpenStdio";
284 static SendPort newServicePort() native "File_NewServicePort"; 285 static SendPort newServicePort() native "File_NewServicePort";
285 286
286 static bool checkedExists(String name) { 287 static bool checkedExists(String name) {
287 if (name is !String) { 288 if (name is !String) {
288 throw new IllegalArgumentException(); 289 throw new IllegalArgumentException();
289 } 290 }
290 var result = exists(name); 291 var result = exists(name);
291 if (result is OSError) { 292 if (result is OSError) {
292 throw new FileIOException("Cannot check existence of file", result); 293 throw new FileIOException("Cannot check existence of file", result);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 return 0; 357 return 0;
357 } 358 }
358 359
359 static int checkedWriteString(int id, String string) { 360 static int checkedWriteString(int id, String string) {
360 if (string is !String) return -1; 361 if (string is !String) return -1;
361 return writeString(id, string); 362 return writeString(id, string);
362 } 363 }
363 364
364 } 365 }
365 366
367 // Base class for _File and _RandomAccessFile with shared functions.
368 class _FileBase {
369 bool _isErrorResponse(response) {
370 return response is List && response[0] != _FileUtils.kSuccessResponse;
371 }
372
373 bool _reportError(response, String message) {
374 assert(_isErrorResponse(response));
375 if (_onError != null) {
376 switch (response[0]) {
377 case _FileUtils.kIllegalArgumentResponse:
378 _onError(new IllegalArgumentException());
379 break;
380 case _FileUtils.kOSErrorResponse:
381 _onError(new FileIOException(message,
382 new OSError(response[2], response[1])));
383 break;
384 case _FileUtils.kFileClosedResponse:
385 _onError(new FileIOException("File closed"));
386 break;
387 default:
388 _onError(new Exception("Unknown error"));
389 break;
390 }
391 }
392 }
393
394 void set onError(void handler(Exception e)) {
395 _onError = handler;
396 }
397
398 _checkNotAsync() {
399 if (_asyncUsed) {
400 throw new FileIOException(
401 "Mixed use of synchronous and asynchronous API");
402 }
403 }
404
405 bool _asyncUsed = false;
406 Function _onError;
407 }
366 408
367 // Class for encapsulating the native implementation of files. 409 // Class for encapsulating the native implementation of files.
368 class _File implements File { 410 class _File extends _FileBase implements File {
369 // Constructor for file. 411 // Constructor for file.
370 _File(String this._name) : _asyncUsed = false; 412 _File(String this._name);
371 413
372 void exists(void callback(bool exists)) { 414 void exists(void callback(bool exists)) {
373 _ensureFileService(); 415 _ensureFileService();
374 _asyncUsed = true; 416 _asyncUsed = true;
375 List request = new List(2); 417 List request = new List(2);
376 request[0] = _FileUtils.kExistsRequest; 418 request[0] = _FileUtils.kExistsRequest;
377 request[1] = _name; 419 request[1] = _name;
378 _fileService.call(request).then((response) { 420 _fileService.call(request).then((response) {
379 if (_isErrorResponse(response)) { 421 if (_isErrorResponse(response)) {
380 _reportError(response, "Cannot open file"); 422 _reportError(response, "Cannot open file");
381 } else { 423 } else {
382 callback(response); 424 callback(response);
383 } 425 }
384 }); 426 });
385 } 427 }
386 428
387 bool existsSync() { 429 bool existsSync() {
388 if (_asyncUsed) { 430 _checkNotAsync();
389 throw new FileIOException(
390 "Mixed use of synchronous and asynchronous API");
391 }
392 return _FileUtils.checkedExists(_name); 431 return _FileUtils.checkedExists(_name);
393 } 432 }
394 433
395 void create(void callback()) { 434 void create(void callback()) {
396 _ensureFileService(); 435 _ensureFileService();
397 _asyncUsed = true; 436 _asyncUsed = true;
398 List request = new List(2); 437 List request = new List(2);
399 request[0] = _FileUtils.kCreateRequest; 438 request[0] = _FileUtils.kCreateRequest;
400 request[1] = _name; 439 request[1] = _name;
401 _fileService.call(request).then((response) { 440 _fileService.call(request).then((response) {
402 if (_isErrorResponse(response)) { 441 if (_isErrorResponse(response)) {
403 _reportError(response, "Cannot create file"); 442 _reportError(response, "Cannot create file");
404 } else { 443 } else {
405 callback(); 444 callback();
406 } 445 }
407 }); 446 });
408 } 447 }
409 448
410 void createSync() { 449 void createSync() {
411 if (_asyncUsed) { 450 _checkNotAsync();
412 throw new FileIOException(
413 "Mixed use of synchronous and asynchronous API");
414 }
415 bool created = _FileUtils.checkedCreate(_name); 451 bool created = _FileUtils.checkedCreate(_name);
416 if (!created) { 452 if (!created) {
417 throw new FileIOException("Cannot create file: $_name"); 453 throw new FileIOException("Cannot create file: $_name");
418 } 454 }
419 } 455 }
420 456
421 void delete(void callback()) { 457 void delete(void callback()) {
422 _ensureFileService(); 458 _ensureFileService();
423 _asyncUsed = true; 459 _asyncUsed = true;
424 List request = new List(2); 460 List request = new List(2);
425 request[0] = _FileUtils.kDeleteRequest; 461 request[0] = _FileUtils.kDeleteRequest;
426 request[1] = _name; 462 request[1] = _name;
427 _fileService.call(request).then((response) { 463 _fileService.call(request).then((response) {
428 if (_isErrorResponse(response)) { 464 if (_isErrorResponse(response)) {
429 _reportError(response, "Cannot delete file"); 465 _reportError(response, "Cannot delete file");
430 } else { 466 } else {
431 callback(); 467 callback();
432 } 468 }
433 }); 469 });
434 } 470 }
435 471
436 void deleteSync() { 472 void deleteSync() {
437 if (_asyncUsed) { 473 _checkNotAsync();
438 throw new FileIOException(
439 "Mixed use of synchronous and asynchronous API");
440 }
441 _FileUtils.checkedDelete(_name); 474 _FileUtils.checkedDelete(_name);
442 } 475 }
443 476
444 void directory(void callback(Directory dir)) { 477 void directory(void callback(Directory dir)) {
445 _ensureFileService(); 478 _ensureFileService();
446 _asyncUsed = true; 479 _asyncUsed = true;
447 List request = new List(2); 480 List request = new List(2);
448 request[0] = _FileUtils.kDirectoryRequest; 481 request[0] = _FileUtils.kDirectoryRequest;
449 request[1] = _name; 482 request[1] = _name;
450 _fileService.call(request).then((response) { 483 _fileService.call(request).then((response) {
451 if (_isErrorResponse(response)) { 484 if (_isErrorResponse(response)) {
452 _reportError(response, "Cannot retrieve directory for file"); 485 _reportError(response, "Cannot retrieve directory for file");
453 } else { 486 } else {
454 callback(new Directory(response)); 487 callback(new Directory(response));
455 } 488 }
456 }); 489 });
457 } 490 }
458 491
459 Directory directorySync() { 492 Directory directorySync() {
460 if (_asyncUsed) { 493 _checkNotAsync();
461 throw new FileIOException(
462 "Mixed use of synchronous and asynchronous API");
463 }
464 _FileUtils.checkedDirectory(_name); 494 _FileUtils.checkedDirectory(_name);
465 return new Directory(_FileUtils.directory(_name)); 495 return new Directory(_FileUtils.directory(_name));
466 } 496 }
467 497
468 void open(FileMode mode, void callback(RandomAccessFile file)) { 498 void open(FileMode mode, void callback(RandomAccessFile file)) {
469 _ensureFileService(); 499 _ensureFileService();
470 _asyncUsed = true; 500 _asyncUsed = true;
471 if (mode != FileMode.READ && 501 if (mode != FileMode.READ &&
472 mode != FileMode.WRITE && 502 mode != FileMode.WRITE &&
473 mode != FileMode.APPEND) { 503 mode != FileMode.APPEND) {
474 if (_onError != null) { 504 if (_onError != null) {
475 _onError(new IllegalArgumentException()); 505 _onError(new IllegalArgumentException());
476 return; 506 return;
477 } 507 }
478 } 508 }
479 List request = new List(3); 509 List request = new List(3);
480 request[0] = _FileUtils.kOpenRequest; 510 request[0] = _FileUtils.kOpenRequest;
481 request[1] = _name; 511 request[1] = _name;
482 request[2] = mode._mode; // Direct int value for serialization. 512 request[2] = mode._mode; // Direct int value for serialization.
483 _fileService.call(request).then((response) { 513 _fileService.call(request).then((response) {
484 if (_isErrorResponse(response)) { 514 if (_isErrorResponse(response)) {
485 _reportError(response, "Cannot open file"); 515 _reportError(response, "Cannot open file");
486 } else { 516 } else {
487 callback(new _RandomAccessFile(response, _name)); 517 callback(new _RandomAccessFile(response, _name));
488 } 518 }
489 }); 519 });
490 } 520 }
491 521
492 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { 522 RandomAccessFile openSync([FileMode mode = FileMode.READ]) {
493 if (_asyncUsed) { 523 _checkNotAsync();
494 throw new FileIOException(
495 "Mixed use of synchronous and asynchronous API");
496 }
497 if (mode != FileMode.READ && 524 if (mode != FileMode.READ &&
498 mode != FileMode.WRITE && 525 mode != FileMode.WRITE &&
499 mode != FileMode.APPEND) { 526 mode != FileMode.APPEND) {
500 throw new FileIOException("Unknown file mode. Use FileMode.READ, " 527 throw new FileIOException("Unknown file mode. Use FileMode.READ, "
501 "FileMode.WRITE or FileMode.APPEND."); 528 "FileMode.WRITE or FileMode.APPEND.");
502 } 529 }
503 var id = _FileUtils.checkedOpen(_name, mode._mode); 530 var id = _FileUtils.checkedOpen(_name, mode._mode);
504 assert(id != 0); 531 assert(id != 0);
505 return new _RandomAccessFile(id, _name); 532 return new _RandomAccessFile(id, _name);
506 } 533 }
(...skipping 15 matching lines...) Expand all
522 _fileService.call(request).then((response) { 549 _fileService.call(request).then((response) {
523 if (_isErrorResponse(response)) { 550 if (_isErrorResponse(response)) {
524 _reportError(response, "Cannot retrieve full path"); 551 _reportError(response, "Cannot retrieve full path");
525 } else { 552 } else {
526 callback(response); 553 callback(response);
527 } 554 }
528 }); 555 });
529 } 556 }
530 557
531 String fullPathSync() { 558 String fullPathSync() {
532 if (_asyncUsed) { 559 _checkNotAsync();
533 throw new FileIOException(
534 "Mixed use of synchronous and asynchronous API");
535 }
536 return _FileUtils.checkedFullPath(_name); 560 return _FileUtils.checkedFullPath(_name);
537 } 561 }
538 562
539 InputStream openInputStream() { 563 InputStream openInputStream() {
540 return new _FileInputStream(_name); 564 return new _FileInputStream(_name);
541 } 565 }
542 566
543 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) { 567 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) {
544 if (mode != FileMode.WRITE && 568 if (mode != FileMode.WRITE &&
545 mode != FileMode.APPEND) { 569 mode != FileMode.APPEND) {
546 throw new FileIOException( 570 throw new FileIOException(
547 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); 571 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND");
548 } 572 }
549 return new _FileOutputStream(_name, mode); 573 return new _FileOutputStream(_name, mode);
550 } 574 }
551 575
552 void readAsBytes(void callback(List<int> bytes)) { 576 void readAsBytes(void callback(List<int> bytes)) {
577 _ensureFileService();
553 _asyncUsed = true; 578 _asyncUsed = true;
554 var chunks = new _BufferList(); 579 var chunks = new _BufferList();
555 var stream = openInputStream(); 580 var stream = openInputStream();
556 stream.onClosed = () { 581 stream.onClosed = () {
557 callback(chunks.readBytes(chunks.length)); 582 callback(chunks.readBytes(chunks.length));
558 }; 583 };
559 stream.onData = () { 584 stream.onData = () {
560 var chunk = stream.read(); 585 var chunk = stream.read();
561 chunks.add(chunk); 586 chunks.add(chunk);
562 }; 587 };
563 stream.onError = (e) { 588 stream.onError = (e) {
564 if (_onError != null) { 589 if (_onError != null) {
565 _onError(e); 590 _onError(e);
566 } 591 }
567 }; 592 };
568 } 593 }
569 594
570 List<int> readAsBytesSync() { 595 List<int> readAsBytesSync() {
571 if (_asyncUsed) { 596 _checkNotAsync();
572 throw new FileIOException(
573 "Mixed use of synchronous and asynchronous API");
574 }
575 var opened = openSync(); 597 var opened = openSync();
576 var length = opened.lengthSync(); 598 var length = opened.lengthSync();
577 var result = new ByteArray(length); 599 var result = new ByteArray(length);
578 var read = opened.readListSync(result, 0, length); 600 var read = opened.readListSync(result, 0, length);
579 if (read != length) { 601 if (read != length) {
580 throw new FileIOException("Failed to read file"); 602 throw new FileIOException("Failed to read file");
581 } 603 }
582 opened.closeSync(); 604 opened.closeSync();
583 return result; 605 return result;
584 } 606 }
585 607
586 void readAsText(Encoding encoding, void callback(String text)) { 608 void readAsText(Encoding encoding, void callback(String text)) {
609 _ensureFileService();
587 _asyncUsed = true; 610 _asyncUsed = true;
588 var decoder = _StringDecoders.decoder(encoding); 611 var decoder = _StringDecoders.decoder(encoding);
589 readAsBytes((bytes) { 612 readAsBytes((bytes) {
590 try { 613 try {
591 decoder.write(bytes); 614 decoder.write(bytes);
592 } catch (var e) { 615 } catch (var e) {
593 if (_onError != null) { 616 if (_onError != null) {
594 _onError(e); 617 _onError(e);
595 return; 618 return;
596 } 619 }
597 } 620 }
598 callback(decoder.decoded); 621 callback(decoder.decoded);
599 }); 622 });
600 } 623 }
601 624
602 String readAsTextSync([Encoding encoding = Encoding.UTF_8]) { 625 String readAsTextSync([Encoding encoding = Encoding.UTF_8]) {
603 if (_asyncUsed) { 626 _checkNotAsync();
604 throw new FileIOException(
605 "Mixed use of synchronous and asynchronous API");
606 }
607 var decoder = _StringDecoders.decoder(encoding); 627 var decoder = _StringDecoders.decoder(encoding);
608 List<int> bytes = readAsBytesSync(); 628 List<int> bytes = readAsBytesSync();
609 decoder.write(bytes); 629 decoder.write(bytes);
610 return decoder.decoded; 630 return decoder.decoded;
611 } 631 }
612 632
613 List<String> _getDecodedLines(_StringDecoder decoder) { 633 List<String> _getDecodedLines(_StringDecoder decoder) {
614 List<String> result = []; 634 List<String> result = [];
615 var line = decoder.decodedLine; 635 var line = decoder.decodedLine;
616 while (line != null) { 636 while (line != null) {
617 result.add(line); 637 result.add(line);
618 line = decoder.decodedLine; 638 line = decoder.decodedLine;
619 } 639 }
620 // If there is more data with no terminating line break we treat 640 // If there is more data with no terminating line break we treat
621 // it as the last line. 641 // it as the last line.
622 var data = decoder.decoded; 642 var data = decoder.decoded;
623 if (data != null) { 643 if (data != null) {
624 result.add(data); 644 result.add(data);
625 } 645 }
626 return result; 646 return result;
627 } 647 }
628 648
629 void readAsLines(Encoding encoding, void callback(List<String> lines)) { 649 void readAsLines(Encoding encoding, void callback(List<String> lines)) {
650 _ensureFileService();
630 _asyncUsed = true; 651 _asyncUsed = true;
631 var decoder = _StringDecoders.decoder(encoding); 652 var decoder = _StringDecoders.decoder(encoding);
632 readAsBytes((bytes) { 653 readAsBytes((bytes) {
633 try { 654 try {
634 decoder.write(bytes); 655 decoder.write(bytes);
635 } catch (var e) { 656 } catch (var e) {
636 if (_onError != null) { 657 if (_onError != null) {
637 _onError(e); 658 _onError(e);
638 return; 659 return;
639 } 660 }
640 } 661 }
641 callback(_getDecodedLines(decoder)); 662 callback(_getDecodedLines(decoder));
642 }); 663 });
643 } 664 }
644 665
645 List<String> readAsLinesSync([Encoding encoding = Encoding.UTF_8]) { 666 List<String> readAsLinesSync([Encoding encoding = Encoding.UTF_8]) {
646 if (_asyncUsed) { 667 _checkNotAsync();
647 throw new FileIOException(
648 "Mixed use of synchronous and asynchronous API");
649 }
650 var decoder = _StringDecoders.decoder(encoding); 668 var decoder = _StringDecoders.decoder(encoding);
651 List<int> bytes = readAsBytesSync(); 669 List<int> bytes = readAsBytesSync();
652 decoder.write(bytes); 670 decoder.write(bytes);
653 return _getDecodedLines(decoder); 671 return _getDecodedLines(decoder);
654 } 672 }
655 673
656 String get name() => _name; 674 String get name() => _name;
657 675
658 void set onError(void handler(Exception error)) {
659 _onError = handler;
660 }
661
662 void _ensureFileService() { 676 void _ensureFileService() {
663 if (_fileService == null) { 677 if (_fileService == null) {
664 _fileService = _FileUtils.newServicePort(); 678 _fileService = _FileUtils.newServicePort();
665 } 679 }
666 } 680 }
667 681
668 bool _isErrorResponse(response) {
669 return response is List && response[0] != _FileUtils.kSuccessResponse;
670 }
671
672 bool _reportError(response, String message) {
673 assert(_isErrorResponse(response));
674 if (_onError != null) {
675 switch (response[0]) {
676 case _FileUtils.kIllegalArgumentResponse:
677 _onError(new IllegalArgumentException());
678 break;
679 case _FileUtils.kOSErrorResponse:
680 _onError(new FileIOException(message,
681 new OSError(response[2], response[1])));
682 break;
683 default:
684 _onError(new Exception("Unknown error"));
685 }
686 }
687 }
688
689 String _name; 682 String _name;
690 bool _asyncUsed;
691 683
692 SendPort _fileService; 684 SendPort _fileService;
693
694 Function _onError;
695 } 685 }
696 686
697 687
698 class _RandomAccessFile implements RandomAccessFile { 688 class _RandomAccessFile extends _FileBase implements RandomAccessFile {
699 _RandomAccessFile(int this._id, String this._name) : _asyncUsed = false; 689 _RandomAccessFile(int this._id, String this._name);
700 690
701 void close(void callback()) { 691 void close(void callback()) {
702 if (_id == 0) return; 692 if (_id == 0) return;
703 _ensureFileService(); 693 _ensureFileService();
704 _asyncUsed = true; 694 _asyncUsed = true;
705 List request = new List(2); 695 List request = new List(2);
706 request[0] = _FileUtils.kCloseRequest; 696 request[0] = _FileUtils.kCloseRequest;
707 request[1] = _id; 697 request[1] = _id;
708 // Set the id_ to 0 (NULL) to ensure the no more async requests 698 // Set the id_ to 0 (NULL) to ensure the no more async requests
709 // can be issues for this file. 699 // can be issues for this file.
710 _id = 0; 700 _id = 0;
711 _fileService.call(request).then((result) { 701 _fileService.call(request).then((result) {
712 if (result != -1) { 702 if (result != -1) {
713 _id = result; 703 _id = result;
714 callback(); 704 callback();
715 } else if (_onError != null) { 705 } else if (_onError != null) {
716 _onError("Cannot close file: $_name"); 706 _onError("Cannot close file: $_name");
717 } 707 }
718 }); 708 });
719 } 709 }
720 710
721 void closeSync() { 711 void closeSync() {
722 if (_asyncUsed) { 712 _checkNotAsync();
723 throw new FileIOException(
724 "Mixed use of synchronous and asynchronous API");
725 }
726 var id = _FileUtils.close(_id); 713 var id = _FileUtils.close(_id);
727 if (id == -1) { 714 if (id == -1) {
728 throw new FileIOException("Cannot close file: $_name"); 715 throw new FileIOException("Cannot close file: $_name");
729 } 716 }
730 _id = id; 717 _id = id;
731 } 718 }
732 719
733 void readByte(void callback(int byte)) { 720 void readByte(void callback(int byte)) {
734 _ensureFileService(); 721 _ensureFileService();
735 _asyncUsed = true; 722 _asyncUsed = true;
736 List request = new List(2); 723 List request = new List(2);
737 request[0] = _FileUtils.kReadByteRequest; 724 request[0] = _FileUtils.kReadByteRequest;
738 request[1] = _id; 725 request[1] = _id;
739 _fileService.call(request).then((result) { 726 _fileService.call(request).then((response) {
740 if (result != -1) { 727 if (_isErrorResponse(response)) {
741 callback(result); 728 _reportError(response, "readByte failed");
742 } else if (_onError != null) { 729 } else {
743 _onError("readByte failed"); 730 callback(response);
744 } 731 }
745 }); 732 });
746 } 733 }
747 734
748 int readByteSync() { 735 int readByteSync() {
749 if (_asyncUsed) { 736 _checkNotAsyncAndNotClosed();
750 throw new FileIOException( 737 var result = _FileUtils.readByte(_id);
751 "Mixed use of synchronous and asynchronous API"); 738 if (result is OSError) {
752 } 739 throw new FileIOException("readByte failed", result);
753 int result = _FileUtils.readByte(_id);
754 if (result == -1) {
755 throw new FileIOException("readByte failed");
756 } 740 }
757 return result; 741 return result;
758 } 742 }
759 743
760 void readList(List<int> buffer, int offset, int bytes, 744 void readList(List<int> buffer, int offset, int bytes,
761 void callback(int read)) { 745 void callback(int read)) {
762 _ensureFileService(); 746 _ensureFileService();
763 _asyncUsed = true; 747 _asyncUsed = true;
764 if (buffer is !List || offset is !int || bytes is !int) { 748 if (buffer is !List || offset is !int || bytes is !int) {
765 if (_onError != null) { 749 if (_onError != null) {
766 _onError("Invalid arguments to readList"); 750 _onError("Invalid arguments to readList");
767 } 751 }
768 return; 752 return;
769 }; 753 };
770 List request = new List(3); 754 List request = new List(3);
771 request[0] = _FileUtils.kReadListRequest; 755 request[0] = _FileUtils.kReadListRequest;
772 request[1] = _id; 756 request[1] = _id;
773 request[2] = bytes; 757 request[2] = bytes;
774 _fileService.call(request).then((result) { 758 _fileService.call(request).then((response) {
775 if (result is List && result.length == 2 && result[0] != -1) { 759 if (_isErrorResponse(response)) {
776 var read = result[0]; 760 _reportError(response, "readList failed");
777 var data = result[1]; 761 } else {
762 var read = response[1];
763 var data = response[2];
778 buffer.setRange(offset, read, data); 764 buffer.setRange(offset, read, data);
779 callback(read); 765 callback(read);
780 return;
781 } else if (_onError != null) {
782 _onError(result is String ? result : "readList failed");
783 } 766 }
784 }); 767 });
785 } 768 }
786 769
787 int readListSync(List<int> buffer, int offset, int bytes) { 770 int readListSync(List<int> buffer, int offset, int bytes) {
788 if (_asyncUsed) { 771 _checkNotAsyncAndNotClosed();
789 throw new FileIOException(
790 "Mixed use of synchronous and asynchronous API");
791 }
792 if (buffer is !List || offset is !int || bytes is !int) { 772 if (buffer is !List || offset is !int || bytes is !int) {
793 throw new FileIOException("Invalid arguments to readList"); 773 throw new FileIOException("Invalid arguments to readList");
794 } 774 }
795 if (bytes == 0) return 0; 775 if (bytes == 0) return 0;
796 int index = 776 int index =
797 _FileUtils.checkReadWriteListArguments(buffer.length, offset, bytes); 777 _FileUtils.checkReadWriteListArguments(buffer.length, offset, bytes);
798 if (index != 0) { 778 if (index != 0) {
799 throw new IndexOutOfRangeException(index); 779 throw new IndexOutOfRangeException(index);
800 } 780 }
801 int result = _FileUtils.readList(_id, buffer, offset, bytes); 781 var result = _FileUtils.readList(_id, buffer, offset, bytes);
802 if (result == -1) { 782 if (result is OSError) {
803 throw new FileIOException("readList failed"); 783 throw new FileIOException("readList failed", result);
804 } 784 }
805 return result; 785 return result;
806 } 786 }
807 787
808 void writeByte(int value) { 788 void writeByte(int value) {
809 _ensureFileService(); 789 _ensureFileService();
810 _asyncUsed = true; 790 _asyncUsed = true;
811 if (value is !int) { 791 if (value is !int) {
812 if (_onError != null) { 792 if (_onError != null) {
813 _onError("Invalid argument to writeByte"); 793 _onError("Invalid argument to writeByte");
814 } 794 }
815 return; 795 return;
816 } 796 }
817 List request = new List(3); 797 List request = new List(3);
818 request[0] = _FileUtils.kWriteByteRequest; 798 request[0] = _FileUtils.kWriteByteRequest;
819 request[1] = _id; 799 request[1] = _id;
820 request[2] = value; 800 request[2] = value;
821 _writeEnqueued(); 801 _writeEnqueued();
822 _fileService.call(request).then((result) { 802 _fileService.call(request).then((response) {
823 _writeCompleted(); 803 _writeCompleted();
824 if (result == -1 && _onError !== null) { 804 if (_isErrorResponse(response)) {
825 _onError("writeByte failed"); 805 _reportError(response, "writeByte failed");
826 } 806 }
827 }); 807 });
828 } 808 }
829 809
830 int writeByteSync(int value) { 810 int writeByteSync(int value) {
831 if (_asyncUsed) { 811 _checkNotAsyncAndNotClosed();
832 throw new FileIOException(
833 "Mixed use of synchronous and asynchronous API");
834 }
835 if (value is !int) { 812 if (value is !int) {
836 throw new FileIOException("Invalid argument to writeByte"); 813 throw new FileIOException("Invalid argument to writeByte");
837 } 814 }
838 int result = _FileUtils.writeByte(_id, value); 815 var result = _FileUtils.writeByte(_id, value);
839 if (result == -1) { 816 if (result is OSError) {
840 throw new FileIOException("writeByte failed"); 817 throw new FileIOException("writeByte failed", result);
841 } 818 }
842 return result; 819 return result;
843 } 820 }
844 821
845 void writeList(List<int> buffer, int offset, int bytes) { 822 void writeList(List<int> buffer, int offset, int bytes) {
846 _ensureFileService(); 823 _ensureFileService();
847 _asyncUsed = true; 824 _asyncUsed = true;
848 if (buffer is !List || offset is !int || bytes is !int) { 825 if (buffer is !List || offset is !int || bytes is !int) {
849 if (_onError != null) { 826 if (_onError != null) {
850 _onError("Invalid arguments to writeList"); 827 _onError("Invalid arguments to writeList");
851 } 828 }
852 return; 829 return;
853 } 830 }
854 831
855 List result = 832 List result =
856 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); 833 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes);
857 List outBuffer = result[0]; 834 List outBuffer = result[0];
858 int outOffset = result[1]; 835 int outOffset = result[1];
859 836
860 List request = new List(5); 837 List request = new List(5);
861 request[0] = _FileUtils.kWriteListRequest; 838 request[0] = _FileUtils.kWriteListRequest;
862 request[1] = _id; 839 request[1] = _id;
863 request[2] = outBuffer; 840 request[2] = outBuffer;
864 request[3] = outOffset; 841 request[3] = outOffset;
865 request[4] = bytes; 842 request[4] = bytes;
866 _writeEnqueued(); 843 _writeEnqueued();
867 _fileService.call(request).then((result) { 844 _fileService.call(request).then((response) {
868 _writeCompleted(); 845 _writeCompleted();
869 if (result == -1 && _onError !== null) { 846 if (_isErrorResponse(response)) {
870 _onError("writeList failed"); 847 _reportError(response, "writeList failed");
871 } 848 }
872 }); 849 });
873 } 850 }
874 851
875 int writeListSync(List<int> buffer, int offset, int bytes) { 852 int writeListSync(List<int> buffer, int offset, int bytes) {
876 if (_asyncUsed) { 853 _checkNotAsyncAndNotClosed();
877 throw new FileIOException(
878 "Mixed use of synchronous and asynchronous API");
879 }
880 if (buffer is !List || offset is !int || bytes is !int) { 854 if (buffer is !List || offset is !int || bytes is !int) {
881 throw new FileIOException("Invalid arguments to writeList"); 855 throw new FileIOException("Invalid arguments to writeList");
882 } 856 }
883 if (bytes == 0) return 0; 857 if (bytes == 0) return 0;
884 int index = 858 int index =
885 _FileUtils.checkReadWriteListArguments(buffer.length, offset, bytes); 859 _FileUtils.checkReadWriteListArguments(buffer.length, offset, bytes);
886 if (index != 0) { 860 if (index != 0) {
887 throw new IndexOutOfRangeException(index); 861 throw new IndexOutOfRangeException(index);
888 } 862 }
889 int result = _FileUtils.writeList(_id, buffer, offset, bytes); 863 var result = _FileUtils.writeList(_id, buffer, offset, bytes);
890 if (result == -1) { 864 if (result is OSError) {
891 throw new FileIOException("writeList failed"); 865 throw new FileIOException("writeList failed", result);
892 } 866 }
893 return result; 867 return result;
894 } 868 }
895 869
896 void writeString(String string, [Encoding encoding = Encoding.UTF_8]) { 870 void writeString(String string, [Encoding encoding = Encoding.UTF_8]) {
897 _ensureFileService(); 871 _ensureFileService();
898 _asyncUsed = true; 872 _asyncUsed = true;
899 List request = new List(3); 873 List request = new List(3);
900 request[0] = _FileUtils.kWriteStringRequest; 874 request[0] = _FileUtils.kWriteStringRequest;
901 request[1] = _id; 875 request[1] = _id;
902 request[2] = string; 876 request[2] = string;
903 _writeEnqueued(); 877 _writeEnqueued();
904 _fileService.call(request).then((result) { 878 _fileService.call(request).then((response) {
905 _writeCompleted(); 879 _writeCompleted();
906 if (result == -1 && _onError !== null) { 880 if (_isErrorResponse(response)) {
907 _onError("writeString failed"); 881 _reportError(response, "writeString failed");
908 } 882 }
909 }); 883 });
910 } 884 }
911 885
912 int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) { 886 int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) {
913 if (_asyncUsed) { 887 _checkNotAsyncAndNotClosed();
914 throw new FileIOException( 888 var result = _FileUtils.checkedWriteString(_id, string);
915 "Mixed use of synchronous and asynchronous API"); 889 if (result is OSError) {
916 } 890 throw new FileIOException("writeString failed", result);
917 int result = _FileUtils.checkedWriteString(_id, string);
918 if (result == -1) {
919 throw new FileIOException("writeString failed");
920 } 891 }
921 return result; 892 return result;
922 } 893 }
923 894
924 void position(void callback(int position)) { 895 void position(void callback(int position)) {
925 _ensureFileService(); 896 _ensureFileService();
926 _asyncUsed = true; 897 _asyncUsed = true;
927 List request = new List(2); 898 List request = new List(2);
928 request[0] = _FileUtils.kPositionRequest; 899 request[0] = _FileUtils.kPositionRequest;
929 request[1] = _id; 900 request[1] = _id;
930 _fileService.call(request).then((result) { 901 _fileService.call(request).then((response) {
931 if (result != -1) { 902 if (_isErrorResponse(response)) {
932 callback(result); 903 _reportError(response, "position failed");
933 } else if (_onError != null) { 904 } else {
934 _onError("position failed"); 905 callback(response);
935 } 906 }
936 }); 907 });
937 } 908 }
938 909
939 int positionSync() { 910 int positionSync() {
940 if (_asyncUsed) { 911 _checkNotAsyncAndNotClosed();
941 throw new FileIOException( 912 var result = _FileUtils.position(_id);
942 "Mixed use of synchronous and asynchronous API"); 913 if (result is OSError) {
943 } 914 throw new FileIOException("position failed", result);
944 int result = _FileUtils.position(_id);
945 if (result == -1) {
946 throw new FileIOException("position failed");
947 } 915 }
948 return result; 916 return result;
949 } 917 }
950 918
951 void setPosition(int position, void callback()) { 919 void setPosition(int position, void callback()) {
952 _ensureFileService(); 920 _ensureFileService();
953 _asyncUsed = true; 921 _asyncUsed = true;
954 List request = new List(3); 922 List request = new List(3);
955 request[0] = _FileUtils.kSetPositionRequest; 923 request[0] = _FileUtils.kSetPositionRequest;
956 request[1] = _id; 924 request[1] = _id;
957 request[2] = position; 925 request[2] = position;
958 _fileService.call(request).then((result) { 926 _fileService.call(request).then((response) {
959 if (result) { 927 if (_isErrorResponse(response)) {
928 _reportError(response, "setPosition failed");
929 } else {
960 callback(); 930 callback();
961 } else if (_onError != null) {
962 _onError("setPosition failed");
963 } 931 }
964 }); 932 });
965 } 933 }
966 934
967 void setPositionSync(int position) { 935 void setPositionSync(int position) {
968 _ensureFileService(); 936 _checkNotAsyncAndNotClosed();
969 if (_asyncUsed) { 937 var result = _FileUtils.setPosition(_id, position);
970 throw new FileIOException( 938 if (result is OSError) {
971 "Mixed use of synchronous and asynchronous API"); 939 throw new FileIOException("setPosition failed", result);
972 }
973 bool result = _FileUtils.setPosition(_id, position);
974 if (result == false) {
975 throw new FileIOException("setPosition failed");
976 } 940 }
977 } 941 }
978 942
979 void truncate(int length, void callback()) { 943 void truncate(int length, void callback()) {
980 _ensureFileService(); 944 _ensureFileService();
981 _asyncUsed = true; 945 _asyncUsed = true;
982 List request = new List(3); 946 List request = new List(3);
983 request[0] = _FileUtils.kTruncateRequest; 947 request[0] = _FileUtils.kTruncateRequest;
984 request[1] = _id; 948 request[1] = _id;
985 request[2] = length; 949 request[2] = length;
986 _fileService.call(request).then((result) { 950 _fileService.call(request).then((response) {
987 if (result) { 951 if (_isErrorResponse(response)) {
952 _reportError(response, "truncate failed");
953 } else {
988 callback(); 954 callback();
989 } else if (_onError != null) {
990 _onError("truncate failed");
991 } 955 }
992 }); 956 });
993 } 957 }
994 958
995 void truncateSync(int length) { 959 void truncateSync(int length) {
996 if (_asyncUsed) { 960 _checkNotAsyncAndNotClosed();
997 throw new FileIOException( 961 var result = _FileUtils.truncate(_id, length);
998 "Mixed use of synchronous and asynchronous API"); 962 if (result is OSError) {
999 } 963 throw new FileIOException("truncate failed", result);
1000 bool result = _FileUtils.truncate(_id, length);
1001 if (result == false) {
1002 throw new FileIOException("truncate failed");
1003 } 964 }
1004 } 965 }
1005 966
1006 void length(void callback(int length)) { 967 void length(void callback(int length)) {
1007 _ensureFileService(); 968 _ensureFileService();
1008 _asyncUsed = true; 969 _asyncUsed = true;
1009 List request = new List(2); 970 List request = new List(2);
1010 request[0] = _FileUtils.kLengthRequest; 971 request[0] = _FileUtils.kLengthRequest;
1011 request[1] = _id; 972 request[1] = _id;
1012 _fileService.call(request).then((result) { 973 _fileService.call(request).then((response) {
1013 if (result != -1) { 974 if (_isErrorResponse(response)) {
1014 callback(result); 975 _reportError(response, "length failed");
1015 } else if (_onError != null) { 976 } else {
1016 _onError("length failed"); 977 callback(response);
1017 } 978 }
1018 }); 979 });
1019 } 980 }
1020 981
1021 int lengthSync() { 982 int lengthSync() {
1022 if (_asyncUsed) { 983 _checkNotAsyncAndNotClosed();
1023 throw new FileIOException( 984 var result = _FileUtils.length(_id);
1024 "Mixed use of synchronous and asynchronous API"); 985 if (result is OSError) {
1025 } 986 throw new FileIOException("length failed", result);
1026 int result = _FileUtils.length(_id);
1027 if (result == -1) {
1028 throw new FileIOException("length failed");
1029 } 987 }
1030 return result; 988 return result;
1031 } 989 }
1032 990
1033 void flush(void callback()) { 991 void flush(void callback()) {
1034 _ensureFileService(); 992 _ensureFileService();
1035 _asyncUsed = true; 993 _asyncUsed = true;
1036 List request = new List(2); 994 List request = new List(2);
1037 request[0] = _FileUtils.kFlushRequest; 995 request[0] = _FileUtils.kFlushRequest;
1038 request[1] = _id; 996 request[1] = _id;
1039 _fileService.call(request).then((result) { 997 _fileService.call(request).then((response) {
1040 if (result != -1) { 998 if (_isErrorResponse(response)) {
999 _reportError(response, "flush failed");
1000 } else {
1041 callback(); 1001 callback();
1042 } else if (_onError != null) {
1043 _onError("flush failed");
1044 } 1002 }
1045 }); 1003 });
1046 } 1004 }
1047 1005
1048 void flushSync() { 1006 void flushSync() {
1049 if (_asyncUsed) { 1007 _checkNotAsyncAndNotClosed();
1050 throw new FileIOException( 1008 var result = _FileUtils.flush(_id);
1051 "Mixed use of synchronous and asynchronous API"); 1009 if (result is OSError) {
1052 } 1010 throw new FileIOException("flush failed", result);
1053 int result = _FileUtils.flush(_id);
1054 if (result == -1) {
1055 throw new FileIOException("flush failed");
1056 } 1011 }
1057 } 1012 }
1058 1013
1059 String get name() => _name; 1014 String get name() => _name;
1060 1015
1061 void set onError(void handler(String error)) {
1062 _onError = handler;
1063 }
1064
1065 void set onNoPendingWrites(void handler()) { 1016 void set onNoPendingWrites(void handler()) {
1066 _onNoPendingWrites = handler; 1017 _onNoPendingWrites = handler;
1067 if (_pendingWrites == 0) { 1018 if (_pendingWrites == 0) {
1068 _noPendingWriteTimer = new Timer(0, (t) { 1019 _noPendingWriteTimer = new Timer(0, (t) {
1069 if (_onNoPendingWrites != null) _onNoPendingWrites(); 1020 if (_onNoPendingWrites != null) _onNoPendingWrites();
1070 }); 1021 });
1071 } 1022 }
1072 } 1023 }
1073 1024
1074 void _ensureFileService() { 1025 void _ensureFileService() {
(...skipping 10 matching lines...) Expand all
1085 } 1036 }
1086 } 1037 }
1087 1038
1088 void _writeCompleted() { 1039 void _writeCompleted() {
1089 _pendingWrites--; 1040 _pendingWrites--;
1090 if (_pendingWrites == 0 && _onNoPendingWrites != null) { 1041 if (_pendingWrites == 0 && _onNoPendingWrites != null) {
1091 _onNoPendingWrites(); 1042 _onNoPendingWrites();
1092 } 1043 }
1093 } 1044 }
1094 1045
1046 _checkNotAsyncAndNotClosed() {
1047 _checkNotAsync();
1048 if (_id == 0) {
1049 throw new FileIOException("File closed");
1050 }
1051 }
1095 1052
1096 String _name; 1053 String _name;
1097 int _id; 1054 int _id;
1098 bool _asyncUsed;
1099 int _pendingWrites = 0; 1055 int _pendingWrites = 0;
1100 1056
1101 SendPort _fileService; 1057 SendPort _fileService;
1102 1058
1103 Timer _noPendingWriteTimer; 1059 Timer _noPendingWriteTimer;
1104 1060
1105 Function _onNoPendingWrites; 1061 Function _onNoPendingWrites;
1106 Function _onError;
1107 } 1062 }
OLDNEW
« no previous file with comments | « runtime/bin/file.dart ('k') | runtime/bin/file_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698