Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 // Read the file in blocks of size 64k. | 7 // Read the file in blocks of size 64k. |
| 8 const int _BLOCK_SIZE = 64 * 1024; | 8 const int _BLOCK_SIZE = 64 * 1024; |
| 9 | 9 |
| 10 | 10 |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 // Constructor from Path for file. | 246 // Constructor from Path for file. |
| 247 _File.fromPath(Path path) : this(path.toNativePath()); | 247 _File.fromPath(Path path) : this(path.toNativePath()); |
| 248 | 248 |
| 249 Future<bool> exists() { | 249 Future<bool> exists() { |
| 250 _ensureFileService(); | 250 _ensureFileService(); |
| 251 List request = new List(2); | 251 List request = new List(2); |
| 252 request[0] = _EXISTS_REQUEST; | 252 request[0] = _EXISTS_REQUEST; |
| 253 request[1] = _path; | 253 request[1] = _path; |
| 254 return _fileService.call(request).then((response) { | 254 return _fileService.call(request).then((response) { |
| 255 if (_isErrorResponse(response)) { | 255 if (_isErrorResponse(response)) { |
| 256 throw _exceptionFromResponse(response, | 256 throw _exceptionFromResponse(response, "Cannot check existence", _path); |
| 257 "Cannot check existence of file '$_path'"); | |
| 258 } | 257 } |
| 259 return response; | 258 return response; |
| 260 }); | 259 }); |
| 261 } | 260 } |
| 262 | 261 |
| 263 external static _exists(String path); | 262 external static _exists(String path); |
| 264 | 263 |
| 265 bool existsSync() { | 264 bool existsSync() { |
| 266 var result = _exists(_path); | 265 var result = _exists(_path); |
| 267 throwIfError(result, "Cannot check existence of file '$_path'"); | 266 throwIfError(result, "Cannot check existence of file", _path); |
| 268 return result; | 267 return result; |
| 269 } | 268 } |
| 270 | 269 |
| 271 Future<FileStat> stat() => FileStat.stat(path); | 270 Future<FileStat> stat() => FileStat.stat(path); |
| 272 | 271 |
| 273 FileStat statSync() => FileStat.statSync(path); | 272 FileStat statSync() => FileStat.statSync(path); |
| 274 | 273 |
| 275 Future<File> create() { | 274 Future<File> create() { |
| 276 _ensureFileService(); | 275 _ensureFileService(); |
| 277 List request = new List(2); | 276 List request = new List(2); |
| 278 request[0] = _CREATE_REQUEST; | 277 request[0] = _CREATE_REQUEST; |
| 279 request[1] = _path; | 278 request[1] = _path; |
| 280 return _fileService.call(request).then((response) { | 279 return _fileService.call(request).then((response) { |
| 281 if (_isErrorResponse(response)) { | 280 if (_isErrorResponse(response)) { |
| 282 throw _exceptionFromResponse(response, "Cannot create file '$_path'"); | 281 throw _exceptionFromResponse(response, "Cannot create file", _path); |
| 283 } | 282 } |
| 284 return this; | 283 return this; |
| 285 }); | 284 }); |
| 286 } | 285 } |
| 287 | 286 |
| 288 external static _create(String path); | 287 external static _create(String path); |
| 289 | 288 |
| 290 external static _createLink(String path, String target); | 289 external static _createLink(String path, String target); |
| 291 | 290 |
| 292 external static _linkTarget(String path); | 291 external static _linkTarget(String path); |
| 293 | 292 |
| 294 void createSync() { | 293 void createSync() { |
| 295 var result = _create(_path); | 294 var result = _create(_path); |
| 296 throwIfError(result, "Cannot create file '$_path'"); | 295 throwIfError(result, "Cannot create file", _path); |
| 297 } | 296 } |
| 298 | 297 |
| 299 Future<File> delete() { | 298 Future<File> delete() { |
| 300 _ensureFileService(); | 299 _ensureFileService(); |
| 301 List request = new List(2); | 300 List request = new List(2); |
| 302 request[0] = _DELETE_REQUEST; | 301 request[0] = _DELETE_REQUEST; |
| 303 request[1] = _path; | 302 request[1] = _path; |
| 304 return _fileService.call(request).then((response) { | 303 return _fileService.call(request).then((response) { |
| 305 if (_isErrorResponse(response)) { | 304 if (_isErrorResponse(response)) { |
| 306 throw _exceptionFromResponse(response, "Cannot delete file '$_path'"); | 305 throw _exceptionFromResponse(response, "Cannot delete file", _path); |
| 307 } | 306 } |
| 308 return this; | 307 return this; |
| 309 }); | 308 }); |
| 310 } | 309 } |
| 311 | 310 |
| 312 external static _delete(String path); | 311 external static _delete(String path); |
| 313 | 312 |
| 314 external static _deleteLink(String path); | 313 external static _deleteLink(String path); |
| 315 | 314 |
| 316 void deleteSync() { | 315 void deleteSync() { |
| 317 var result = _delete(_path); | 316 var result = _delete(_path); |
| 318 throwIfError(result, "Cannot delete file '$_path'"); | 317 throwIfError(result, "Cannot delete file", _path); |
| 319 } | 318 } |
| 320 | 319 |
| 321 Future<File> rename(String newPath) { | 320 Future<File> rename(String newPath) { |
| 322 _ensureFileService(); | 321 _ensureFileService(); |
| 323 List request = new List(3); | 322 List request = new List(3); |
| 324 request[0] = _RENAME_REQUEST; | 323 request[0] = _RENAME_REQUEST; |
| 325 request[1] = _path; | 324 request[1] = _path; |
| 326 request[2] = newPath; | 325 request[2] = newPath; |
| 327 return _fileService.call(request).then((response) { | 326 return _fileService.call(request).then((response) { |
| 328 if (_isErrorResponse(response)) { | 327 if (_isErrorResponse(response)) { |
| 329 throw _exceptionFromResponse( | 328 throw _exceptionFromResponse( |
| 330 response, "Cannot rename file '$_path' to '$newPath'"); | 329 response, "Cannot rename file to '$newPath'", _path); |
| 331 } | 330 } |
| 332 return new File(newPath); | 331 return new File(newPath); |
| 333 }); | 332 }); |
| 334 } | 333 } |
| 335 | 334 |
| 336 external static _rename(String oldPath, String newPath); | 335 external static _rename(String oldPath, String newPath); |
| 337 | 336 |
| 338 external static _renameLink(String oldPath, String newPath); | 337 external static _renameLink(String oldPath, String newPath); |
| 339 | 338 |
| 340 File renameSync(String newPath) { | 339 File renameSync(String newPath) { |
| 341 var result = _rename(_path, newPath); | 340 var result = _rename(_path, newPath); |
| 342 throwIfError(result, "Cannot rename file '$_path' to '$newPath'"); | 341 throwIfError(result, "Cannot rename file to '$newPath'", _path); |
| 343 return new File(newPath); | 342 return new File(newPath); |
| 344 } | 343 } |
| 345 | 344 |
| 346 Directory get directory { | 345 Directory get directory { |
| 347 Path path = new Path(_path).directoryPath; | 346 Path path = new Path(_path).directoryPath; |
| 348 return new Directory.fromPath(path); | 347 return new Directory.fromPath(path); |
| 349 } | 348 } |
| 350 | 349 |
| 351 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { | 350 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { |
| 352 _ensureFileService(); | 351 _ensureFileService(); |
| 353 if (mode != FileMode.READ && | 352 if (mode != FileMode.READ && |
| 354 mode != FileMode.WRITE && | 353 mode != FileMode.WRITE && |
| 355 mode != FileMode.APPEND) { | 354 mode != FileMode.APPEND) { |
| 356 return new Future.error(new ArgumentError()); | 355 return new Future.error(new ArgumentError()); |
| 357 } | 356 } |
| 358 List request = new List(3); | 357 List request = new List(3); |
| 359 request[0] = _OPEN_REQUEST; | 358 request[0] = _OPEN_REQUEST; |
| 360 request[1] = _path; | 359 request[1] = _path; |
| 361 request[2] = mode._mode; // Direct int value for serialization. | 360 request[2] = mode._mode; // Direct int value for serialization. |
| 362 return _fileService.call(request).then((response) { | 361 return _fileService.call(request).then((response) { |
| 363 if (_isErrorResponse(response)) { | 362 if (_isErrorResponse(response)) { |
| 364 throw _exceptionFromResponse(response, "Cannot open file '$_path'"); | 363 throw _exceptionFromResponse(response, "Cannot open file", _path); |
| 365 } | 364 } |
| 366 return new _RandomAccessFile(response, _path); | 365 return new _RandomAccessFile(response, _path); |
| 367 }); | 366 }); |
| 368 } | 367 } |
| 369 | 368 |
| 370 Future<int> length() { | 369 Future<int> length() { |
| 371 _ensureFileService(); | 370 _ensureFileService(); |
| 372 List request = new List(2); | 371 List request = new List(2); |
| 373 request[0] = _LENGTH_FROM_PATH_REQUEST; | 372 request[0] = _LENGTH_FROM_PATH_REQUEST; |
| 374 request[1] = _path; | 373 request[1] = _path; |
| 375 return _fileService.call(request).then((response) { | 374 return _fileService.call(request).then((response) { |
| 376 if (_isErrorResponse(response)) { | 375 if (_isErrorResponse(response)) { |
| 377 throw _exceptionFromResponse(response, | 376 throw _exceptionFromResponse(response, |
| 378 "Cannot retrieve length of " | 377 "Cannot retrieve length of file", |
| 379 "file '$_path'"); | 378 _path); |
| 380 } | 379 } |
| 381 return response; | 380 return response; |
| 382 }); | 381 }); |
| 383 } | 382 } |
| 384 | 383 |
| 385 | 384 |
| 386 external static _lengthFromPath(String path); | 385 external static _lengthFromPath(String path); |
| 387 | 386 |
| 388 int lengthSync() { | 387 int lengthSync() { |
| 389 var result = _lengthFromPath(_path); | 388 var result = _lengthFromPath(_path); |
| 390 throwIfError(result, "Cannot retrieve length of file '$_path'"); | 389 throwIfError(result, "Cannot retrieve length of file", _path); |
| 391 return result; | 390 return result; |
| 392 } | 391 } |
| 393 | 392 |
| 394 Future<DateTime> lastModified() { | 393 Future<DateTime> lastModified() { |
| 395 _ensureFileService(); | 394 _ensureFileService(); |
| 396 List request = new List(2); | 395 List request = new List(2); |
| 397 request[0] = _LAST_MODIFIED_REQUEST; | 396 request[0] = _LAST_MODIFIED_REQUEST; |
| 398 request[1] = _path; | 397 request[1] = _path; |
| 399 return _fileService.call(request).then((response) { | 398 return _fileService.call(request).then((response) { |
| 400 if (_isErrorResponse(response)) { | 399 if (_isErrorResponse(response)) { |
| 401 throw _exceptionFromResponse(response, | 400 throw _exceptionFromResponse(response, |
| 402 "Cannot retrieve modification time " | 401 "Cannot retrieve modification time", |
| 403 "for file '$_path'"); | 402 _path); |
| 404 } | 403 } |
| 405 return new DateTime.fromMillisecondsSinceEpoch(response); | 404 return new DateTime.fromMillisecondsSinceEpoch(response); |
| 406 }); | 405 }); |
| 407 } | 406 } |
| 408 | 407 |
| 409 external static _lastModified(String path); | 408 external static _lastModified(String path); |
| 410 | 409 |
| 411 DateTime lastModifiedSync() { | 410 DateTime lastModifiedSync() { |
| 412 var ms = _lastModified(path); | 411 var ms = _lastModified(path); |
| 413 throwIfError(ms, "Cannot retrieve modification time for file '$_path'"); | 412 throwIfError(ms, "Cannot retrieve modification", _path); |
|
Bill Hesse
2013/06/27 16:32:46
modification time
Anders Johnsen
2013/06/27 16:42:19
Done.
| |
| 414 return new DateTime.fromMillisecondsSinceEpoch(ms); | 413 return new DateTime.fromMillisecondsSinceEpoch(ms); |
| 415 } | 414 } |
| 416 | 415 |
| 417 external static _open(String path, int mode); | 416 external static _open(String path, int mode); |
| 418 | 417 |
| 419 RandomAccessFile openSync({FileMode mode: FileMode.READ}) { | 418 RandomAccessFile openSync({FileMode mode: FileMode.READ}) { |
| 420 if (mode != FileMode.READ && | 419 if (mode != FileMode.READ && |
| 421 mode != FileMode.WRITE && | 420 mode != FileMode.WRITE && |
| 422 mode != FileMode.APPEND) { | 421 mode != FileMode.APPEND) { |
| 423 throw new FileException("Unknown file mode. Use FileMode.READ, " | 422 throw new FileException("Unknown file mode. Use FileMode.READ, " |
| 424 "FileMode.WRITE or FileMode.APPEND."); | 423 "FileMode.WRITE or FileMode.APPEND.", |
| 424 _path); | |
| 425 } | 425 } |
| 426 var id = _open(_path, mode._mode); | 426 var id = _open(_path, mode._mode); |
| 427 throwIfError(id, "Cannot open file '$_path'"); | 427 throwIfError(id, "Cannot open file", _path); |
| 428 return new _RandomAccessFile(id, _path); | 428 return new _RandomAccessFile(id, _path); |
| 429 } | 429 } |
| 430 | 430 |
| 431 external static int _openStdio(int fd); | 431 external static int _openStdio(int fd); |
| 432 | 432 |
| 433 static RandomAccessFile _openStdioSync(int fd) { | 433 static RandomAccessFile _openStdioSync(int fd) { |
| 434 var id = _openStdio(fd); | 434 var id = _openStdio(fd); |
| 435 if (id == 0) { | 435 if (id == 0) { |
| 436 throw new FileException("Cannot open stdio file for: $fd"); | 436 throw new FileException("Cannot open stdio file for: $fd"); |
| 437 } | 437 } |
| 438 return new _RandomAccessFile(id, ""); | 438 return new _RandomAccessFile(id, ""); |
| 439 } | 439 } |
| 440 | 440 |
| 441 Future<String> fullPath() { | 441 Future<String> fullPath() { |
| 442 _ensureFileService(); | 442 _ensureFileService(); |
| 443 List request = new List(2); | 443 List request = new List(2); |
| 444 request[0] = _FULL_PATH_REQUEST; | 444 request[0] = _FULL_PATH_REQUEST; |
| 445 request[1] = _path; | 445 request[1] = _path; |
| 446 return _fileService.call(request).then((response) { | 446 return _fileService.call(request).then((response) { |
| 447 if (_isErrorResponse(response)) { | 447 if (_isErrorResponse(response)) { |
| 448 throw _exceptionFromResponse(response, | 448 throw _exceptionFromResponse(response, |
| 449 "Cannot retrieve full path" | 449 "Cannot retrieve full path", |
| 450 " for '$_path'"); | 450 _path); |
| 451 } | 451 } |
| 452 return response; | 452 return response; |
| 453 }); | 453 }); |
| 454 } | 454 } |
| 455 | 455 |
| 456 external static _fullPath(String path); | 456 external static _fullPath(String path); |
| 457 | 457 |
| 458 String fullPathSync() { | 458 String fullPathSync() { |
| 459 var result = _fullPath(_path); | 459 var result = _fullPath(_path); |
| 460 throwIfError(result, "Cannot retrieve full path for file '$_path'"); | 460 throwIfError(result, "Cannot retrieve full path", _path); |
| 461 return result; | 461 return result; |
| 462 } | 462 } |
| 463 | 463 |
| 464 Stream<List<int>> openRead([int start, int end]) { | 464 Stream<List<int>> openRead([int start, int end]) { |
| 465 return new _FileStream(_path, start, end); | 465 return new _FileStream(_path, start, end); |
| 466 } | 466 } |
| 467 | 467 |
| 468 IOSink openWrite({FileMode mode: FileMode.WRITE, | 468 IOSink openWrite({FileMode mode: FileMode.WRITE, |
| 469 Encoding encoding: Encoding.UTF_8}) { | 469 Encoding encoding: Encoding.UTF_8}) { |
| 470 if (mode != FileMode.WRITE && | 470 if (mode != FileMode.WRITE && |
| 471 mode != FileMode.APPEND) { | 471 mode != FileMode.APPEND) { |
| 472 throw new FileException( | 472 throw new ArgumentError( |
| 473 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 473 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
| 474 } | 474 } |
| 475 var consumer = new _FileStreamConsumer(this, mode); | 475 var consumer = new _FileStreamConsumer(this, mode); |
| 476 return new IOSink(consumer, encoding: encoding); | 476 return new IOSink(consumer, encoding: encoding); |
| 477 } | 477 } |
| 478 | 478 |
| 479 Future<List<int>> readAsBytes() { | 479 Future<List<int>> readAsBytes() { |
| 480 _ensureFileService(); | 480 _ensureFileService(); |
| 481 Completer<List<int>> completer = new Completer<List<int>>(); | 481 Completer<List<int>> completer = new Completer<List<int>>(); |
| 482 var chunks = new _BufferList(); | 482 var chunks = new _BufferList(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 String get path => _path; | 577 String get path => _path; |
| 578 | 578 |
| 579 String toString() => "File: '$path'"; | 579 String toString() => "File: '$path'"; |
| 580 | 580 |
| 581 void _ensureFileService() { | 581 void _ensureFileService() { |
| 582 if (_fileService == null) { | 582 if (_fileService == null) { |
| 583 _fileService = _FileUtils._newServicePort(); | 583 _fileService = _FileUtils._newServicePort(); |
| 584 } | 584 } |
| 585 } | 585 } |
| 586 | 586 |
| 587 static throwIfError(Object result, String msg) { | 587 static throwIfError(Object result, String msg, String path) { |
| 588 if (result is OSError) { | 588 if (result is OSError) { |
| 589 throw new FileException(msg, result); | 589 throw new FileException(msg, path, result); |
| 590 } | 590 } |
| 591 } | 591 } |
| 592 | 592 |
| 593 final String _path; | 593 final String _path; |
| 594 | 594 |
| 595 SendPort _fileService; | 595 SendPort _fileService; |
| 596 } | 596 } |
| 597 | 597 |
| 598 | 598 |
| 599 class _RandomAccessFile implements RandomAccessFile { | 599 class _RandomAccessFile implements RandomAccessFile { |
| 600 _RandomAccessFile(int this._id, String this._path); | 600 _RandomAccessFile(int this._id, String this._path); |
| 601 | 601 |
| 602 Future<RandomAccessFile> close() { | 602 Future<RandomAccessFile> close() { |
| 603 if (closed) return _closedException(); | 603 if (closed) return _closedException(); |
| 604 _ensureFileService(); | 604 _ensureFileService(); |
| 605 List request = new List(2); | 605 List request = new List(2); |
| 606 request[0] = _CLOSE_REQUEST; | 606 request[0] = _CLOSE_REQUEST; |
| 607 request[1] = _id; | 607 request[1] = _id; |
| 608 // Set the id_ to 0 (NULL) to ensure the no more async requests | 608 // Set the id_ to 0 (NULL) to ensure the no more async requests |
| 609 // can be issued for this file. | 609 // can be issued for this file. |
| 610 _id = 0; | 610 _id = 0; |
| 611 return _fileService.call(request).then((result) { | 611 return _fileService.call(request).then((result) { |
| 612 if (result != -1) { | 612 if (result != -1) { |
| 613 _id = result; | 613 _id = result; |
| 614 return this; | 614 return this; |
| 615 } else { | 615 } else { |
| 616 throw new FileException("Cannot close file '$_path'"); | 616 throw new FileException("Cannot close file", _path); |
| 617 } | 617 } |
| 618 }); | 618 }); |
| 619 } | 619 } |
| 620 | 620 |
| 621 external static int _close(int id); | 621 external static int _close(int id); |
| 622 | 622 |
| 623 void closeSync() { | 623 void closeSync() { |
| 624 _checkNotClosed(); | 624 _checkNotClosed(); |
| 625 var id = _close(_id); | 625 var id = _close(_id); |
| 626 if (id == -1) { | 626 if (id == -1) { |
| 627 throw new FileException("Cannot close file '$_path'"); | 627 throw new FileException("Cannot close file", _path); |
| 628 } | 628 } |
| 629 _id = id; | 629 _id = id; |
| 630 } | 630 } |
| 631 | 631 |
| 632 Future<int> readByte() { | 632 Future<int> readByte() { |
| 633 _ensureFileService(); | 633 _ensureFileService(); |
| 634 if (closed) return _closedException(); | 634 if (closed) return _closedException(); |
| 635 List request = new List(2); | 635 List request = new List(2); |
| 636 request[0] = _READ_BYTE_REQUEST; | 636 request[0] = _READ_BYTE_REQUEST; |
| 637 request[1] = _id; | 637 request[1] = _id; |
| 638 return _fileService.call(request).then((response) { | 638 return _fileService.call(request).then((response) { |
| 639 if (_isErrorResponse(response)) { | 639 if (_isErrorResponse(response)) { |
| 640 throw _exceptionFromResponse(response, | 640 throw _exceptionFromResponse(response, "readByte failed", _path); |
| 641 "readByte failed for file '$_path'"); | |
| 642 } | 641 } |
| 643 return response; | 642 return response; |
| 644 }); | 643 }); |
| 645 } | 644 } |
| 646 | 645 |
| 647 external static _readByte(int id); | 646 external static _readByte(int id); |
| 648 | 647 |
| 649 int readByteSync() { | 648 int readByteSync() { |
| 650 _checkNotClosed(); | 649 _checkNotClosed(); |
| 651 var result = _readByte(_id); | 650 var result = _readByte(_id); |
| 652 if (result is OSError) { | 651 if (result is OSError) { |
| 653 throw new FileException("readByte failed for file '$_path'", result); | 652 throw new FileException("readByte failed", _path, result); |
| 654 } | 653 } |
| 655 return result; | 654 return result; |
| 656 } | 655 } |
| 657 | 656 |
| 658 Future<List<int>> read(int bytes) { | 657 Future<List<int>> read(int bytes) { |
| 659 _ensureFileService(); | 658 _ensureFileService(); |
| 660 if (bytes is !int) { | 659 if (bytes is !int) { |
| 661 return new Future.error(new FileException( | 660 throw new ArgumentError(bytes); |
| 662 "Invalid arguments to read for file '$_path'")); | |
| 663 } | 661 } |
| 664 if (closed) return _closedException(); | 662 if (closed) return _closedException(); |
| 665 List request = new List(3); | 663 List request = new List(3); |
| 666 request[0] = _READ_REQUEST; | 664 request[0] = _READ_REQUEST; |
| 667 request[1] = _id; | 665 request[1] = _id; |
| 668 request[2] = bytes; | 666 request[2] = bytes; |
| 669 return _fileService.call(request).then((response) { | 667 return _fileService.call(request).then((response) { |
| 670 if (_isErrorResponse(response)) { | 668 if (_isErrorResponse(response)) { |
| 671 throw _exceptionFromResponse(response, | 669 throw _exceptionFromResponse(response, "read failed", _path); |
| 672 "read failed for file '$_path'"); | |
| 673 } | 670 } |
| 674 return response[1]; | 671 return response[1]; |
| 675 }); | 672 }); |
| 676 } | 673 } |
| 677 | 674 |
| 678 external static _read(int id, int bytes); | 675 external static _read(int id, int bytes); |
| 679 | 676 |
| 680 List<int> readSync(int bytes) { | 677 List<int> readSync(int bytes) { |
| 681 _checkNotClosed(); | 678 _checkNotClosed(); |
| 682 if (bytes is !int) { | 679 if (bytes is !int) { |
| 683 throw new FileException( | 680 throw new ArgumentError(bytes); |
| 684 "Invalid arguments to readSync for file '$_path'"); | |
| 685 } | 681 } |
| 686 var result = _read(_id, bytes); | 682 var result = _read(_id, bytes); |
| 687 if (result is OSError) { | 683 if (result is OSError) { |
| 688 throw new FileException("readSync failed for file '$_path'", | 684 throw new FileException("readSync failed",_path, result); |
| 689 result); | |
| 690 } | 685 } |
| 691 return result; | 686 return result; |
| 692 } | 687 } |
| 693 | 688 |
| 694 Future<int> readInto(List<int> buffer, [int start, int end]) { | 689 Future<int> readInto(List<int> buffer, [int start, int end]) { |
| 695 _ensureFileService(); | 690 _ensureFileService(); |
| 696 if (buffer is !List || | 691 if (buffer is !List || |
| 697 (start != null && start is !int) || | 692 (start != null && start is !int) || |
| 698 (end != null && end is !int)) { | 693 (end != null && end is !int)) { |
| 699 return new Future.error(new FileException( | 694 throw new ArgumentError(); |
| 700 "Invalid arguments to readInto for file '$_path'")); | 695 } |
| 701 }; | |
| 702 if (closed) return _closedException(); | 696 if (closed) return _closedException(); |
| 703 List request = new List(3); | 697 List request = new List(3); |
| 704 if (start == null) start = 0; | 698 if (start == null) start = 0; |
| 705 if (end == null) end = buffer.length; | 699 if (end == null) end = buffer.length; |
| 706 request[0] = _READ_LIST_REQUEST; | 700 request[0] = _READ_LIST_REQUEST; |
| 707 request[1] = _id; | 701 request[1] = _id; |
| 708 request[2] = end - start; | 702 request[2] = end - start; |
| 709 return _fileService.call(request).then((response) { | 703 return _fileService.call(request).then((response) { |
| 710 if (_isErrorResponse(response)) { | 704 if (_isErrorResponse(response)) { |
| 711 throw _exceptionFromResponse(response, | 705 throw _exceptionFromResponse(response, "readInto failed", _path); |
| 712 "readInto failed for file '$_path'"); | |
| 713 } | 706 } |
| 714 var read = response[1]; | 707 var read = response[1]; |
| 715 var data = response[2]; | 708 var data = response[2]; |
| 716 buffer.setRange(start, start + read, data); | 709 buffer.setRange(start, start + read, data); |
| 717 return read; | 710 return read; |
| 718 }); | 711 }); |
| 719 } | 712 } |
| 720 | 713 |
| 721 static void _checkReadWriteListArguments(int length, int start, int end) { | 714 static void _checkReadWriteListArguments(int length, int start, int end) { |
| 722 if (start < 0) throw new RangeError.value(start); | 715 if (start < 0) throw new RangeError.value(start); |
| 723 if (end < start) throw new RangeError.value(end); | 716 if (end < start) throw new RangeError.value(end); |
| 724 if (end > length) { | 717 if (end > length) { |
| 725 throw new RangeError.value(end); | 718 throw new RangeError.value(end); |
| 726 } | 719 } |
| 727 } | 720 } |
| 728 | 721 |
| 729 external static _readInto(int id, List<int> buffer, int start, int end); | 722 external static _readInto(int id, List<int> buffer, int start, int end); |
| 730 | 723 |
| 731 int readIntoSync(List<int> buffer, [int start, int end]) { | 724 int readIntoSync(List<int> buffer, [int start, int end]) { |
| 732 _checkNotClosed(); | 725 _checkNotClosed(); |
| 733 if (buffer is !List || | 726 if (buffer is !List || |
| 734 (start != null && start is !int) || | 727 (start != null && start is !int) || |
| 735 (end != null && end is !int)) { | 728 (end != null && end is !int)) { |
| 736 throw new FileException( | 729 throw new ArgumentError(); |
| 737 "Invalid arguments to readInto for file '$_path'"); | |
| 738 } | 730 } |
| 739 if (start == null) start = 0; | 731 if (start == null) start = 0; |
| 740 if (end == null) end = buffer.length; | 732 if (end == null) end = buffer.length; |
| 741 if (end == start) return 0; | 733 if (end == start) return 0; |
| 742 _checkReadWriteListArguments(buffer.length, start, end); | 734 _checkReadWriteListArguments(buffer.length, start, end); |
| 743 var result = _readInto(_id, buffer, start, end); | 735 var result = _readInto(_id, buffer, start, end); |
| 744 if (result is OSError) { | 736 if (result is OSError) { |
| 745 throw new FileException("readInto failed for file '$_path'", | 737 throw new FileException("readInto failed", _path, result); |
| 746 result); | |
| 747 } | 738 } |
| 748 return result; | 739 return result; |
| 749 } | 740 } |
| 750 | 741 |
| 751 Future<RandomAccessFile> writeByte(int value) { | 742 Future<RandomAccessFile> writeByte(int value) { |
| 752 _ensureFileService(); | 743 _ensureFileService(); |
| 753 if (value is !int) { | 744 if (value is !int) { |
| 754 return new Future.error(new FileException( | 745 throw new ArgumentError(value); |
| 755 "Invalid argument to writeByte for file '$_path'")); | |
| 756 } | 746 } |
| 757 if (closed) return _closedException(); | 747 if (closed) return _closedException(); |
| 758 List request = new List(3); | 748 List request = new List(3); |
| 759 request[0] = _WRITE_BYTE_REQUEST; | 749 request[0] = _WRITE_BYTE_REQUEST; |
| 760 request[1] = _id; | 750 request[1] = _id; |
| 761 request[2] = value; | 751 request[2] = value; |
| 762 return _fileService.call(request).then((response) { | 752 return _fileService.call(request).then((response) { |
| 763 if (_isErrorResponse(response)) { | 753 if (_isErrorResponse(response)) { |
| 764 throw _exceptionFromResponse(response, | 754 throw _exceptionFromResponse(response, "writeByte failed",_path); |
| 765 "writeByte failed for file '$_path'"); | |
| 766 } | 755 } |
| 767 return this; | 756 return this; |
| 768 }); | 757 }); |
| 769 } | 758 } |
| 770 | 759 |
| 771 external static _writeByte(int id, int value); | 760 external static _writeByte(int id, int value); |
| 772 | 761 |
| 773 int writeByteSync(int value) { | 762 int writeByteSync(int value) { |
| 774 _checkNotClosed(); | 763 _checkNotClosed(); |
| 775 if (value is !int) { | 764 if (value is !int) { |
| 776 throw new FileException( | 765 throw new ArgumentError(value); |
| 777 "Invalid argument to writeByte for file '$_path'"); | |
| 778 } | 766 } |
| 779 var result = _writeByte(_id, value); | 767 var result = _writeByte(_id, value); |
| 780 if (result is OSError) { | 768 if (result is OSError) { |
| 781 throw new FileException("writeByte failed for file '$_path'", | 769 throw new FileException("writeByte failed", _path, result); |
| 782 result); | |
| 783 } | 770 } |
| 784 return result; | 771 return result; |
| 785 } | 772 } |
| 786 | 773 |
| 787 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { | 774 Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) { |
| 788 _ensureFileService(); | 775 _ensureFileService(); |
| 789 if ((buffer is !List && buffer is !ByteData) || | 776 if ((buffer is !List && buffer is !ByteData) || |
| 790 (start != null && start is !int) || | 777 (start != null && start is !int) || |
| 791 (end != null && end is !int)) { | 778 (end != null && end is !int)) { |
| 792 return new Future.error(new FileException( | 779 throw new ArgumentError("Invalid arguments to writeFrom"); |
| 793 "Invalid arguments to writeFrom for file '$_path'")); | |
| 794 } | 780 } |
| 795 | 781 |
| 796 if (closed) return _closedException(); | 782 if (closed) return _closedException(); |
| 797 | 783 |
| 798 _BufferAndStart result; | 784 _BufferAndStart result; |
| 799 try { | 785 try { |
| 800 result = _ensureFastAndSerializableData(buffer, start, end); | 786 result = _ensureFastAndSerializableData(buffer, start, end); |
| 801 } catch (e) { | 787 } catch (e) { |
| 802 return new Future.error(e); | 788 return new Future.error(e); |
| 803 } | 789 } |
| 804 | 790 |
| 805 List request = new List(5); | 791 List request = new List(5); |
| 806 request[0] = _WRITE_LIST_REQUEST; | 792 request[0] = _WRITE_LIST_REQUEST; |
| 807 request[1] = _id; | 793 request[1] = _id; |
| 808 request[2] = result.buffer; | 794 request[2] = result.buffer; |
| 809 request[3] = result.start; | 795 request[3] = result.start; |
| 810 request[4] = end - (start - result.start); | 796 request[4] = end - (start - result.start); |
| 811 return _fileService.call(request).then((response) { | 797 return _fileService.call(request).then((response) { |
| 812 if (_isErrorResponse(response)) { | 798 if (_isErrorResponse(response)) { |
| 813 throw _exceptionFromResponse(response, | 799 throw _exceptionFromResponse(response, "writeFrom failed", _path); |
| 814 "writeFrom failed for file '$_path'"); | |
| 815 } | 800 } |
| 816 return this; | 801 return this; |
| 817 }); | 802 }); |
| 818 } | 803 } |
| 819 | 804 |
| 820 external static _writeFrom(int id, List<int> buffer, int start, int end); | 805 external static _writeFrom(int id, List<int> buffer, int start, int end); |
| 821 | 806 |
| 822 void writeFromSync(List<int> buffer, [int start, int end]) { | 807 void writeFromSync(List<int> buffer, [int start, int end]) { |
| 823 _checkNotClosed(); | 808 _checkNotClosed(); |
| 824 if (buffer is !List || | 809 if (buffer is !List || |
| 825 (start != null && start is !int) || | 810 (start != null && start is !int) || |
| 826 (end != null && end is !int)) { | 811 (end != null && end is !int)) { |
| 827 throw new FileException( | 812 throw new ArgumentError("Invalid arguments to writeFromSync"); |
| 828 "Invalid arguments to writeFrom for file '$_path'"); | |
| 829 } | 813 } |
| 830 if (start == null) start = 0; | 814 if (start == null) start = 0; |
| 831 if (end == null) end = buffer.length; | 815 if (end == null) end = buffer.length; |
| 832 if (end == start) return; | 816 if (end == start) return; |
| 833 _checkReadWriteListArguments(buffer.length, start, end); | 817 _checkReadWriteListArguments(buffer.length, start, end); |
| 834 _BufferAndStart bufferAndStart = | 818 _BufferAndStart bufferAndStart = |
| 835 _ensureFastAndSerializableData(buffer, start, end); | 819 _ensureFastAndSerializableData(buffer, start, end); |
| 836 var result = _writeFrom(_id, | 820 var result = _writeFrom(_id, |
| 837 bufferAndStart.buffer, | 821 bufferAndStart.buffer, |
| 838 bufferAndStart.start, | 822 bufferAndStart.start, |
| 839 end - (start - bufferAndStart.start)); | 823 end - (start - bufferAndStart.start)); |
| 840 if (result is OSError) { | 824 if (result is OSError) { |
| 841 throw new FileException("writeFrom failed for file '$_path'", result); | 825 throw new FileException("writeFrom failed", _path, result); |
| 842 } | 826 } |
| 843 } | 827 } |
| 844 | 828 |
| 845 Future<RandomAccessFile> writeString(String string, | 829 Future<RandomAccessFile> writeString(String string, |
| 846 {Encoding encoding: Encoding.UTF_8}) { | 830 {Encoding encoding: Encoding.UTF_8}) { |
| 847 if (encoding is! Encoding) { | 831 if (encoding is! Encoding) { |
| 848 return new Future.error(new FileException( | 832 throw new ArgumentError(encoding); |
| 849 "Invalid encoding in writeString: $encoding")); | |
| 850 } | 833 } |
| 851 var data = _encodeString(string, encoding); | 834 var data = _encodeString(string, encoding); |
| 852 return writeFrom(data, 0, data.length); | 835 return writeFrom(data, 0, data.length); |
| 853 } | 836 } |
| 854 | 837 |
| 855 void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) { | 838 void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) { |
| 856 if (encoding is! Encoding) { | 839 if (encoding is! Encoding) { |
| 857 throw new FileException( | 840 throw new ArgumentError(encoding); |
| 858 "Invalid encoding in writeStringSync: $encoding"); | |
| 859 } | 841 } |
| 860 var data = _encodeString(string, encoding); | 842 var data = _encodeString(string, encoding); |
| 861 writeFromSync(data, 0, data.length); | 843 writeFromSync(data, 0, data.length); |
| 862 } | 844 } |
| 863 | 845 |
| 864 Future<int> position() { | 846 Future<int> position() { |
| 865 _ensureFileService(); | 847 _ensureFileService(); |
| 866 if (closed) return _closedException(); | 848 if (closed) return _closedException(); |
| 867 List request = new List(2); | 849 List request = new List(2); |
| 868 request[0] = _POSITION_REQUEST; | 850 request[0] = _POSITION_REQUEST; |
| 869 request[1] = _id; | 851 request[1] = _id; |
| 870 return _fileService.call(request).then((response) { | 852 return _fileService.call(request).then((response) { |
| 871 if (_isErrorResponse(response)) { | 853 if (_isErrorResponse(response)) { |
| 872 throw _exceptionFromResponse(response, | 854 throw _exceptionFromResponse(response, "position failed", _path); |
| 873 "position failed for file '$_path'"); | |
| 874 } | 855 } |
| 875 return response; | 856 return response; |
| 876 }); | 857 }); |
| 877 } | 858 } |
| 878 | 859 |
| 879 external static _position(int id); | 860 external static _position(int id); |
| 880 | 861 |
| 881 int positionSync() { | 862 int positionSync() { |
| 882 _checkNotClosed(); | 863 _checkNotClosed(); |
| 883 var result = _position(_id); | 864 var result = _position(_id); |
| 884 if (result is OSError) { | 865 if (result is OSError) { |
| 885 throw new FileException("position failed for file '$_path'", result); | 866 throw new FileException("position failed", _path, result); |
| 886 } | 867 } |
| 887 return result; | 868 return result; |
| 888 } | 869 } |
| 889 | 870 |
| 890 Future<RandomAccessFile> setPosition(int position) { | 871 Future<RandomAccessFile> setPosition(int position) { |
| 891 _ensureFileService(); | 872 _ensureFileService(); |
| 892 if (closed) return _closedException(); | 873 if (closed) return _closedException(); |
| 893 List request = new List(3); | 874 List request = new List(3); |
| 894 request[0] = _SET_POSITION_REQUEST; | 875 request[0] = _SET_POSITION_REQUEST; |
| 895 request[1] = _id; | 876 request[1] = _id; |
| 896 request[2] = position; | 877 request[2] = position; |
| 897 return _fileService.call(request).then((response) { | 878 return _fileService.call(request).then((response) { |
| 898 if (_isErrorResponse(response)) { | 879 if (_isErrorResponse(response)) { |
| 899 throw _exceptionFromResponse(response, | 880 throw _exceptionFromResponse(response, "setPosition failed", _path); |
| 900 "setPosition failed for file '$_path'"); | |
| 901 } | 881 } |
| 902 return this; | 882 return this; |
| 903 }); | 883 }); |
| 904 } | 884 } |
| 905 | 885 |
| 906 external static _setPosition(int id, int position); | 886 external static _setPosition(int id, int position); |
| 907 | 887 |
| 908 void setPositionSync(int position) { | 888 void setPositionSync(int position) { |
| 909 _checkNotClosed(); | 889 _checkNotClosed(); |
| 910 var result = _setPosition(_id, position); | 890 var result = _setPosition(_id, position); |
| 911 if (result is OSError) { | 891 if (result is OSError) { |
| 912 throw new FileException("setPosition failed for file '$_path'", result); | 892 throw new FileException("setPosition failed", _path, result); |
| 913 } | 893 } |
| 914 } | 894 } |
| 915 | 895 |
| 916 Future<RandomAccessFile> truncate(int length) { | 896 Future<RandomAccessFile> truncate(int length) { |
| 917 _ensureFileService(); | 897 _ensureFileService(); |
| 918 if (closed) return _closedException(); | 898 if (closed) return _closedException(); |
| 919 List request = new List(3); | 899 List request = new List(3); |
| 920 request[0] = _TRUNCATE_REQUEST; | 900 request[0] = _TRUNCATE_REQUEST; |
| 921 request[1] = _id; | 901 request[1] = _id; |
| 922 request[2] = length; | 902 request[2] = length; |
| 923 return _fileService.call(request).then((response) { | 903 return _fileService.call(request).then((response) { |
| 924 if (_isErrorResponse(response)) { | 904 if (_isErrorResponse(response)) { |
| 925 throw _exceptionFromResponse(response, | 905 throw _exceptionFromResponse(response, "truncate failed", _path); |
| 926 "truncate failed for file '$_path'"); | |
| 927 } | 906 } |
| 928 return this; | 907 return this; |
| 929 }); | 908 }); |
| 930 } | 909 } |
| 931 | 910 |
| 932 external static _truncate(int id, int length); | 911 external static _truncate(int id, int length); |
| 933 | 912 |
| 934 void truncateSync(int length) { | 913 void truncateSync(int length) { |
| 935 _checkNotClosed(); | 914 _checkNotClosed(); |
| 936 var result = _truncate(_id, length); | 915 var result = _truncate(_id, length); |
| 937 if (result is OSError) { | 916 if (result is OSError) { |
| 938 throw new FileException("truncate failed for file '$_path'", result); | 917 throw new FileException("truncate failed", _path, result); |
| 939 } | 918 } |
| 940 } | 919 } |
| 941 | 920 |
| 942 Future<int> length() { | 921 Future<int> length() { |
| 943 _ensureFileService(); | 922 _ensureFileService(); |
| 944 if (closed) return _closedException(); | 923 if (closed) return _closedException(); |
| 945 List request = new List(2); | 924 List request = new List(2); |
| 946 request[0] = _LENGTH_REQUEST; | 925 request[0] = _LENGTH_REQUEST; |
| 947 request[1] = _id; | 926 request[1] = _id; |
| 948 return _fileService.call(request).then((response) { | 927 return _fileService.call(request).then((response) { |
| 949 if (_isErrorResponse(response)) { | 928 if (_isErrorResponse(response)) { |
| 950 throw _exceptionFromResponse(response, | 929 throw _exceptionFromResponse(response, "length failed", _path); |
| 951 "length failed for file '$_path'"); | |
| 952 } | 930 } |
| 953 return response; | 931 return response; |
| 954 }); | 932 }); |
| 955 } | 933 } |
| 956 | 934 |
| 957 external static _length(int id); | 935 external static _length(int id); |
| 958 | 936 |
| 959 int lengthSync() { | 937 int lengthSync() { |
| 960 _checkNotClosed(); | 938 _checkNotClosed(); |
| 961 var result = _length(_id); | 939 var result = _length(_id); |
| 962 if (result is OSError) { | 940 if (result is OSError) { |
| 963 throw new FileException("length failed for file '$_path'", result); | 941 throw new FileException("length failed", _path, result); |
| 964 } | 942 } |
| 965 return result; | 943 return result; |
| 966 } | 944 } |
| 967 | 945 |
| 968 Future<RandomAccessFile> flush() { | 946 Future<RandomAccessFile> flush() { |
| 969 _ensureFileService(); | 947 _ensureFileService(); |
| 970 if (closed) return _closedException(); | 948 if (closed) return _closedException(); |
| 971 List request = new List(2); | 949 List request = new List(2); |
| 972 request[0] = _FLUSH_REQUEST; | 950 request[0] = _FLUSH_REQUEST; |
| 973 request[1] = _id; | 951 request[1] = _id; |
| 974 return _fileService.call(request).then((response) { | 952 return _fileService.call(request).then((response) { |
| 975 if (_isErrorResponse(response)) { | 953 if (_isErrorResponse(response)) { |
| 976 throw _exceptionFromResponse(response, | 954 throw _exceptionFromResponse(response, |
| 977 "flush failed for file '$_path'"); | 955 "flush failed", |
| 956 _path); | |
| 978 } | 957 } |
| 979 return this; | 958 return this; |
| 980 }); | 959 }); |
| 981 } | 960 } |
| 982 | 961 |
| 983 external static _flush(int id); | 962 external static _flush(int id); |
| 984 | 963 |
| 985 void flushSync() { | 964 void flushSync() { |
| 986 _checkNotClosed(); | 965 _checkNotClosed(); |
| 987 var result = _flush(_id); | 966 var result = _flush(_id); |
| 988 if (result is OSError) { | 967 if (result is OSError) { |
| 989 throw new FileException("flush failed for file '$_path'", result); | 968 throw new FileException("flush failed", _path, result); |
| 990 } | 969 } |
| 991 } | 970 } |
| 992 | 971 |
| 993 String get path => _path; | 972 String get path => _path; |
| 994 | 973 |
| 995 void _ensureFileService() { | 974 void _ensureFileService() { |
| 996 if (_fileService == null) { | 975 if (_fileService == null) { |
| 997 _fileService = _FileUtils._newServicePort(); | 976 _fileService = _FileUtils._newServicePort(); |
| 998 } | 977 } |
| 999 } | 978 } |
| 1000 | 979 |
| 1001 bool get closed => _id == 0; | 980 bool get closed => _id == 0; |
| 1002 | 981 |
| 1003 void _checkNotClosed() { | 982 void _checkNotClosed() { |
| 1004 if (closed) { | 983 if (closed) { |
| 1005 throw new FileException("File closed '$_path'"); | 984 throw new FileException("File closed", _path); |
| 1006 } | 985 } |
| 1007 } | 986 } |
| 1008 | 987 |
| 1009 Future _closedException() { | 988 Future _closedException() { |
| 1010 return new Future.error(new FileException("File closed '$_path'")); | 989 return new Future.error(new FileException("File closed", _path)); |
| 1011 } | 990 } |
| 1012 | 991 |
| 1013 final String _path; | 992 final String _path; |
| 1014 int _id; | 993 int _id; |
| 1015 | 994 |
| 1016 SendPort _fileService; | 995 SendPort _fileService; |
| 1017 } | 996 } |
| OLD | NEW |