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 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 class _FileInputStream extends _BaseDataInputStream implements InputStream { | 7 class _FileInputStream extends _BaseDataInputStream implements InputStream { |
8 _FileInputStream(String name) | 8 _FileInputStream(String name) |
9 : _data = const [], | 9 : _data = const [], |
10 _position = 0, | 10 _position = 0, |
11 _filePosition = 0 { | 11 _filePosition = 0 { |
12 var file = new File(name); | 12 var file = new File(name); |
13 var future = file.open(FileMode.READ); | 13 var future = file.open(FileMode.READ); |
14 future.handleException((e) { | 14 future.then(_setupOpenedFile) |
15 _reportError(e); | 15 .catchError((e) { |
16 return true; | 16 _reportError(e.error); |
17 }); | 17 }); |
18 future.then(_setupOpenedFile); | |
19 } | 18 } |
20 | 19 |
21 _FileInputStream.fromStdio(int fd) | 20 _FileInputStream.fromStdio(int fd) |
22 : _data = const [], | 21 : _data = const [], |
23 _position = 0, | 22 _position = 0, |
24 _filePosition = 0 { | 23 _filePosition = 0 { |
25 assert(fd == 0); | 24 assert(fd == 0); |
26 _setupOpenedFile(_File._openStdioSync(fd)); | 25 _setupOpenedFile(_File._openStdioSync(fd)); |
27 } | 26 } |
28 | 27 |
29 void _setupOpenedFile(RandomAccessFile openedFile) { | 28 void _setupOpenedFile(RandomAccessFile openedFile) { |
30 _openedFile = openedFile; | 29 _openedFile = openedFile; |
31 if (_streamMarkedClosed) { | 30 if (_streamMarkedClosed) { |
32 // This input stream has already been closed. | 31 // This input stream has already been closed. |
33 _fileLength = 0; | 32 _fileLength = 0; |
34 _closeFile(); | 33 _closeFile(); |
35 return; | 34 return; |
36 } | 35 } |
37 var futureOpen = _openedFile.length(); | 36 var futureOpen = _openedFile.length(); |
38 futureOpen.then((len) { | 37 futureOpen |
39 _fileLength = len; | 38 .then((len) { |
40 _fillBuffer(); | 39 _fileLength = len; |
41 }); | 40 _fillBuffer(); |
42 futureOpen.handleException((e) { | 41 }) |
43 _reportError(e); | 42 .catchError((e) { |
44 return true; | 43 _reportError(e.error); |
45 }); | 44 }); |
46 } | 45 } |
47 | 46 |
48 void _closeFile() { | 47 void _closeFile() { |
49 if (_openedFile == null) { | 48 if (_openedFile == null) { |
50 _streamMarkedClosed = true; | 49 _streamMarkedClosed = true; |
51 return; | 50 return; |
52 } | 51 } |
53 if (available() == 0) _cancelScheduledDataCallback(); | 52 if (available() == 0) _cancelScheduledDataCallback(); |
54 if (!_openedFile.closed) { | 53 if (!_openedFile.closed) { |
55 _openedFile.close().then((ignore) { | 54 _openedFile.close().then((ignore) { |
(...skipping 19 matching lines...) Expand all Loading... |
75 future.then((data) { | 74 future.then((data) { |
76 _data = data; | 75 _data = data; |
77 _position = 0; | 76 _position = 0; |
78 _filePosition += _data.length; | 77 _filePosition += _data.length; |
79 _activeFillBufferCall = false; | 78 _activeFillBufferCall = false; |
80 | 79 |
81 if (_fileLength == _filePosition) { | 80 if (_fileLength == _filePosition) { |
82 _closeFile(); | 81 _closeFile(); |
83 } | 82 } |
84 _checkScheduleCallbacks(); | 83 _checkScheduleCallbacks(); |
85 }); | 84 }).catchError((e) { |
86 future.handleException((e) { | |
87 _activeFillBufferCall = false; | 85 _activeFillBufferCall = false; |
88 _reportError(e); | 86 _reportError(e.error); |
89 return true; | |
90 }); | 87 }); |
91 } | 88 } |
92 | 89 |
93 int available() { | 90 int available() { |
94 return closed ? 0 : _data.length - _position; | 91 return closed ? 0 : _data.length - _position; |
95 } | 92 } |
96 | 93 |
97 void pipe(OutputStream output, {bool close: true}) { | 94 void pipe(OutputStream output, {bool close: true}) { |
98 _pipe(this, output, close: close); | 95 _pipe(this, output, close: close); |
99 } | 96 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 152 |
156 | 153 |
157 class _FileOutputStream extends _BaseOutputStream implements OutputStream { | 154 class _FileOutputStream extends _BaseOutputStream implements OutputStream { |
158 _FileOutputStream(String name, FileMode mode) { | 155 _FileOutputStream(String name, FileMode mode) { |
159 _pendingOperations = new List(); | 156 _pendingOperations = new List(); |
160 var f = new File(name); | 157 var f = new File(name); |
161 var openFuture = f.open(mode); | 158 var openFuture = f.open(mode); |
162 openFuture.then((openedFile) { | 159 openFuture.then((openedFile) { |
163 _file = openedFile; | 160 _file = openedFile; |
164 _processPendingOperations(); | 161 _processPendingOperations(); |
165 }); | 162 }).catchError((e) { |
166 openFuture.handleException((e) { | 163 _reportError(e.error); |
167 _reportError(e); | |
168 return true; | |
169 }); | 164 }); |
170 } | 165 } |
171 | 166 |
172 _FileOutputStream.fromStdio(int fd) { | 167 _FileOutputStream.fromStdio(int fd) { |
173 assert(1 <= fd && fd <= 2); | 168 assert(1 <= fd && fd <= 2); |
174 _file = _File._openStdioSync(fd); | 169 _file = _File._openStdioSync(fd); |
175 } | 170 } |
176 | 171 |
177 bool write(List<int> buffer, [bool copyBuffer = false]) { | 172 bool write(List<int> buffer, [bool copyBuffer = false]) { |
178 var data = buffer; | 173 var data = buffer; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 void _write(List<int> buffer, int offset, int len) { | 255 void _write(List<int> buffer, int offset, int len) { |
261 outstandingWrites++; | 256 outstandingWrites++; |
262 var writeListFuture = _file.writeList(buffer, offset, len); | 257 var writeListFuture = _file.writeList(buffer, offset, len); |
263 writeListFuture.then((ignore) { | 258 writeListFuture.then((ignore) { |
264 outstandingWrites--; | 259 outstandingWrites--; |
265 if (outstandingWrites == 0 && | 260 if (outstandingWrites == 0 && |
266 !_streamMarkedClosed && | 261 !_streamMarkedClosed && |
267 _onNoPendingWrites != null) { | 262 _onNoPendingWrites != null) { |
268 _onNoPendingWrites(); | 263 _onNoPendingWrites(); |
269 } | 264 } |
270 }); | 265 }).catchError((e) { |
271 writeListFuture.handleException((e) { | |
272 outstandingWrites--; | 266 outstandingWrites--; |
273 _reportError(e); | 267 _reportError(e.error); |
274 return true; | |
275 }); | 268 }); |
276 } | 269 } |
277 | 270 |
278 bool get closed => _streamMarkedClosed; | 271 bool get closed => _streamMarkedClosed; |
279 | 272 |
280 RandomAccessFile _file; | 273 RandomAccessFile _file; |
281 | 274 |
282 // When this is set to true the stream is marked closed. When a | 275 // When this is set to true the stream is marked closed. When a |
283 // stream is marked closed no more data can be written. | 276 // stream is marked closed no more data can be written. |
284 bool _streamMarkedClosed = false; | 277 bool _streamMarkedClosed = false; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 throw new ArgumentError('${Error.safeToString(_name)} ' | 349 throw new ArgumentError('${Error.safeToString(_name)} ' |
357 'is not a String'); | 350 'is not a String'); |
358 } | 351 } |
359 } | 352 } |
360 | 353 |
361 // Constructor from Path for file. | 354 // Constructor from Path for file. |
362 _File.fromPath(Path path) : this(path.toNativePath()); | 355 _File.fromPath(Path path) : this(path.toNativePath()); |
363 | 356 |
364 Future<bool> exists() { | 357 Future<bool> exists() { |
365 _ensureFileService(); | 358 _ensureFileService(); |
366 List request = new List(2); | 359 List request = new List.fixedLength(2); |
367 request[0] = _EXISTS_REQUEST; | 360 request[0] = _EXISTS_REQUEST; |
368 request[1] = _name; | 361 request[1] = _name; |
369 return _fileService.call(request).transform((response) { | 362 return _fileService.call(request).then((response) { |
370 if (_isErrorResponse(response)) { | 363 if (_isErrorResponse(response)) { |
371 throw _exceptionFromResponse(response, "Cannot open file '$_name'"); | 364 throw _exceptionFromResponse(response, "Cannot open file '$_name'"); |
372 } | 365 } |
373 return response; | 366 return response; |
374 }); | 367 }); |
375 } | 368 } |
376 | 369 |
377 external static _exists(String name); | 370 external static _exists(String name); |
378 | 371 |
379 bool existsSync() { | 372 bool existsSync() { |
380 var result = _exists(_name); | 373 var result = _exists(_name); |
381 throwIfError(result, "Cannot check existence of file '$_name'"); | 374 throwIfError(result, "Cannot check existence of file '$_name'"); |
382 return result; | 375 return result; |
383 } | 376 } |
384 | 377 |
385 Future<File> create() { | 378 Future<File> create() { |
386 _ensureFileService(); | 379 _ensureFileService(); |
387 List request = new List(2); | 380 List request = new List.fixedLength(2); |
388 request[0] = _CREATE_REQUEST; | 381 request[0] = _CREATE_REQUEST; |
389 request[1] = _name; | 382 request[1] = _name; |
390 return _fileService.call(request).transform((response) { | 383 return _fileService.call(request).then((response) { |
391 if (_isErrorResponse(response)) { | 384 if (_isErrorResponse(response)) { |
392 throw _exceptionFromResponse(response, "Cannot create file '$_name'"); | 385 throw _exceptionFromResponse(response, "Cannot create file '$_name'"); |
393 } | 386 } |
394 return this; | 387 return this; |
395 }); | 388 }); |
396 } | 389 } |
397 | 390 |
398 external static _create(String name); | 391 external static _create(String name); |
399 | 392 |
400 void createSync() { | 393 void createSync() { |
401 var result = _create(_name); | 394 var result = _create(_name); |
402 throwIfError(result, "Cannot create file '$_name'"); | 395 throwIfError(result, "Cannot create file '$_name'"); |
403 } | 396 } |
404 | 397 |
405 Future<File> delete() { | 398 Future<File> delete() { |
406 _ensureFileService(); | 399 _ensureFileService(); |
407 List request = new List(2); | 400 List request = new List.fixedLength(2); |
408 request[0] = _DELETE_REQUEST; | 401 request[0] = _DELETE_REQUEST; |
409 request[1] = _name; | 402 request[1] = _name; |
410 return _fileService.call(request).transform((response) { | 403 return _fileService.call(request).then((response) { |
411 if (_isErrorResponse(response)) { | 404 if (_isErrorResponse(response)) { |
412 throw _exceptionFromResponse(response, "Cannot delete file '$_name'"); | 405 throw _exceptionFromResponse(response, "Cannot delete file '$_name'"); |
413 } | 406 } |
414 return this; | 407 return this; |
415 }); | 408 }); |
416 } | 409 } |
417 | 410 |
418 external static _delete(String name); | 411 external static _delete(String name); |
419 | 412 |
420 void deleteSync() { | 413 void deleteSync() { |
421 var result = _delete(_name); | 414 var result = _delete(_name); |
422 throwIfError(result, "Cannot delete file '$_name'"); | 415 throwIfError(result, "Cannot delete file '$_name'"); |
423 } | 416 } |
424 | 417 |
425 Future<Directory> directory() { | 418 Future<Directory> directory() { |
426 _ensureFileService(); | 419 _ensureFileService(); |
427 List request = new List(2); | 420 List request = new List.fixedLength(2); |
428 request[0] = _DIRECTORY_REQUEST; | 421 request[0] = _DIRECTORY_REQUEST; |
429 request[1] = _name; | 422 request[1] = _name; |
430 return _fileService.call(request).transform((response) { | 423 return _fileService.call(request).then((response) { |
431 if (_isErrorResponse(response)) { | 424 if (_isErrorResponse(response)) { |
432 throw _exceptionFromResponse(response, | 425 throw _exceptionFromResponse(response, |
433 "Cannot retrieve directory for " | 426 "Cannot retrieve directory for " |
434 "file '$_name'"); | 427 "file '$_name'"); |
435 } | 428 } |
436 return new Directory(response); | 429 return new Directory(response); |
437 }); | 430 }); |
438 } | 431 } |
439 | 432 |
440 external static _directory(String name); | 433 external static _directory(String name); |
441 | 434 |
442 Directory directorySync() { | 435 Directory directorySync() { |
443 var result = _directory(name); | 436 var result = _directory(name); |
444 throwIfError(result, "Cannot retrieve directory for file '$_name'"); | 437 throwIfError(result, "Cannot retrieve directory for file '$_name'"); |
445 return new Directory(result); | 438 return new Directory(result); |
446 } | 439 } |
447 | 440 |
448 Future<RandomAccessFile> open([FileMode mode = FileMode.READ]) { | 441 Future<RandomAccessFile> open([FileMode mode = FileMode.READ]) { |
449 _ensureFileService(); | 442 _ensureFileService(); |
450 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 443 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
451 if (mode != FileMode.READ && | 444 if (mode != FileMode.READ && |
452 mode != FileMode.WRITE && | 445 mode != FileMode.WRITE && |
453 mode != FileMode.APPEND) { | 446 mode != FileMode.APPEND) { |
454 new Timer(0, (t) { | 447 new Timer(0, (t) { |
455 completer.completeException(new ArgumentError()); | 448 completer.completeError(new ArgumentError()); |
456 }); | 449 }); |
457 return completer.future; | 450 return completer.future; |
458 } | 451 } |
459 List request = new List(3); | 452 List request = new List.fixedLength(3); |
460 request[0] = _OPEN_REQUEST; | 453 request[0] = _OPEN_REQUEST; |
461 request[1] = _name; | 454 request[1] = _name; |
462 request[2] = mode._mode; // Direct int value for serialization. | 455 request[2] = mode._mode; // Direct int value for serialization. |
463 return _fileService.call(request).transform((response) { | 456 return _fileService.call(request).then((response) { |
464 if (_isErrorResponse(response)) { | 457 if (_isErrorResponse(response)) { |
465 throw _exceptionFromResponse(response, "Cannot open file '$_name'"); | 458 throw _exceptionFromResponse(response, "Cannot open file '$_name'"); |
466 } | 459 } |
467 return new _RandomAccessFile(response, _name); | 460 return new _RandomAccessFile(response, _name); |
468 }); | 461 }); |
469 } | 462 } |
470 | 463 |
471 Future<int> length() { | 464 Future<int> length() { |
472 _ensureFileService(); | 465 _ensureFileService(); |
473 List request = new List(2); | 466 List request = new List.fixedLength(2); |
474 request[0] = _LENGTH_FROM_NAME_REQUEST; | 467 request[0] = _LENGTH_FROM_NAME_REQUEST; |
475 request[1] = _name; | 468 request[1] = _name; |
476 return _fileService.call(request).transform((response) { | 469 return _fileService.call(request).then((response) { |
477 if (_isErrorResponse(response)) { | 470 if (_isErrorResponse(response)) { |
478 throw _exceptionFromResponse(response, | 471 throw _exceptionFromResponse(response, |
479 "Cannot retrieve length of " | 472 "Cannot retrieve length of " |
480 "file '$_name'"); | 473 "file '$_name'"); |
481 } | 474 } |
482 return response; | 475 return response; |
483 }); | 476 }); |
484 } | 477 } |
485 | 478 |
486 | 479 |
487 external static _lengthFromName(String name); | 480 external static _lengthFromName(String name); |
488 | 481 |
489 int lengthSync() { | 482 int lengthSync() { |
490 var result = _lengthFromName(_name); | 483 var result = _lengthFromName(_name); |
491 throwIfError(result, "Cannot retrieve length of file '$_name'"); | 484 throwIfError(result, "Cannot retrieve length of file '$_name'"); |
492 return result; | 485 return result; |
493 } | 486 } |
494 | 487 |
495 Future<Date> lastModified() { | 488 Future<Date> lastModified() { |
496 _ensureFileService(); | 489 _ensureFileService(); |
497 List request = new List(2); | 490 List request = new List.fixedLength(2); |
498 request[0] = _LAST_MODIFIED_REQUEST; | 491 request[0] = _LAST_MODIFIED_REQUEST; |
499 request[1] = _name; | 492 request[1] = _name; |
500 return _fileService.call(request).transform((response) { | 493 return _fileService.call(request).then((response) { |
501 if (_isErrorResponse(response)) { | 494 if (_isErrorResponse(response)) { |
502 throw _exceptionFromResponse(response, | 495 throw _exceptionFromResponse(response, |
503 "Cannot retrieve modification time " | 496 "Cannot retrieve modification time " |
504 "for file '$_name'"); | 497 "for file '$_name'"); |
505 } | 498 } |
506 return new Date.fromMillisecondsSinceEpoch(response); | 499 return new Date.fromMillisecondsSinceEpoch(response); |
507 }); | 500 }); |
508 } | 501 } |
509 | 502 |
510 external static _lastModified(String name); | 503 external static _lastModified(String name); |
(...skipping 23 matching lines...) Expand all Loading... |
534 static RandomAccessFile _openStdioSync(int fd) { | 527 static RandomAccessFile _openStdioSync(int fd) { |
535 var id = _openStdio(fd); | 528 var id = _openStdio(fd); |
536 if (id == 0) { | 529 if (id == 0) { |
537 throw new FileIOException("Cannot open stdio file for: $fd"); | 530 throw new FileIOException("Cannot open stdio file for: $fd"); |
538 } | 531 } |
539 return new _RandomAccessFile(id, ""); | 532 return new _RandomAccessFile(id, ""); |
540 } | 533 } |
541 | 534 |
542 Future<String> fullPath() { | 535 Future<String> fullPath() { |
543 _ensureFileService(); | 536 _ensureFileService(); |
544 List request = new List(2); | 537 List request = new List.fixedLength(2); |
545 request[0] = _FULL_PATH_REQUEST; | 538 request[0] = _FULL_PATH_REQUEST; |
546 request[1] = _name; | 539 request[1] = _name; |
547 return _fileService.call(request).transform((response) { | 540 return _fileService.call(request).then((response) { |
548 if (_isErrorResponse(response)) { | 541 if (_isErrorResponse(response)) { |
549 throw _exceptionFromResponse(response, | 542 throw _exceptionFromResponse(response, |
550 "Cannot retrieve full path" | 543 "Cannot retrieve full path" |
551 " for '$_name'"); | 544 " for '$_name'"); |
552 } | 545 } |
553 return response; | 546 return response; |
554 }); | 547 }); |
555 } | 548 } |
556 | 549 |
557 external static _fullPath(String name); | 550 external static _fullPath(String name); |
(...skipping 24 matching lines...) Expand all Loading... |
582 var stream = openInputStream(); | 575 var stream = openInputStream(); |
583 stream.onClosed = () { | 576 stream.onClosed = () { |
584 var result = chunks.readBytes(chunks.length); | 577 var result = chunks.readBytes(chunks.length); |
585 if (result == null) result = <int>[]; | 578 if (result == null) result = <int>[]; |
586 completer.complete(result); | 579 completer.complete(result); |
587 }; | 580 }; |
588 stream.onData = () { | 581 stream.onData = () { |
589 var chunk = stream.read(); | 582 var chunk = stream.read(); |
590 chunks.add(chunk); | 583 chunks.add(chunk); |
591 }; | 584 }; |
592 stream.onError = completer.completeException; | 585 stream.onError = (e) { |
| 586 completer.completeError(e); |
| 587 }; |
593 return completer.future; | 588 return completer.future; |
594 } | 589 } |
595 | 590 |
596 List<int> readAsBytesSync() { | 591 List<int> readAsBytesSync() { |
597 var opened = openSync(); | 592 var opened = openSync(); |
598 var length = opened.lengthSync(); | 593 var length = opened.lengthSync(); |
599 var result = new Uint8List(length); | 594 var result = new Uint8List(length); |
600 var read = opened.readListSync(result, 0, length); | 595 var read = opened.readListSync(result, 0, length); |
601 if (read != length) { | 596 if (read != length) { |
602 throw new FileIOException("Failed to read file"); | 597 throw new FileIOException("Failed to read file"); |
603 } | 598 } |
604 opened.closeSync(); | 599 opened.closeSync(); |
605 return result; | 600 return result; |
606 } | 601 } |
607 | 602 |
608 Future<String> readAsString([Encoding encoding = Encoding.UTF_8]) { | 603 Future<String> readAsString([Encoding encoding = Encoding.UTF_8]) { |
609 _ensureFileService(); | 604 _ensureFileService(); |
610 return readAsBytes().transform((bytes) { | 605 return readAsBytes().then((bytes) { |
611 if (bytes.length == 0) return ""; | 606 if (bytes.length == 0) return ""; |
612 var decoder = _StringDecoders.decoder(encoding); | 607 var decoder = _StringDecoders.decoder(encoding); |
613 decoder.write(bytes); | 608 decoder.write(bytes); |
614 return decoder.decoded(); | 609 return decoder.decoded(); |
615 }); | 610 }); |
616 } | 611 } |
617 | 612 |
618 String readAsStringSync([Encoding encoding = Encoding.UTF_8]) { | 613 String readAsStringSync([Encoding encoding = Encoding.UTF_8]) { |
619 var decoder = _StringDecoders.decoder(encoding); | 614 var decoder = _StringDecoders.decoder(encoding); |
620 List<int> bytes = readAsBytesSync(); | 615 List<int> bytes = readAsBytesSync(); |
(...skipping 14 matching lines...) Expand all Loading... |
635 var data = decoder.decoded(); | 630 var data = decoder.decoded(); |
636 if (data != null) { | 631 if (data != null) { |
637 result.add(data); | 632 result.add(data); |
638 } | 633 } |
639 return result; | 634 return result; |
640 } | 635 } |
641 | 636 |
642 Future<List<String>> readAsLines([Encoding encoding = Encoding.UTF_8]) { | 637 Future<List<String>> readAsLines([Encoding encoding = Encoding.UTF_8]) { |
643 _ensureFileService(); | 638 _ensureFileService(); |
644 Completer<List<String>> completer = new Completer<List<String>>(); | 639 Completer<List<String>> completer = new Completer<List<String>>(); |
645 return readAsBytes().transform((bytes) { | 640 return readAsBytes().then((bytes) { |
646 var decoder = _StringDecoders.decoder(encoding); | 641 var decoder = _StringDecoders.decoder(encoding); |
647 decoder.write(bytes); | 642 decoder.write(bytes); |
648 return _getDecodedLines(decoder); | 643 return _getDecodedLines(decoder); |
649 }); | 644 }); |
650 } | 645 } |
651 | 646 |
652 List<String> readAsLinesSync([Encoding encoding = Encoding.UTF_8]) { | 647 List<String> readAsLinesSync([Encoding encoding = Encoding.UTF_8]) { |
653 var decoder = _StringDecoders.decoder(encoding); | 648 var decoder = _StringDecoders.decoder(encoding); |
654 List<int> bytes = readAsBytesSync(); | 649 List<int> bytes = readAsBytesSync(); |
655 decoder.write(bytes); | 650 decoder.write(bytes); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 } | 719 } |
725 | 720 |
726 | 721 |
727 class _RandomAccessFile extends _FileBase implements RandomAccessFile { | 722 class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
728 _RandomAccessFile(int this._id, String this._name); | 723 _RandomAccessFile(int this._id, String this._name); |
729 | 724 |
730 Future<RandomAccessFile> close() { | 725 Future<RandomAccessFile> close() { |
731 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 726 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
732 if (closed) return _completeWithClosedException(completer); | 727 if (closed) return _completeWithClosedException(completer); |
733 _ensureFileService(); | 728 _ensureFileService(); |
734 List request = new List(2); | 729 List request = new List.fixedLength(2); |
735 request[0] = _CLOSE_REQUEST; | 730 request[0] = _CLOSE_REQUEST; |
736 request[1] = _id; | 731 request[1] = _id; |
737 // Set the id_ to 0 (NULL) to ensure the no more async requests | 732 // Set the id_ to 0 (NULL) to ensure the no more async requests |
738 // can be issued for this file. | 733 // can be issued for this file. |
739 _id = 0; | 734 _id = 0; |
740 return _fileService.call(request).transform((result) { | 735 return _fileService.call(request).then((result) { |
741 if (result != -1) { | 736 if (result != -1) { |
742 _id = result; | 737 _id = result; |
743 return this; | 738 return this; |
744 } else { | 739 } else { |
745 throw new FileIOException("Cannot close file '$_name'"); | 740 throw new FileIOException("Cannot close file '$_name'"); |
746 } | 741 } |
747 }); | 742 }); |
748 } | 743 } |
749 | 744 |
750 external static int _close(int id); | 745 external static int _close(int id); |
751 | 746 |
752 void closeSync() { | 747 void closeSync() { |
753 _checkNotClosed(); | 748 _checkNotClosed(); |
754 var id = _close(_id); | 749 var id = _close(_id); |
755 if (id == -1) { | 750 if (id == -1) { |
756 throw new FileIOException("Cannot close file '$_name'"); | 751 throw new FileIOException("Cannot close file '$_name'"); |
757 } | 752 } |
758 _id = id; | 753 _id = id; |
759 } | 754 } |
760 | 755 |
761 Future<int> readByte() { | 756 Future<int> readByte() { |
762 _ensureFileService(); | 757 _ensureFileService(); |
763 Completer<int> completer = new Completer<int>(); | 758 Completer<int> completer = new Completer<int>(); |
764 if (closed) return _completeWithClosedException(completer); | 759 if (closed) return _completeWithClosedException(completer); |
765 List request = new List(2); | 760 List request = new List.fixedLength(2); |
766 request[0] = _READ_BYTE_REQUEST; | 761 request[0] = _READ_BYTE_REQUEST; |
767 request[1] = _id; | 762 request[1] = _id; |
768 return _fileService.call(request).transform((response) { | 763 return _fileService.call(request).then((response) { |
769 if (_isErrorResponse(response)) { | 764 if (_isErrorResponse(response)) { |
770 throw _exceptionFromResponse(response, | 765 throw _exceptionFromResponse(response, |
771 "readByte failed for file '$_name'"); | 766 "readByte failed for file '$_name'"); |
772 } | 767 } |
773 return response; | 768 return response; |
774 }); | 769 }); |
775 } | 770 } |
776 | 771 |
777 external static _readByte(int id); | 772 external static _readByte(int id); |
778 | 773 |
(...skipping 17 matching lines...) Expand all Loading... |
796 completer.completeException(new FileIOException( | 791 completer.completeException(new FileIOException( |
797 "Invalid arguments to read for file '$_name'")); | 792 "Invalid arguments to read for file '$_name'")); |
798 }); | 793 }); |
799 return completer.future; | 794 return completer.future; |
800 }; | 795 }; |
801 if (closed) return _completeWithClosedException(completer); | 796 if (closed) return _completeWithClosedException(completer); |
802 List request = new List(3); | 797 List request = new List(3); |
803 request[0] = _READ_REQUEST; | 798 request[0] = _READ_REQUEST; |
804 request[1] = _id; | 799 request[1] = _id; |
805 request[2] = bytes; | 800 request[2] = bytes; |
806 return _fileService.call(request).transform((response) { | 801 return _fileService.call(request).then((response) { |
807 if (_isErrorResponse(response)) { | 802 if (_isErrorResponse(response)) { |
808 throw _exceptionFromResponse(response, | 803 throw _exceptionFromResponse(response, |
809 "read failed for file '$_name'"); | 804 "read failed for file '$_name'"); |
810 } | 805 } |
811 return response[1]; | 806 return response[1]; |
812 }); | 807 }); |
813 } | 808 } |
814 | 809 |
815 external static _read(int id, int bytes); | 810 external static _read(int id, int bytes); |
816 | 811 |
817 List<int> readSync(int bytes) { | 812 List<int> readSync(int bytes) { |
818 if (bytes is !int) { | 813 if (bytes is !int) { |
819 throw new FileIOException( | 814 throw new FileIOException( |
820 "Invalid arguments to readSync for file '$_name'"); | 815 "Invalid arguments to readSync for file '$_name'"); |
821 } | 816 } |
822 return _read(_id, bytes); | 817 return _read(_id, bytes); |
823 } | 818 } |
824 | 819 |
825 Future<int> readList(List<int> buffer, int offset, int bytes) { | 820 Future<int> readList(List<int> buffer, int offset, int bytes) { |
826 _ensureFileService(); | 821 _ensureFileService(); |
827 Completer<int> completer = new Completer<int>(); | 822 Completer<int> completer = new Completer<int>(); |
828 if (buffer is !List || offset is !int || bytes is !int) { | 823 if (buffer is !List || offset is !int || bytes is !int) { |
829 // Complete asynchronously so the user has a chance to setup | 824 // Complete asynchronously so the user has a chance to setup |
830 // handlers without getting exceptions when registering the | 825 // handlers without getting exceptions when registering the |
831 // then handler. | 826 // then handler. |
832 new Timer(0, (t) { | 827 new Timer(0, (t) { |
833 completer.completeException(new FileIOException( | 828 completer.completeError(new FileIOException( |
834 "Invalid arguments to readList for file '$_name'")); | 829 "Invalid arguments to readList for file '$_name'")); |
835 }); | 830 }); |
836 return completer.future; | 831 return completer.future; |
837 }; | 832 }; |
838 if (closed) return _completeWithClosedException(completer); | 833 if (closed) return _completeWithClosedException(completer); |
839 List request = new List(3); | 834 List request = new List.fixedLength(3); |
840 request[0] = _READ_LIST_REQUEST; | 835 request[0] = _READ_LIST_REQUEST; |
841 request[1] = _id; | 836 request[1] = _id; |
842 request[2] = bytes; | 837 request[2] = bytes; |
843 return _fileService.call(request).transform((response) { | 838 return _fileService.call(request).then((response) { |
844 if (_isErrorResponse(response)) { | 839 if (_isErrorResponse(response)) { |
845 throw _exceptionFromResponse(response, | 840 throw _exceptionFromResponse(response, |
846 "readList failed for file '$_name'"); | 841 "readList failed for file '$_name'"); |
847 } | 842 } |
848 var read = response[1]; | 843 var read = response[1]; |
849 var data = response[2]; | 844 var data = response[2]; |
850 buffer.setRange(offset, read, data); | 845 buffer.setRange(offset, read, data); |
851 return read; | 846 return read; |
852 }); | 847 }); |
853 } | 848 } |
(...skipping 25 matching lines...) Expand all Loading... |
879 } | 874 } |
880 | 875 |
881 Future<RandomAccessFile> writeByte(int value) { | 876 Future<RandomAccessFile> writeByte(int value) { |
882 _ensureFileService(); | 877 _ensureFileService(); |
883 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 878 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
884 if (value is !int) { | 879 if (value is !int) { |
885 // Complete asynchronously so the user has a chance to setup | 880 // Complete asynchronously so the user has a chance to setup |
886 // handlers without getting exceptions when registering the | 881 // handlers without getting exceptions when registering the |
887 // then handler. | 882 // then handler. |
888 new Timer(0, (t) { | 883 new Timer(0, (t) { |
889 completer.completeException(new FileIOException( | 884 completer.completeError(new FileIOException( |
890 "Invalid argument to writeByte for file '$_name'")); | 885 "Invalid argument to writeByte for file '$_name'")); |
891 }); | 886 }); |
892 return completer.future; | 887 return completer.future; |
893 } | 888 } |
894 if (closed) return _completeWithClosedException(completer); | 889 if (closed) return _completeWithClosedException(completer); |
895 List request = new List(3); | 890 List request = new List.fixedLength(3); |
896 request[0] = _WRITE_BYTE_REQUEST; | 891 request[0] = _WRITE_BYTE_REQUEST; |
897 request[1] = _id; | 892 request[1] = _id; |
898 request[2] = value; | 893 request[2] = value; |
899 return _fileService.call(request).transform((response) { | 894 return _fileService.call(request).then((response) { |
900 if (_isErrorResponse(response)) { | 895 if (_isErrorResponse(response)) { |
901 throw _exceptionFromResponse(response, | 896 throw _exceptionFromResponse(response, |
902 "writeByte failed for file '$_name'"); | 897 "writeByte failed for file '$_name'"); |
903 } | 898 } |
904 return this; | 899 return this; |
905 }); | 900 }); |
906 } | 901 } |
907 | 902 |
908 external static _writeByte(int id, int value); | 903 external static _writeByte(int id, int value); |
909 | 904 |
(...skipping 12 matching lines...) Expand all Loading... |
922 } | 917 } |
923 | 918 |
924 Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) { | 919 Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) { |
925 _ensureFileService(); | 920 _ensureFileService(); |
926 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 921 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
927 if (buffer is !List || offset is !int || bytes is !int) { | 922 if (buffer is !List || offset is !int || bytes is !int) { |
928 // Complete asynchronously so the user has a chance to setup | 923 // Complete asynchronously so the user has a chance to setup |
929 // handlers without getting exceptions when registering the | 924 // handlers without getting exceptions when registering the |
930 // then handler. | 925 // then handler. |
931 new Timer(0, (t) { | 926 new Timer(0, (t) { |
932 completer.completeException(new FileIOException( | 927 completer.completeError(new FileIOException( |
933 "Invalid arguments to writeList for file '$_name'")); | 928 "Invalid arguments to writeList for file '$_name'")); |
934 }); | 929 }); |
935 return completer.future; | 930 return completer.future; |
936 } | 931 } |
937 if (closed) return _completeWithClosedException(completer); | 932 if (closed) return _completeWithClosedException(completer); |
938 | 933 |
939 _BufferAndOffset result; | 934 _BufferAndOffset result; |
940 try { | 935 try { |
941 result = _ensureFastAndSerializableBuffer(buffer, offset, bytes); | 936 result = _ensureFastAndSerializableBuffer(buffer, offset, bytes); |
942 } catch (e) { | 937 } catch (e) { |
943 // Complete asynchronously so the user has a chance to setup | 938 // Complete asynchronously so the user has a chance to setup |
944 // handlers without getting exceptions when registering the | 939 // handlers without getting exceptions when registering the |
945 // then handler. | 940 // then handler. |
946 new Timer(0, (t) => completer.completeException(e)); | 941 new Timer(0, (t) => completer.completeError(e)); |
947 return completer.future; | 942 return completer.future; |
948 } | 943 } |
949 | 944 |
950 List request = new List(5); | 945 List request = new List.fixedLength(5); |
951 request[0] = _WRITE_LIST_REQUEST; | 946 request[0] = _WRITE_LIST_REQUEST; |
952 request[1] = _id; | 947 request[1] = _id; |
953 request[2] = result.buffer; | 948 request[2] = result.buffer; |
954 request[3] = result.offset; | 949 request[3] = result.offset; |
955 request[4] = bytes; | 950 request[4] = bytes; |
956 return _fileService.call(request).transform((response) { | 951 return _fileService.call(request).then((response) { |
957 if (_isErrorResponse(response)) { | 952 if (_isErrorResponse(response)) { |
958 throw _exceptionFromResponse(response, | 953 throw _exceptionFromResponse(response, |
959 "writeList failed for file '$_name'"); | 954 "writeList failed for file '$_name'"); |
960 } | 955 } |
961 return this; | 956 return this; |
962 }); | 957 }); |
963 } | 958 } |
964 | 959 |
965 external static _writeList(int id, List<int> buffer, int offset, int bytes); | 960 external static _writeList(int id, List<int> buffer, int offset, int bytes); |
966 | 961 |
(...skipping 13 matching lines...) Expand all Loading... |
980 throw new FileIOException("writeList failed for file '$_name'", result); | 975 throw new FileIOException("writeList failed for file '$_name'", result); |
981 } | 976 } |
982 return result; | 977 return result; |
983 } | 978 } |
984 | 979 |
985 Future<RandomAccessFile> writeString(String string, | 980 Future<RandomAccessFile> writeString(String string, |
986 [Encoding encoding = Encoding.UTF_8]) { | 981 [Encoding encoding = Encoding.UTF_8]) { |
987 if (encoding is! Encoding) { | 982 if (encoding is! Encoding) { |
988 var completer = new Completer(); | 983 var completer = new Completer(); |
989 new Timer(0, (t) { | 984 new Timer(0, (t) { |
990 completer.completeException(new FileIOException( | 985 completer.completeError(new FileIOException( |
991 "Invalid encoding in writeString: $encoding")); | 986 "Invalid encoding in writeString: $encoding")); |
992 }); | 987 }); |
993 return completer.future; | 988 return completer.future; |
994 } | 989 } |
995 var data = _StringEncoders.encoder(encoding).encodeString(string); | 990 var data = _StringEncoders.encoder(encoding).encodeString(string); |
996 return writeList(data, 0, data.length); | 991 return writeList(data, 0, data.length); |
997 } | 992 } |
998 | 993 |
999 int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) { | 994 int writeStringSync(String string, [Encoding encoding = Encoding.UTF_8]) { |
1000 if (encoding is! Encoding) { | 995 if (encoding is! Encoding) { |
1001 throw new FileIOException( | 996 throw new FileIOException( |
1002 "Invalid encoding in writeStringSync: $encoding"); | 997 "Invalid encoding in writeStringSync: $encoding"); |
1003 } | 998 } |
1004 var data = _StringEncoders.encoder(encoding).encodeString(string); | 999 var data = _StringEncoders.encoder(encoding).encodeString(string); |
1005 return writeListSync(data, 0, data.length); | 1000 return writeListSync(data, 0, data.length); |
1006 } | 1001 } |
1007 | 1002 |
1008 Future<int> position() { | 1003 Future<int> position() { |
1009 _ensureFileService(); | 1004 _ensureFileService(); |
1010 Completer<int> completer = new Completer<int>(); | 1005 Completer<int> completer = new Completer<int>(); |
1011 if (closed) return _completeWithClosedException(completer); | 1006 if (closed) return _completeWithClosedException(completer); |
1012 List request = new List(2); | 1007 List request = new List.fixedLength(2); |
1013 request[0] = _POSITION_REQUEST; | 1008 request[0] = _POSITION_REQUEST; |
1014 request[1] = _id; | 1009 request[1] = _id; |
1015 return _fileService.call(request).transform((response) { | 1010 return _fileService.call(request).then((response) { |
1016 if (_isErrorResponse(response)) { | 1011 if (_isErrorResponse(response)) { |
1017 throw _exceptionFromResponse(response, | 1012 throw _exceptionFromResponse(response, |
1018 "position failed for file '$_name'"); | 1013 "position failed for file '$_name'"); |
1019 } | 1014 } |
1020 return response; | 1015 return response; |
1021 }); | 1016 }); |
1022 } | 1017 } |
1023 | 1018 |
1024 external static _position(int id); | 1019 external static _position(int id); |
1025 | 1020 |
1026 int positionSync() { | 1021 int positionSync() { |
1027 _checkNotClosed(); | 1022 _checkNotClosed(); |
1028 var result = _position(_id); | 1023 var result = _position(_id); |
1029 if (result is OSError) { | 1024 if (result is OSError) { |
1030 throw new FileIOException("position failed for file '$_name'", result); | 1025 throw new FileIOException("position failed for file '$_name'", result); |
1031 } | 1026 } |
1032 return result; | 1027 return result; |
1033 } | 1028 } |
1034 | 1029 |
1035 Future<RandomAccessFile> setPosition(int position) { | 1030 Future<RandomAccessFile> setPosition(int position) { |
1036 _ensureFileService(); | 1031 _ensureFileService(); |
1037 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1032 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
1038 if (closed) return _completeWithClosedException(completer); | 1033 if (closed) return _completeWithClosedException(completer); |
1039 List request = new List(3); | 1034 List request = new List.fixedLength(3); |
1040 request[0] = _SET_POSITION_REQUEST; | 1035 request[0] = _SET_POSITION_REQUEST; |
1041 request[1] = _id; | 1036 request[1] = _id; |
1042 request[2] = position; | 1037 request[2] = position; |
1043 return _fileService.call(request).transform((response) { | 1038 return _fileService.call(request).then((response) { |
1044 if (_isErrorResponse(response)) { | 1039 if (_isErrorResponse(response)) { |
1045 throw _exceptionFromResponse(response, | 1040 throw _exceptionFromResponse(response, |
1046 "setPosition failed for file '$_name'"); | 1041 "setPosition failed for file '$_name'"); |
1047 } | 1042 } |
1048 return this; | 1043 return this; |
1049 }); | 1044 }); |
1050 } | 1045 } |
1051 | 1046 |
1052 external static _setPosition(int id, int position); | 1047 external static _setPosition(int id, int position); |
1053 | 1048 |
1054 void setPositionSync(int position) { | 1049 void setPositionSync(int position) { |
1055 _checkNotClosed(); | 1050 _checkNotClosed(); |
1056 var result = _setPosition(_id, position); | 1051 var result = _setPosition(_id, position); |
1057 if (result is OSError) { | 1052 if (result is OSError) { |
1058 throw new FileIOException("setPosition failed for file '$_name'", result); | 1053 throw new FileIOException("setPosition failed for file '$_name'", result); |
1059 } | 1054 } |
1060 } | 1055 } |
1061 | 1056 |
1062 Future<RandomAccessFile> truncate(int length) { | 1057 Future<RandomAccessFile> truncate(int length) { |
1063 _ensureFileService(); | 1058 _ensureFileService(); |
1064 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1059 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
1065 if (closed) return _completeWithClosedException(completer); | 1060 if (closed) return _completeWithClosedException(completer); |
1066 List request = new List(3); | 1061 List request = new List.fixedLength(3); |
1067 request[0] = _TRUNCATE_REQUEST; | 1062 request[0] = _TRUNCATE_REQUEST; |
1068 request[1] = _id; | 1063 request[1] = _id; |
1069 request[2] = length; | 1064 request[2] = length; |
1070 return _fileService.call(request).transform((response) { | 1065 return _fileService.call(request).then((response) { |
1071 if (_isErrorResponse(response)) { | 1066 if (_isErrorResponse(response)) { |
1072 throw _exceptionFromResponse(response, | 1067 throw _exceptionFromResponse(response, |
1073 "truncate failed for file '$_name'"); | 1068 "truncate failed for file '$_name'"); |
1074 } | 1069 } |
1075 return this; | 1070 return this; |
1076 }); | 1071 }); |
1077 } | 1072 } |
1078 | 1073 |
1079 external static _truncate(int id, int length); | 1074 external static _truncate(int id, int length); |
1080 | 1075 |
1081 void truncateSync(int length) { | 1076 void truncateSync(int length) { |
1082 _checkNotClosed(); | 1077 _checkNotClosed(); |
1083 var result = _truncate(_id, length); | 1078 var result = _truncate(_id, length); |
1084 if (result is OSError) { | 1079 if (result is OSError) { |
1085 throw new FileIOException("truncate failed for file '$_name'", result); | 1080 throw new FileIOException("truncate failed for file '$_name'", result); |
1086 } | 1081 } |
1087 } | 1082 } |
1088 | 1083 |
1089 Future<int> length() { | 1084 Future<int> length() { |
1090 _ensureFileService(); | 1085 _ensureFileService(); |
1091 Completer<int> completer = new Completer<int>(); | 1086 Completer<int> completer = new Completer<int>(); |
1092 if (closed) return _completeWithClosedException(completer); | 1087 if (closed) return _completeWithClosedException(completer); |
1093 List request = new List(2); | 1088 List request = new List.fixedLength(2); |
1094 request[0] = _LENGTH_REQUEST; | 1089 request[0] = _LENGTH_REQUEST; |
1095 request[1] = _id; | 1090 request[1] = _id; |
1096 return _fileService.call(request).transform((response) { | 1091 return _fileService.call(request).then((response) { |
1097 if (_isErrorResponse(response)) { | 1092 if (_isErrorResponse(response)) { |
1098 throw _exceptionFromResponse(response, | 1093 throw _exceptionFromResponse(response, |
1099 "length failed for file '$_name'"); | 1094 "length failed for file '$_name'"); |
1100 } | 1095 } |
1101 return response; | 1096 return response; |
1102 }); | 1097 }); |
1103 } | 1098 } |
1104 | 1099 |
1105 external static _length(int id); | 1100 external static _length(int id); |
1106 | 1101 |
1107 int lengthSync() { | 1102 int lengthSync() { |
1108 _checkNotClosed(); | 1103 _checkNotClosed(); |
1109 var result = _length(_id); | 1104 var result = _length(_id); |
1110 if (result is OSError) { | 1105 if (result is OSError) { |
1111 throw new FileIOException("length failed for file '$_name'", result); | 1106 throw new FileIOException("length failed for file '$_name'", result); |
1112 } | 1107 } |
1113 return result; | 1108 return result; |
1114 } | 1109 } |
1115 | 1110 |
1116 Future<RandomAccessFile> flush() { | 1111 Future<RandomAccessFile> flush() { |
1117 _ensureFileService(); | 1112 _ensureFileService(); |
1118 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1113 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
1119 if (closed) return _completeWithClosedException(completer); | 1114 if (closed) return _completeWithClosedException(completer); |
1120 List request = new List(2); | 1115 List request = new List.fixedLength(2); |
1121 request[0] = _FLUSH_REQUEST; | 1116 request[0] = _FLUSH_REQUEST; |
1122 request[1] = _id; | 1117 request[1] = _id; |
1123 return _fileService.call(request).transform((response) { | 1118 return _fileService.call(request).then((response) { |
1124 if (_isErrorResponse(response)) { | 1119 if (_isErrorResponse(response)) { |
1125 throw _exceptionFromResponse(response, | 1120 throw _exceptionFromResponse(response, |
1126 "flush failed for file '$_name'"); | 1121 "flush failed for file '$_name'"); |
1127 } | 1122 } |
1128 return this; | 1123 return this; |
1129 }); | 1124 }); |
1130 } | 1125 } |
1131 | 1126 |
1132 external static _flush(int id); | 1127 external static _flush(int id); |
1133 | 1128 |
(...skipping 16 matching lines...) Expand all Loading... |
1150 bool get closed => _id == 0; | 1145 bool get closed => _id == 0; |
1151 | 1146 |
1152 void _checkNotClosed() { | 1147 void _checkNotClosed() { |
1153 if (closed) { | 1148 if (closed) { |
1154 throw new FileIOException("File closed '$_name'"); | 1149 throw new FileIOException("File closed '$_name'"); |
1155 } | 1150 } |
1156 } | 1151 } |
1157 | 1152 |
1158 Future _completeWithClosedException(Completer completer) { | 1153 Future _completeWithClosedException(Completer completer) { |
1159 new Timer(0, (t) { | 1154 new Timer(0, (t) { |
1160 completer.completeException( | 1155 completer.completeError( |
1161 new FileIOException("File closed '$_name'")); | 1156 new FileIOException("File closed '$_name'")); |
1162 }); | 1157 }); |
1163 return completer.future; | 1158 return completer.future; |
1164 } | 1159 } |
1165 | 1160 |
1166 final String _name; | 1161 final String _name; |
1167 int _id; | 1162 int _id; |
1168 | 1163 |
1169 SendPort _fileService; | 1164 SendPort _fileService; |
1170 } | 1165 } |
OLD | NEW |