Skip to content

Commit

Permalink
Implement LocalFileSystem with new interface (flutter#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
tvolkert authored Dec 9, 2016
1 parent 18a00a3 commit d9a0e72
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 71 deletions.
1 change: 1 addition & 0 deletions lib/local.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/backends/local.dart';
4 changes: 3 additions & 1 deletion lib/src/backends/local.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
library file.src.backends.local;

import 'dart:async';
import 'dart:convert';
import 'dart:io' as io;

import 'package:file/src/interface.dart';
import 'package:file/file.dart';

part 'local/local_directory.dart';
part 'local/local_file.dart';
part 'local/local_file_system.dart';
part 'local/local_file_system_entity.dart';
part 'local/local_link.dart';
67 changes: 45 additions & 22 deletions lib/src/backends/local/local_directory.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,55 @@
part of file.src.backends.local;

class _LocalDirectory extends _LocalFileSystemEntity implements Directory {
_LocalDirectory(io.Directory entity, FileSystem system)
: super(entity, system);
class _LocalDirectory extends _LocalFileSystemEntity<
_LocalDirectory,
io.Directory> implements Directory {

_LocalDirectory(FileSystem fileSystem, io.Directory delegate)
: super(fileSystem, delegate);

@override
Future<Directory> copy(String newPath) async {
throw new UnsupportedError('Not a supported operation');
}
_LocalDirectory _createNew(io.Directory delegate) =>
new _LocalDirectory(fileSystem, delegate);

@override
Future<Directory> create({bool recursive: false}) async {
return new _LocalDirectory(
await (_ioEntity as io.Directory).create(recursive: recursive),
fileSystem);
}
Future<Directory> create({bool recursive: false}) async =>
_createNew(await _delegate.create(recursive: recursive));

@override
void createSync({bool recursive: false}) =>
_delegate.createSync(recursive: recursive);

@override
Future<Directory> createTemp([String prefix]) async =>
_createNew(await _delegate.createTemp(prefix));

@override
Directory createTempSync([String prefix]) =>
_createNew(_delegate.createTempSync(prefix));

@override
Stream<FileSystemEntity> list({bool recursive: false}) {
io.Directory directory = _ioEntity;
return directory.list(recursive: recursive).map((entity) {
if (entity is io.File) {
return new _LocalFile(entity, fileSystem);
}
if (entity is io.Directory) {
return new _LocalDirectory(entity, fileSystem);
}
return null;
}).where((e) => e != null);
Stream<FileSystemEntity> list({
bool recursive: false,
bool followLinks: true,
}) => _delegate.list(recursive: recursive, followLinks: followLinks)
.map(_wrap);

@override
List<FileSystemEntity> listSync({
bool recursive: false,
bool followLinks: true,
}) => _delegate.listSync(recursive: recursive, followLinks: followLinks)
.map((io.FileSystemEntity entity) => _wrap(entity))
.toList();

FileSystemEntity _wrap(io.FileSystemEntity entity) {
if (entity is io.File) {
return new _LocalFile(fileSystem, entity);
} else if (entity is io.Directory) {
return new _LocalDirectory(fileSystem, entity);
} else if (entity is io.Link) {
return new _LocalLink(fileSystem, entity);
}
throw new io.FileSystemException('Unsupported type: $entity');
}
}
127 changes: 107 additions & 20 deletions lib/src/backends/local/local_file.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,122 @@
part of file.src.backends.local;

class _LocalFile extends _LocalFileSystemEntity implements File {
_LocalFile(io.File entity, FileSystem system) : super(entity, system);
class _LocalFile extends _LocalFileSystemEntity<File, io.File> implements File {
_LocalFile(FileSystem fileSystem, io.File delegate)
: super(fileSystem, delegate);

@override
Future<File> copy(String newPath) async {
return new _LocalFile(
await (_ioEntity as io.File).copy(newPath), fileSystem);
}
_LocalFile _createNew(io.File delegate) =>
new _LocalFile(fileSystem, delegate);

@override
Future<File> create({bool recursive: false}) async {
return new _LocalFile(
await (_ioEntity as io.File).create(recursive: recursive), fileSystem);
}
Future<File> create({bool recursive: false}) async =>
_createNew(await _delegate.create(recursive: recursive));

@override
Future<List<int>> readAsBytes() => (_ioEntity as io.File).readAsBytes();
void createSync({bool recursive: false}) =>
_delegate.createSync(recursive: recursive);

@override
Future<String> readAsString() => (_ioEntity as io.File).readAsString();
Future<File> copy(String newPath) async =>
_createNew(await _delegate.copy(newPath));

@override
Future<File> writeAsBytes(List<int> contents) async {
return new _LocalFile(
await (_ioEntity as io.File).writeAsBytes(contents), fileSystem);
}
File copySync(String newPath) => _createNew(_delegate.copySync(newPath));

@override
Future<File> writeAsString(String contents) async {
return new _LocalFile(
await (_ioEntity as io.File).writeAsString(contents), fileSystem);
}
Future<int> length() => _delegate.length();

@override
int lengthSync() => _delegate.lengthSync();

@override
Future<DateTime> lastModified() => _delegate.lastModified();

@override
DateTime lastModifiedSync() => _delegate.lastModifiedSync();

@override
Future<io.RandomAccessFile> open({
io.FileMode mode: io.FileMode.READ,
}) async => _delegate.open(mode: mode);

@override
io.RandomAccessFile openSync({io.FileMode mode: io.FileMode.READ}) =>
_delegate.openSync(mode: mode);

@override
Stream<List<int>> openRead([int start, int end]) =>
_delegate.openRead(start, end);

@override
io.IOSink openWrite({
io.FileMode mode: io.FileMode.WRITE,
Encoding encoding: UTF8,
}) => _delegate.openWrite(mode: mode, encoding: encoding);

@override
Future<List<int>> readAsBytes() => _delegate.readAsBytes();

@override
List<int> readAsBytesSync() => _delegate.readAsBytesSync();

@override
Future<String> readAsString({Encoding encoding: UTF8}) =>
_delegate.readAsString(encoding: encoding);

@override
String readAsStringSync({Encoding encoding: UTF8}) =>
_delegate.readAsStringSync(encoding: encoding);

@override
Future<List<String>> readAsLines({Encoding encoding: UTF8}) =>
_delegate.readAsLines(encoding: encoding);

@override
List<String> readAsLinesSync({Encoding encoding: UTF8}) =>
_delegate.readAsLinesSync(encoding: encoding);

@override
Future<File> writeAsBytes(
List<int> bytes, {
io.FileMode mode: io.FileMode.WRITE,
bool flush: false,
}) async => _createNew(await _delegate.writeAsBytes(
bytes,
mode: mode,
flush: flush,
));

@override
void writeAsBytesSync(
List<int> bytes, {
io.FileMode mode: io.FileMode.WRITE,
bool flush: false,
}) => _delegate.writeAsBytesSync(bytes, mode: mode, flush: flush);

@override
Future<File> writeAsString(
String contents, {
io.FileMode mode: io.FileMode.WRITE,
Encoding encoding: UTF8,
bool flush: false,
}) async => _createNew(await _delegate.writeAsString(
contents,
mode: mode,
encoding: encoding,
flush: flush,
));

@override
void writeAsStringSync(
String contents, {
io.FileMode mode: io.FileMode.WRITE,
Encoding encoding: UTF8,
bool flush: false,
}) => _delegate.writeAsStringSync(
contents,
mode: mode,
encoding: encoding,
flush: flush,
);
}
46 changes: 32 additions & 14 deletions lib/src/backends/local/local_file_system.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
part of file.src.backends.local;

/// A wrapper implementation around `dart:io`'s implementation.
class LocalFileSystem implements FileSystem {
class LocalFileSystem extends FileSystem {
const LocalFileSystem();

@override
Directory directory(String path) =>
new _LocalDirectory(new io.Directory(path), this);
new _LocalDirectory(this, new io.Directory(path));

@override
File file(String path) => new _LocalFile(new io.File(path), this);
File file(String path) => new _LocalFile(this, new io.File(path));

@override
Future<FileSystemEntityType> type(String path,
{bool followLinks: true}) async {
var type = await io.FileSystemEntity.type(path);
if (type == io.FileSystemEntityType.FILE) {
return FileSystemEntityType.FILE;
} else if (type == io.FileSystemEntityType.DIRECTORY) {
return FileSystemEntityType.DIRECTORY;
} else {
return FileSystemEntityType.NOT_FOUND;
}
}
Directory get currentDirectory => directory(io.Directory.current.path);

@override
set currentDirectory(dynamic path) => io.Directory.current = path;

@override
Future<io.FileStat> stat(String path) => io.FileStat.stat(path);

@override
io.FileStat statSync(String path) => io.FileStat.statSync(path);

@override
Future<bool> identical(String path1, String path2) =>
io.FileSystemEntity.identical(path1, path2);

@override
bool identicalSync(String path1, String path2) =>
io.FileSystemEntity.identicalSync(path1, path2);

@override
bool get isWatchSupported => io.FileSystemEntity.isWatchSupported;

@override
Future<io.FileSystemEntityType> type(String path, {bool followLinks: true}) =>
io.FileSystemEntity.type(path, followLinks: followLinks);

@override
io.FileSystemEntityType typeSync(String path, {bool followLinks: true}) =>
io.FileSystemEntity.typeSync(path, followLinks: followLinks);
}
70 changes: 56 additions & 14 deletions lib/src/backends/local/local_file_system_entity.dart
Original file line number Diff line number Diff line change
@@ -1,31 +1,73 @@
part of file.src.backends.local;

abstract class _LocalFileSystemEntity implements FileSystemEntity {
abstract class _LocalFileSystemEntity<
T extends FileSystemEntity,
D extends io.FileSystemEntity
> implements FileSystemEntity {

@override
final FileSystem fileSystem;

io.FileSystemEntity _ioEntity;
final D _delegate;

_LocalFileSystemEntity(this.fileSystem, this._delegate);

/// Creates a new entity with the same file system as this entity but backed
/// by the specified delegate.
T _createNew(D delegate);

@override
Uri get uri => _delegate.uri;

@override
Future<bool> exists() => _delegate.exists();

@override
bool existsSync() => _delegate.existsSync();

@override
Future<T> rename(String newPath) async =>
_createNew(await _delegate.rename(newPath) as D);

@override
T renameSync(String newPath) =>
_createNew(_delegate.renameSync(newPath) as D);

@override
Future<String> resolveSymbolicLinks() => _delegate.resolveSymbolicLinks();

@override
String resolveSymbolicLinksSync() => _delegate.resolveSymbolicLinksSync();

@override
Future<io.FileStat> stat() => _delegate.stat();

@override
io.FileStat statSync() => _delegate.statSync();

_LocalFileSystemEntity(this._ioEntity, this.fileSystem);
@override
Future<T> delete({bool recursive: false}) async =>
_createNew(await _delegate.delete(recursive: recursive) as D);

@override
void deleteSync({bool recursive: false}) =>
_delegate.deleteSync(recursive: recursive);

@override
Future<FileSystemEntity> delete({bool recursive: false}) async {
await _ioEntity.delete(recursive: recursive);
return this;
}
Stream<io.FileSystemEvent> watch({
int events: io.FileSystemEvent.ALL,
bool recursive: false,
}) => _delegate.watch(events: events, recursive: recursive);

@override
Future<bool> exists() => _ioEntity.exists();
bool get isAbsolute => _delegate.isAbsolute;

@override
Directory get parent => new _LocalDirectory(_ioEntity.parent, fileSystem);
T get absolute => _createNew(_delegate.absolute as D);

@override
String get path => _ioEntity.path;
Directory get parent => new _LocalDirectory(fileSystem, _delegate.parent);

@override
Future<FileSystemEntity> rename(String newPath) async {
_ioEntity = await _ioEntity.rename(newPath);
return this;
}
String get path => _delegate.path;
}
Loading

0 comments on commit d9a0e72

Please sign in to comment.