| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |