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