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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/io/file_impl.dart

Issue 2698353003: unfork DDC's copy of most SDK libraries (Closed)
Patch Set: revert core_patch Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of dart.io;
6
7 // Read the file in blocks of size 64k.
8 const int _BLOCK_SIZE = 64 * 1024;
9
10
11 class _FileStream extends Stream<List<int>> {
12 // Stream controller.
13 StreamController<List<int>> _controller;
14
15 // Information about the underlying file.
16 String _path;
17 RandomAccessFile _openedFile;
18 int _position;
19 int _end;
20 final Completer _closeCompleter = new Completer();
21
22 // Has the stream been paused or unsubscribed?
23 bool _unsubscribed = false;
24
25 // Is there a read currently in progress?
26 bool _readInProgress = true;
27 bool _closed = false;
28
29 bool _atEnd = false;
30
31 _FileStream(this._path, this._position, this._end) {
32 if (_position == null) _position = 0;
33 }
34
35 _FileStream.forStdin() : _position = 0;
36
37 StreamSubscription<List<int>> listen(void onData(List<int> event),
38 {Function onError,
39 void onDone(),
40 bool cancelOnError}) {
41 _setupController();
42 return _controller.stream.listen(onData,
43 onError: onError,
44 onDone: onDone,
45 cancelOnError: cancelOnError);
46 }
47
48 void _setupController() {
49 _controller = new StreamController<List<int>>(sync: true,
50 onListen: _start,
51 onResume: _readBlock,
52 onCancel: () {
53 _unsubscribed = true;
54 return _closeFile();
55 });
56 }
57
58 Future _closeFile() {
59 if (_readInProgress || _closed) {
60 return _closeCompleter.future;
61 }
62 _closed = true;
63
64 void done() {
65 _closeCompleter.complete();
66 _controller.close();
67 }
68
69 _openedFile.close()
70 .catchError(_controller.addError)
71 .whenComplete(done);
72 return _closeCompleter.future;
73 }
74
75 void _readBlock() {
76 // Don't start a new read if one is already in progress.
77 if (_readInProgress) return;
78 if (_atEnd) {
79 _closeFile();
80 return;
81 }
82 _readInProgress = true;
83 int readBytes = _BLOCK_SIZE;
84 if (_end != null) {
85 readBytes = min(readBytes, _end - _position);
86 if (readBytes < 0) {
87 _readInProgress = false;
88 if (!_unsubscribed) {
89 _controller.addError(new RangeError("Bad end position: $_end"));
90 _closeFile();
91 _unsubscribed = true;
92 }
93 return;
94 }
95 }
96 _openedFile.read(readBytes)
97 .then((block) {
98 _readInProgress = false;
99 if (_unsubscribed) {
100 _closeFile();
101 return;
102 }
103 _position += block.length;
104 if (block.length < readBytes ||
105 (_end != null && _position == _end)) {
106 _atEnd = true;
107 }
108 if (!_atEnd && !_controller.isPaused) {
109 _readBlock();
110 }
111 _controller.add(block);
112 if (_atEnd) {
113 _closeFile();
114 }
115 })
116 .catchError((e, s) {
117 if (!_unsubscribed) {
118 _controller.addError(e, s);
119 _closeFile();
120 _unsubscribed = true;
121 }
122 });
123 }
124
125 void _start() {
126 if (_position < 0) {
127 _controller.addError(new RangeError("Bad start position: $_position"));
128 _controller.close();
129 _closeCompleter.complete();
130 return;
131 }
132
133 void onReady(RandomAccessFile file) {
134 _openedFile = file;
135 _readInProgress = false;
136 _readBlock();
137 }
138
139 void onOpenFile(RandomAccessFile file) {
140 if (_position > 0) {
141 file.setPosition(_position)
142 .then(onReady, onError: (e, s) {
143 _controller.addError(e, s);
144 _readInProgress = false;
145 _closeFile();
146 });
147 } else {
148 onReady(file);
149 }
150 }
151
152 void openFailed(error, stackTrace) {
153 _controller.addError(error, stackTrace);
154 _controller.close();
155 _closeCompleter.complete();
156 }
157
158 if (_path != null) {
159 new File(_path).open(mode: FileMode.READ)
160 .then(onOpenFile, onError: openFailed);
161 } else {
162 try {
163 onOpenFile(_File._openStdioSync(0));
164 } catch (e, s) {
165 openFailed(e, s);
166 }
167 }
168 }
169 }
170
171 class _FileStreamConsumer extends StreamConsumer<List<int>> {
172 File _file;
173 Future<RandomAccessFile> _openFuture;
174
175 _FileStreamConsumer(File this._file, FileMode mode) {
176 _openFuture = _file.open(mode: mode);
177 }
178
179 _FileStreamConsumer.fromStdio(int fd) {
180 assert(1 <= fd && fd <= 2);
181 _openFuture = new Future.value(_File._openStdioSync(fd));
182 }
183
184 Future<File> addStream(Stream<List<int>> stream) {
185 Completer<File> completer = new Completer<File>.sync();
186 _openFuture
187 .then((openedFile) {
188 var _subscription;
189 void error(e, [StackTrace stackTrace]) {
190 _subscription.cancel();
191 openedFile.close();
192 completer.completeError(e, stackTrace);
193 }
194 _subscription = stream.listen(
195 (d) {
196 _subscription.pause();
197 try {
198 openedFile.writeFrom(d, 0, d.length)
199 .then((_) => _subscription.resume(),
200 onError: error);
201 } catch (e, stackTrace) {
202 error(e, stackTrace);
203 }
204 },
205 onDone: () {
206 completer.complete(_file);
207 },
208 onError: error,
209 cancelOnError: true);
210 })
211 .catchError(completer.completeError);
212 return completer.future;
213 }
214
215 Future<File> close() =>
216 _openFuture.then((openedFile) => openedFile.close());
217 }
218
219
220 // Class for encapsulating the native implementation of files.
221 class _File extends FileSystemEntity implements File {
222 final String path;
223
224 // Constructor for file.
225 _File(this.path) {
226 if (path is! String) {
227 throw new ArgumentError('${Error.safeToString(path)} '
228 'is not a String');
229 }
230 }
231
232 Future<bool> exists() {
233 return _IOService._dispatch(_FILE_EXISTS, [path]).then((response) {
234 if (_isErrorResponse(response)) {
235 throw _exceptionFromResponse(response, "Cannot check existence", path);
236 }
237 return response;
238 });
239 }
240
241 external static _exists(String path);
242
243 bool existsSync() {
244 var result = _exists(path);
245 throwIfError(result, "Cannot check existence of file", path);
246 return result;
247 }
248
249 File get absolute => new File(_absolutePath);
250
251 Future<FileStat> stat() => FileStat.stat(path);
252
253 FileStat statSync() => FileStat.statSync(path);
254
255 Future<File> create({bool recursive: false}) {
256 var result = recursive ? parent.create(recursive: true)
257 : new Future.value(null);
258 return result
259 .then((_) => _IOService._dispatch(_FILE_CREATE, [path]))
260 .then((response) {
261 if (_isErrorResponse(response)) {
262 throw _exceptionFromResponse(response, "Cannot create file", path);
263 }
264 return this;
265 });
266 }
267
268 external static _create(String path);
269
270 external static _createLink(String path, String target);
271
272 external static _linkTarget(String path);
273
274 void createSync({bool recursive: false}) {
275 if (recursive) {
276 parent.createSync(recursive: true);
277 }
278 var result = _create(path);
279 throwIfError(result, "Cannot create file", path);
280 }
281
282 Future<File> _delete({bool recursive: false}) {
283 if (recursive) {
284 return new Directory(path).delete(recursive: true).then((_) => this);
285 }
286 return _IOService._dispatch(_FILE_DELETE, [path]).then((response) {
287 if (_isErrorResponse(response)) {
288 throw _exceptionFromResponse(response, "Cannot delete file", path);
289 }
290 return this;
291 });
292 }
293
294 external static _deleteNative(String path);
295
296 external static _deleteLinkNative(String path);
297
298 void _deleteSync({bool recursive: false}) {
299 if (recursive) {
300 return new Directory(path).deleteSync(recursive: true);
301 }
302 var result = _deleteNative(path);
303 throwIfError(result, "Cannot delete file", path);
304 }
305
306 Future<File> rename(String newPath) {
307 return _IOService._dispatch(_FILE_RENAME, [path, newPath]).then((response) {
308 if (_isErrorResponse(response)) {
309 throw _exceptionFromResponse(
310 response, "Cannot rename file to '$newPath'", path);
311 }
312 return new File(newPath);
313 });
314 }
315
316 external static _rename(String oldPath, String newPath);
317
318 external static _renameLink(String oldPath, String newPath);
319
320 File renameSync(String newPath) {
321 var result = _rename(path, newPath);
322 throwIfError(result, "Cannot rename file to '$newPath'", path);
323 return new File(newPath);
324 }
325
326 Future<File> copy(String newPath) {
327 return _IOService._dispatch(_FILE_COPY, [path, newPath]).then((response) {
328 if (_isErrorResponse(response)) {
329 throw _exceptionFromResponse(
330 response, "Cannot copy file to '$newPath'", path);
331 }
332 return new File(newPath);
333 });
334 }
335
336 external static _copy(String oldPath, String newPath);
337
338 File copySync(String newPath) {
339 var result = _copy(path, newPath);
340 throwIfError(result, "Cannot copy file to '$newPath'", path);
341 return new File(newPath);
342 }
343
344 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) {
345 if (mode != FileMode.READ &&
346 mode != FileMode.WRITE &&
347 mode != FileMode.APPEND &&
348 mode != FileMode.WRITE_ONLY &&
349 mode != FileMode.WRITE_ONLY_APPEND) {
350 return new Future.error(
351 new ArgumentError('Invalid file mode for this operation'));
352 }
353 return _IOService._dispatch(_FILE_OPEN, [path, mode._mode])
354 .then((response) {
355 if (_isErrorResponse(response)) {
356 throw _exceptionFromResponse(response, "Cannot open file", path);
357 }
358 return new _RandomAccessFile(response, path);
359 });
360 }
361
362 Future<int> length() {
363 return _IOService._dispatch(_FILE_LENGTH_FROM_PATH, [path])
364 .then((response) {
365 if (_isErrorResponse(response)) {
366 throw _exceptionFromResponse(response,
367 "Cannot retrieve length of file",
368 path);
369 }
370 return response;
371 });
372 }
373
374
375 external static _lengthFromPath(String path);
376
377 int lengthSync() {
378 var result = _lengthFromPath(path);
379 throwIfError(result, "Cannot retrieve length of file", path);
380 return result;
381 }
382
383 Future<DateTime> lastModified() {
384 return _IOService._dispatch(_FILE_LAST_MODIFIED, [path]).then((response) {
385 if (_isErrorResponse(response)) {
386 throw _exceptionFromResponse(response,
387 "Cannot retrieve modification time",
388 path);
389 }
390 return new DateTime.fromMillisecondsSinceEpoch(response);
391 });
392 }
393
394 external static _lastModified(String path);
395
396 DateTime lastModifiedSync() {
397 var ms = _lastModified(path);
398 throwIfError(ms, "Cannot retrieve modification time", path);
399 return new DateTime.fromMillisecondsSinceEpoch(ms);
400 }
401
402 external static _open(String path, int mode);
403
404 RandomAccessFile openSync({FileMode mode: FileMode.READ}) {
405 if (mode != FileMode.READ &&
406 mode != FileMode.WRITE &&
407 mode != FileMode.APPEND &&
408 mode != FileMode.WRITE_ONLY &&
409 mode != FileMode.WRITE_ONLY_APPEND) {
410 throw new ArgumentError('Invalid file mode for this operation');
411 }
412 var id = _open(path, mode._mode);
413 throwIfError(id, "Cannot open file", path);
414 return new _RandomAccessFile(id, path);
415 }
416
417 external static int _openStdio(int fd);
418
419 static RandomAccessFile _openStdioSync(int fd) {
420 var id = _openStdio(fd);
421 if (id == 0) {
422 throw new FileSystemException("Cannot open stdio file for: $fd");
423 }
424 return new _RandomAccessFile(id, "");
425 }
426
427 Stream<List<int>> openRead([int start, int end]) {
428 return new _FileStream(path, start, end);
429 }
430
431 IOSink openWrite({FileMode mode: FileMode.WRITE,
432 Encoding encoding: UTF8}) {
433 if (mode != FileMode.WRITE &&
434 mode != FileMode.APPEND &&
435 mode != FileMode.WRITE_ONLY &&
436 mode != FileMode.WRITE_ONLY_APPEND) {
437 throw new ArgumentError('Invalid file mode for this operation');
438 }
439 var consumer = new _FileStreamConsumer(this, mode);
440 return new IOSink(consumer, encoding: encoding);
441 }
442
443 Future<List<int>> readAsBytes() {
444 Future<List<int>> readDataChunked(file) {
445 var builder = new BytesBuilder(copy: false);
446 var completer = new Completer();
447 void read() {
448 file.read(_BLOCK_SIZE).then((data) {
449 if (data.length > 0) {
450 builder.add(data);
451 read();
452 } else {
453 completer.complete(builder.takeBytes());
454 }
455 }, onError: completer.completeError);
456 }
457 read();
458 return completer.future;
459 }
460
461 return open().then((file) {
462 return file.length().then((length) {
463 if (length == 0) {
464 // May be character device, try to read it in chunks.
465 return readDataChunked(file);
466 }
467 return file.read(length);
468 }).whenComplete(file.close);
469 });
470 }
471
472 List<int> readAsBytesSync() {
473 var opened = openSync();
474 try {
475 var data;
476 var length = opened.lengthSync();
477 if (length == 0) {
478 // May be character device, try to read it in chunks.
479 var builder = new BytesBuilder(copy: false);
480 do {
481 data = opened.readSync(_BLOCK_SIZE);
482 if (data.length > 0) builder.add(data);
483 } while (data.length > 0);
484 data = builder.takeBytes();
485 } else {
486 data = opened.readSync(length);
487 }
488 return data;
489 } finally {
490 opened.closeSync();
491 }
492 }
493
494 String _tryDecode(List<int> bytes, Encoding encoding) {
495 try {
496 return encoding.decode(bytes);
497 } catch (_) {
498 throw new FileSystemException(
499 "Failed to decode data using encoding '${encoding.name}'", path);
500 }
501 }
502
503 Future<String> readAsString({Encoding encoding: UTF8}) =>
504 readAsBytes().then((bytes) => _tryDecode(bytes, encoding));
505
506 String readAsStringSync({Encoding encoding: UTF8}) =>
507 _tryDecode(readAsBytesSync(), encoding);
508
509 Future<List<String>> readAsLines({Encoding encoding: UTF8}) =>
510 readAsString(encoding: encoding).then(const LineSplitter().convert);
511
512 List<String> readAsLinesSync({Encoding encoding: UTF8}) =>
513 const LineSplitter().convert(readAsStringSync(encoding: encoding));
514
515 Future<File> writeAsBytes(List<int> bytes,
516 {FileMode mode: FileMode.WRITE,
517 bool flush: false}) {
518 return open(mode: mode).then((file) {
519 return file.writeFrom(bytes, 0, bytes.length)
520 .then((_) {
521 if (flush) return file.flush().then((_) => this);
522 return this;
523 })
524 .whenComplete(file.close);
525 });
526 }
527
528 void writeAsBytesSync(List<int> bytes,
529 {FileMode mode: FileMode.WRITE,
530 bool flush: false}) {
531 RandomAccessFile opened = openSync(mode: mode);
532 try {
533 opened.writeFromSync(bytes, 0, bytes.length);
534 if (flush) opened.flushSync();
535 } finally {
536 opened.closeSync();
537 }
538 }
539
540 Future<File> writeAsString(String contents,
541 {FileMode mode: FileMode.WRITE,
542 Encoding encoding: UTF8,
543 bool flush: false}) {
544 try {
545 return writeAsBytes(encoding.encode(contents), mode: mode, flush: flush);
546 } catch (e) {
547 return new Future.error(e);
548 }
549 }
550
551 void writeAsStringSync(String contents,
552 {FileMode mode: FileMode.WRITE,
553 Encoding encoding: UTF8,
554 bool flush: false}) {
555 writeAsBytesSync(encoding.encode(contents), mode: mode, flush: flush);
556 }
557
558 String toString() => "File: '$path'";
559
560 static throwIfError(Object result, String msg, String path) {
561 if (result is OSError) {
562 throw new FileSystemException(msg, path, result);
563 }
564 }
565 }
566
567 abstract class _RandomAccessFileOps {
568 external factory _RandomAccessFileOps(int pointer);
569
570 int getPointer();
571 int close();
572 readByte();
573 read(int bytes);
574 readInto(List<int> buffer, int start, int end);
575 writeByte(int value);
576 writeFrom(List<int> buffer, int start, int end);
577 position();
578 setPosition(int position);
579 truncate(int length);
580 length();
581 flush();
582 lock(int lock, int start, int end);
583 }
584
585 class _RandomAccessFile implements RandomAccessFile {
586 static bool _connectedResourceHandler = false;
587
588 final String path;
589
590 bool _asyncDispatched = false;
591 SendPort _fileService;
592
593 _FileResourceInfo _resourceInfo;
594 _RandomAccessFileOps _ops;
595
596 _RandomAccessFile(int pointer, this.path) {
597 _ops = new _RandomAccessFileOps(pointer);
598 _resourceInfo = new _FileResourceInfo(this);
599 _maybeConnectHandler();
600 }
601
602 void _maybePerformCleanup() {
603 if (closed) {
604 _FileResourceInfo.FileClosed(_resourceInfo);
605 }
606 }
607
608 _maybeConnectHandler() {
609 if (!_connectedResourceHandler) {
610 // TODO(ricow): We probably need to set these in some initialization code.
611 // We need to make sure that these are always available from the
612 // observatory even if no files (or sockets for the socket ones) are
613 // open.
614 registerExtension('ext.dart.io.getOpenFiles',
615 _FileResourceInfo.getOpenFiles);
616 registerExtension('ext.dart.io.getFileByID',
617 _FileResourceInfo.getFileInfoMapByID);
618 _connectedResourceHandler = true;
619 }
620 }
621
622 Future<RandomAccessFile> close() {
623 return _dispatch(_FILE_CLOSE, [null], markClosed: true).then((result) {
624 if (result != -1) {
625 closed = closed || (result == 0);
626 _maybePerformCleanup();
627 return this;
628 } else {
629 throw new FileSystemException("Cannot close file", path);
630 }
631 });
632 }
633
634 void closeSync() {
635 _checkAvailable();
636 var id = _ops.close();
637 if (id == -1) {
638 throw new FileSystemException("Cannot close file", path);
639 }
640 closed = closed || (id == 0);
641 _maybePerformCleanup();
642 }
643
644 Future<int> readByte() {
645 return _dispatch(_FILE_READ_BYTE, [null]).then((response) {
646 if (_isErrorResponse(response)) {
647 throw _exceptionFromResponse(response, "readByte failed", path);
648 }
649 _resourceInfo.addRead(1);
650 return response;
651 });
652 }
653
654 int readByteSync() {
655 _checkAvailable();
656 var result = _ops.readByte();
657 if (result is OSError) {
658 throw new FileSystemException("readByte failed", path, result);
659 }
660 _resourceInfo.addRead(1);
661 return result;
662 }
663
664 Future<List<int>> read(int bytes) {
665 if (bytes is !int) {
666 throw new ArgumentError(bytes);
667 }
668 return _dispatch(_FILE_READ, [null, bytes]).then((response) {
669 if (_isErrorResponse(response)) {
670 throw _exceptionFromResponse(response, "read failed", path);
671 }
672 _resourceInfo.addRead(response[1].length);
673 return response[1];
674 });
675 }
676
677 List<int> readSync(int bytes) {
678 _checkAvailable();
679 if (bytes is !int) {
680 throw new ArgumentError(bytes);
681 }
682 var result = _ops.read(bytes);
683 if (result is OSError) {
684 throw new FileSystemException("readSync failed", path, result);
685 }
686 _resourceInfo.addRead(result.length);
687 return result;
688 }
689
690 Future<int> readInto(List<int> buffer, [int start = 0, int end]) {
691 if ((buffer is !List) ||
692 ((start != null) && (start is !int)) ||
693 ((end != null) && (end is !int))) {
694 throw new ArgumentError();
695 }
696 end = RangeError.checkValidRange(start, end, buffer.length);
697 if (end == start) {
698 return new Future.value(0);
699 }
700 int length = end - start;
701 return _dispatch(_FILE_READ_INTO, [null, length]).then((response) {
702 if (_isErrorResponse(response)) {
703 throw _exceptionFromResponse(response, "readInto failed", path);
704 }
705 var read = response[1];
706 var data = response[2];
707 buffer.setRange(start, start + read, data);
708 _resourceInfo.addRead(read);
709 return read;
710 });
711 }
712
713 int readIntoSync(List<int> buffer, [int start = 0, int end]) {
714 _checkAvailable();
715 if ((buffer is !List) ||
716 ((start != null) && (start is !int)) ||
717 ((end != null) && (end is !int))) {
718 throw new ArgumentError();
719 }
720 end = RangeError.checkValidRange(start, end, buffer.length);
721 if (end == start) {
722 return 0;
723 }
724 var result = _ops.readInto(buffer, start, end);
725 if (result is OSError) {
726 throw new FileSystemException("readInto failed", path, result);
727 }
728 _resourceInfo.addRead(result);
729 return result;
730 }
731
732 Future<RandomAccessFile> writeByte(int value) {
733 if (value is !int) {
734 throw new ArgumentError(value);
735 }
736 return _dispatch(_FILE_WRITE_BYTE, [null, value]).then((response) {
737 if (_isErrorResponse(response)) {
738 throw _exceptionFromResponse(response, "writeByte failed", path);
739 }
740 _resourceInfo.addWrite(1);
741 return this;
742 });
743 }
744
745 int writeByteSync(int value) {
746 _checkAvailable();
747 if (value is !int) {
748 throw new ArgumentError(value);
749 }
750 var result = _ops.writeByte(value);
751 if (result is OSError) {
752 throw new FileSystemException("writeByte failed", path, result);
753 }
754 _resourceInfo.addWrite(1);
755 return result;
756 }
757
758 Future<RandomAccessFile> writeFrom(
759 List<int> buffer, [int start = 0, int end]) {
760 if ((buffer is !List) ||
761 ((start != null) && (start is !int)) ||
762 ((end != null) && (end is !int))) {
763 throw new ArgumentError("Invalid arguments to writeFrom");
764 }
765 end = RangeError.checkValidRange(start, end, buffer.length);
766 if (end == start) {
767 return new Future.value(this);
768 }
769 _BufferAndStart result;
770 try {
771 result = _ensureFastAndSerializableByteData(buffer, start, end);
772 } catch (e) {
773 return new Future.error(e);
774 }
775
776 List request = new List(4);
777 request[0] = null;
778 request[1] = result.buffer;
779 request[2] = result.start;
780 request[3] = end - (start - result.start);
781 return _dispatch(_FILE_WRITE_FROM, request).then((response) {
782 if (_isErrorResponse(response)) {
783 throw _exceptionFromResponse(response, "writeFrom failed", path);
784 }
785 _resourceInfo.addWrite(end - (start - result.start));
786 return this;
787 });
788 }
789
790 void writeFromSync(List<int> buffer, [int start = 0, int end]) {
791 _checkAvailable();
792 if ((buffer is !List) ||
793 ((start != null) && (start is !int)) ||
794 ((end != null) && (end is !int))) {
795 throw new ArgumentError("Invalid arguments to writeFromSync");
796 }
797 end = RangeError.checkValidRange(start, end, buffer.length);
798 if (end == start) {
799 return;
800 }
801 _BufferAndStart bufferAndStart =
802 _ensureFastAndSerializableByteData(buffer, start, end);
803 var result = _ops.writeFrom(bufferAndStart.buffer,
804 bufferAndStart.start,
805 end - (start - bufferAndStart.start));
806 if (result is OSError) {
807 throw new FileSystemException("writeFrom failed", path, result);
808 }
809 _resourceInfo.addWrite(end - (start - bufferAndStart.start));
810 }
811
812 Future<RandomAccessFile> writeString(String string,
813 {Encoding encoding: UTF8}) {
814 if (encoding is! Encoding) {
815 throw new ArgumentError(encoding);
816 }
817 var data = encoding.encode(string);
818 return writeFrom(data, 0, data.length);
819 }
820
821 void writeStringSync(String string, {Encoding encoding: UTF8}) {
822 if (encoding is! Encoding) {
823 throw new ArgumentError(encoding);
824 }
825 var data = encoding.encode(string);
826 writeFromSync(data, 0, data.length);
827 }
828
829 Future<int> position() {
830 return _dispatch(_FILE_POSITION, [null]).then((response) {
831 if (_isErrorResponse(response)) {
832 throw _exceptionFromResponse(response, "position failed", path);
833 }
834 return response;
835 });
836 }
837
838 int positionSync() {
839 _checkAvailable();
840 var result = _ops.position();
841 if (result is OSError) {
842 throw new FileSystemException("position failed", path, result);
843 }
844 return result;
845 }
846
847 Future<RandomAccessFile> setPosition(int position) {
848 return _dispatch(_FILE_SET_POSITION, [null, position])
849 .then((response) {
850 if (_isErrorResponse(response)) {
851 throw _exceptionFromResponse(response, "setPosition failed", path);
852 }
853 return this;
854 });
855 }
856
857 void setPositionSync(int position) {
858 _checkAvailable();
859 var result = _ops.setPosition(position);
860 if (result is OSError) {
861 throw new FileSystemException("setPosition failed", path, result);
862 }
863 }
864
865 Future<RandomAccessFile> truncate(int length) {
866 return _dispatch(_FILE_TRUNCATE, [null, length]).then((response) {
867 if (_isErrorResponse(response)) {
868 throw _exceptionFromResponse(response, "truncate failed", path);
869 }
870 return this;
871 });
872 }
873
874 void truncateSync(int length) {
875 _checkAvailable();
876 var result = _ops.truncate(length);
877 if (result is OSError) {
878 throw new FileSystemException("truncate failed", path, result);
879 }
880 }
881
882 Future<int> length() {
883 return _dispatch(_FILE_LENGTH, [null]).then((response) {
884 if (_isErrorResponse(response)) {
885 throw _exceptionFromResponse(response, "length failed", path);
886 }
887 return response;
888 });
889 }
890
891 int lengthSync() {
892 _checkAvailable();
893 var result = _ops.length();
894 if (result is OSError) {
895 throw new FileSystemException("length failed", path, result);
896 }
897 return result;
898 }
899
900 Future<RandomAccessFile> flush() {
901 return _dispatch(_FILE_FLUSH, [null]).then((response) {
902 if (_isErrorResponse(response)) {
903 throw _exceptionFromResponse(response,
904 "flush failed",
905 path);
906 }
907 return this;
908 });
909 }
910
911 void flushSync() {
912 _checkAvailable();
913 var result = _ops.flush();
914 if (result is OSError) {
915 throw new FileSystemException("flush failed", path, result);
916 }
917 }
918
919 static final int LOCK_UNLOCK = 0;
920 static final int LOCK_SHARED = 1;
921 static final int LOCK_EXCLUSIVE = 2;
922
923 Future<RandomAccessFile> lock(
924 [FileLock mode = FileLock.EXCLUSIVE, int start = 0, int end = -1]) {
925 if ((mode is !FileLock) || (start is !int) || (end is !int)) {
926 throw new ArgumentError();
927 }
928 if ((start < 0) || (end < -1) || ((end != -1) && (start >= end))) {
929 throw new ArgumentError();
930 }
931 int lock = (mode == FileLock.EXCLUSIVE) ? LOCK_EXCLUSIVE : LOCK_SHARED;
932 return _dispatch(_FILE_LOCK, [null, lock, start, end])
933 .then((response) {
934 if (_isErrorResponse(response)) {
935 throw _exceptionFromResponse(response, 'lock failed', path);
936 }
937 return this;
938 });
939 }
940
941 Future<RandomAccessFile> unlock([int start = 0, int end = -1]) {
942 if ((start is !int) || (end is !int)) {
943 throw new ArgumentError();
944 }
945 if (start == end) {
946 throw new ArgumentError();
947 }
948 return _dispatch(_FILE_LOCK, [null, LOCK_UNLOCK, start, end])
949 .then((response) {
950 if (_isErrorResponse(response)) {
951 throw _exceptionFromResponse(response, 'unlock failed', path);
952 }
953 return this;
954 });
955 }
956
957 void lockSync(
958 [FileLock mode = FileLock.EXCLUSIVE, int start = 0, int end = -1]) {
959 _checkAvailable();
960 if ((mode is !FileLock) || (start is !int) || (end is !int)) {
961 throw new ArgumentError();
962 }
963 if ((start < 0) || (end < -1) || ((end != -1) && (start >= end))) {
964 throw new ArgumentError();
965 }
966 int lock = (mode == FileLock.EXCLUSIVE) ? LOCK_EXCLUSIVE : LOCK_SHARED;
967 var result = _ops.lock(lock, start, end);
968 if (result is OSError) {
969 throw new FileSystemException('lock failed', path, result);
970 }
971 }
972
973 void unlockSync([int start = 0, int end = -1]) {
974 _checkAvailable();
975 if ((start is !int) || (end is !int)) {
976 throw new ArgumentError();
977 }
978 if (start == end) {
979 throw new ArgumentError();
980 }
981 var result = _ops.lock(LOCK_UNLOCK, start, end);
982 if (result is OSError) {
983 throw new FileSystemException('unlock failed', path, result);
984 }
985 }
986
987 bool closed = false;
988
989 // Calling this function will increase the reference count on the native
990 // object that implements the file operations. It should only be called to
991 // pass the pointer to the IO Service, which will decrement the reference
992 // count when it is finished with it.
993 int _pointer() => _ops.getPointer();
994
995 Future _dispatch(int request, List data, { bool markClosed: false }) {
996 if (closed) {
997 return new Future.error(new FileSystemException("File closed", path));
998 }
999 if (_asyncDispatched) {
1000 var msg = "An async operation is currently pending";
1001 return new Future.error(new FileSystemException(msg, path));
1002 }
1003 if (markClosed) {
1004 // Set closed to true to ensure that no more async requests can be issued
1005 // for this file.
1006 closed = true;
1007 }
1008 _asyncDispatched = true;
1009 data[0] = _pointer();
1010 return _IOService._dispatch(request, data)
1011 .whenComplete(() {
1012 _asyncDispatched = false;
1013 });
1014 }
1015
1016 void _checkAvailable() {
1017 if (_asyncDispatched) {
1018 throw new FileSystemException("An async operation is currently pending",
1019 path);
1020 }
1021 if (closed) {
1022 throw new FileSystemException("File closed", path);
1023 }
1024 }
1025 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/lib/io/file.dart ('k') | pkg/dev_compiler/tool/input_sdk/lib/io/file_system_entity.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698