Skip to content
This repository was archived by the owner on Oct 27, 2022. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 36 additions & 47 deletions lib/files.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,23 @@
*/
library files;

import 'dart:async';
import 'dart:convert';

abstract class FileSystem {

File getFile(String path);

Directory getDirectory(String path);

}

abstract class FileSystemEntry {

String get path;

Future<FileSystemEntry> rename(String newPath);

Future<FileSystemEntry> delete({bool recursive: false});

}

abstract class File extends FileSystemEntry {

Future<DateTime> lastModified();

Future<bool> exists();
Expand All @@ -48,19 +42,16 @@ abstract class File extends FileSystemEntry {
// Future<List<int>> readAsBytes() => openRead().toList()
// .then((l) => l.expand((i) => i));

FileSink openWrite({FileMode mode: FileMode.WRITE,
Encoding encoding: UTF8});
FileSink openWrite({FileMode mode: FileMode.WRITE, Encoding encoding: UTF8});

Future<File> writeAsString(String contents, {Encoding encoding: UTF8});

Future<File> rename(String newPath);

Future<File> delete({bool recursive: false});

}

abstract class Directory extends FileSystemEntry {

Future<Directory> create({bool recursive: false});

Stream<FileSystemEntry> list({bool recursive: false, bool followLinks: true});
Expand All @@ -72,10 +63,12 @@ abstract class Directory extends FileSystemEntry {
class FileMode {
/// The mode for opening a file only for reading.
static const READ = const FileMode._internal(0);

/// The mode for opening a file for reading and writing. The file is
/// overwritten if it already exists. The file is created if it does not
/// already exist.
static const WRITE = const FileMode._internal(1);

/// The mode for opening a file for reading and writing to the
/// end of it. The file is created if it does not already exist.
static const APPEND = const FileMode._internal(2);
Expand All @@ -100,8 +93,8 @@ class FileMode {
*/
abstract class FileSink implements StreamSink<List<int>>, StringSink {
factory FileSink(StreamConsumer<List<int>> target,
{Encoding encoding: UTF8})
=> new _FileSinkImpl(target, encoding);
{Encoding encoding: UTF8}) =>
new _FileSinkImpl(target, encoding);

/**
* The [Encoding] used when writing strings. Depending on the underlying
Expand Down Expand Up @@ -212,7 +205,7 @@ class _FileSinkImpl extends _StreamSinkImpl<List<int>> implements FileSink {
_FileSinkImpl(StreamConsumer<List<int>> target, this.encoding)
: super(target);

void set encoding(Encoding _encoding) { }
void set encoding(Encoding _encoding) {}

void write(Object obj) {
// This comment is copied from runtime/lib/string_buffer_patch.dart.
Expand Down Expand Up @@ -287,11 +280,11 @@ class _StreamSinkImpl<T> implements StreamSink<T> {
if (_hasError) return done;
// Wait for any sync operations to complete.
Future targetAddStream() {
return _target.addStream(stream)
.whenComplete(() {
_isBound = false;
});
return _target.addStream(stream).whenComplete(() {
_isBound = false;
});
}

if (_controllerInstance == null) return targetAddStream();
var future = _controllerCompleter.future;
_controllerInstance.close();
Expand All @@ -309,8 +302,8 @@ class _StreamSinkImpl<T> implements StreamSink<T> {
var future = _controllerCompleter.future;
_controllerInstance.close();
return future.whenComplete(() {
_isBound = false;
});
_isBound = false;
});
}

Future close() {
Expand All @@ -329,9 +322,8 @@ class _StreamSinkImpl<T> implements StreamSink<T> {
}

void _closeTarget() {
_target.close()
.then((value) => _completeDone(value: value),
onError: (error) => _completeDone(error: error));
_target.close().then((value) => _completeDone(value: value),
onError: (error) => _completeDone(error: error));
}

Future get done => _doneFuture;
Expand All @@ -357,31 +349,28 @@ class _StreamSinkImpl<T> implements StreamSink<T> {
if (_controllerInstance == null) {
_controllerInstance = new StreamController<T>(sync: true);
_controllerCompleter = new Completer();
_target.addStream(_controller.stream)
.then(
(_) {
if (_isBound) {
// A new stream takes over - forward values to that stream.
_controllerCompleter.complete(this);
_controllerCompleter = null;
_controllerInstance = null;
} else {
// No new stream, .close was called. Close _target.
_closeTarget();
}
},
onError: (error) {
if (_isBound) {
// A new stream takes over - forward errors to that stream.
_controllerCompleter.completeError(error);
_controllerCompleter = null;
_controllerInstance = null;
} else {
// No new stream. No need to close target, as it have already
// failed.
_completeDone(error: error);
}
});
_target.addStream(_controller.stream).then((_) {
if (_isBound) {
// A new stream takes over - forward values to that stream.
_controllerCompleter.complete(this);
_controllerCompleter = null;
_controllerInstance = null;
} else {
// No new stream, .close was called. Close _target.
_closeTarget();
}
}, onError: (error) {
if (_isBound) {
// A new stream takes over - forward errors to that stream.
_controllerCompleter.completeError(error);
_controllerCompleter = null;
_controllerInstance = null;
} else {
// No new stream. No need to close target, as it have already
// failed.
_completeDone(error: error);
}
});
}
return _controllerInstance;
}
Expand Down