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

Unified Diff: tool/input_sdk/lib/io/directory_impl.dart

Issue 1976103003: Migrate dart2js stubs for dart:io (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tool/input_sdk/lib/io/directory.dart ('k') | tool/input_sdk/lib/io/eventhandler.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tool/input_sdk/lib/io/directory_impl.dart
diff --git a/tool/input_sdk/lib/io/directory_impl.dart b/tool/input_sdk/lib/io/directory_impl.dart
new file mode 100644
index 0000000000000000000000000000000000000000..52cf54824ecf4e8ed14a4b5491ade076c4a32471
--- /dev/null
+++ b/tool/input_sdk/lib/io/directory_impl.dart
@@ -0,0 +1,428 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.io;
+
+class _Directory extends FileSystemEntity implements Directory {
+ final String path;
+
+ _Directory(this.path) {
+ if (path is! String) {
+ throw new ArgumentError('${Error.safeToString(path)} '
+ 'is not a String');
+ }
+ }
+
+ external static _current();
+ external static _setCurrent(path);
+ external static _createTemp(String path);
+ external static String _systemTemp();
+ external static _exists(String path);
+ external static _create(String path);
+ external static _deleteNative(String path, bool recursive);
+ external static _rename(String path, String newPath);
+ external static void _fillWithDirectoryListing(
+ List<FileSystemEntity> list, String path, bool recursive,
+ bool followLinks);
+
+ static Directory get current {
+ var result = _current();
+ if (result is OSError) {
+ throw new FileSystemException(
+ "Getting current working directory failed", "", result);
+ }
+ return new _Directory(result);
+ }
+
+ static void set current(path) {
+ if (path is Directory) path = path.path;
+ var result = _setCurrent(path);
+ if (result is ArgumentError) throw result;
+ if (result is OSError) {
+ throw new FileSystemException(
+ "Setting current working directory failed", path, result);
+ }
+ }
+
+ Uri get uri {
+ return new Uri.directory(path);
+ }
+
+ Future<bool> exists() {
+ return _IOService._dispatch(_DIRECTORY_EXISTS, [path]).then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(response, "Exists failed");
+ }
+ return response == 1;
+ });
+ }
+
+ bool existsSync() {
+ var result = _exists(path);
+ if (result is OSError) {
+ throw new FileSystemException("Exists failed", path, result);
+ }
+ return (result == 1);
+ }
+
+ Directory get absolute => new Directory(_absolutePath);
+
+ Future<FileStat> stat() => FileStat.stat(path);
+
+ FileStat statSync() => FileStat.statSync(path);
+
+ // Compute the index of the first directory in the list that exists. If
+ // none of the directories exist dirsToCreate.length is returned.
+ Future<int> _computeExistingIndex(List dirsToCreate) {
+ var future;
+ var notFound = dirsToCreate.length;
+ for (var i = 0; i < dirsToCreate.length; i++) {
+ if (future == null) {
+ future = dirsToCreate[i].exists().then((e) => e ? i : notFound);
+ } else {
+ future = future.then((index) {
+ if (index != notFound) {
+ return new Future.value(index);
+ }
+ return dirsToCreate[i].exists().then((e) => e ? i : notFound);
+ });
+ }
+ }
+ if (future == null) {
+ return new Future.value(notFound);
+ } else {
+ return future;
+ }
+ }
+
+ Future<Directory> create({bool recursive: false}) {
+ if (recursive) {
+ return exists().then((exists) {
+ if (exists) return this;
+ if (path != parent.path) {
+ return parent.create(recursive: true).then((_) {
+ return create();
+ });
+ } else {
+ return create();
+ }
+ });
+ } else {
+ return _IOService._dispatch(_DIRECTORY_CREATE, [path]).then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(response, "Creation failed");
+ }
+ return this;
+ });
+ }
+ }
+
+ void createSync({bool recursive: false}) {
+ if (recursive) {
+ if (existsSync()) return;
+ if (path != parent.path) {
+ parent.createSync(recursive: true);
+ }
+ }
+ var result = _create(path);
+ if (result is OSError) {
+ throw new FileSystemException("Creation failed", path, result);
+ }
+ }
+
+ static Directory get systemTemp => new Directory(_systemTemp());
+
+ Future<Directory> createTemp([String prefix]) {
+ if (prefix == null) prefix = '';
+ if (path == '') {
+ throw new ArgumentError(
+ "Directory.createTemp called with an empty path. "
+ "To use the system temp directory, use Directory.systemTemp");
+ }
+ String fullPrefix;
+ if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
+ fullPrefix = "$path$prefix";
+ } else {
+ fullPrefix = "$path${Platform.pathSeparator}$prefix";
+ }
+ return _IOService._dispatch(_DIRECTORY_CREATE_TEMP, [fullPrefix])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(
+ response, "Creation of temporary directory failed");
+ }
+ return new Directory(response);
+ });
+ }
+
+ Directory createTempSync([String prefix]) {
+ if (prefix == null) prefix = '';
+ if (path == '') {
+ throw new ArgumentError(
+ "Directory.createTemp called with an empty path. "
+ "To use the system temp directory, use Directory.systemTemp");
+ }
+ String fullPrefix;
+ if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
+ fullPrefix = "$path$prefix";
+ } else {
+ fullPrefix = "$path${Platform.pathSeparator}$prefix";
+ }
+ var result = _createTemp(fullPrefix);
+ if (result is OSError) {
+ throw new FileSystemException("Creation of temporary directory failed",
+ fullPrefix,
+ result);
+ }
+ return new Directory(result);
+ }
+
+ Future<Directory> _delete({bool recursive: false}) {
+ return _IOService._dispatch(_DIRECTORY_DELETE, [path, recursive])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(response, "Deletion failed");
+ }
+ return this;
+ });
+ }
+
+ void _deleteSync({bool recursive: false}) {
+ var result = _deleteNative(path, recursive);
+ if (result is OSError) {
+ throw new FileSystemException("Deletion failed", path, result);
+ }
+ }
+
+ Future<Directory> rename(String newPath) {
+ return _IOService._dispatch(_DIRECTORY_RENAME, [path, newPath])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(response, "Rename failed");
+ }
+ return new Directory(newPath);
+ });
+ }
+
+ Directory renameSync(String newPath) {
+ if (newPath is !String) {
+ throw new ArgumentError();
+ }
+ var result = _rename(path, newPath);
+ if (result is OSError) {
+ throw new FileSystemException("Rename failed", path, result);
+ }
+ return new Directory(newPath);
+ }
+
+ Stream<FileSystemEntity> list({bool recursive: false,
+ bool followLinks: true}) {
+ return new _AsyncDirectoryLister(
+ FileSystemEntity._ensureTrailingPathSeparators(path),
+ recursive,
+ followLinks).stream;
+ }
+
+ List<FileSystemEntity> listSync(
+ {bool recursive: false, bool followLinks: true}) {
+ if (recursive is! bool || followLinks is! bool) {
+ throw new ArgumentError();
+ }
+ var result = <FileSystemEntity>[];
+ _fillWithDirectoryListing(
+ result,
+ FileSystemEntity._ensureTrailingPathSeparators(path),
+ recursive,
+ followLinks);
+ return result;
+ }
+
+ String toString() => "Directory: '$path'";
+
+ bool _isErrorResponse(response) =>
+ response is List && response[0] != _SUCCESS_RESPONSE;
+
+ _exceptionOrErrorFromResponse(response, String message) {
+ assert(_isErrorResponse(response));
+ switch (response[_ERROR_RESPONSE_ERROR_TYPE]) {
+ case _ILLEGAL_ARGUMENT_RESPONSE:
+ return new ArgumentError();
+ case _OSERROR_RESPONSE:
+ var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
+ response[_OSERROR_RESPONSE_ERROR_CODE]);
+ return new FileSystemException(message, path, err);
+ default:
+ return new Exception("Unknown error");
+ }
+ }
+}
+
+abstract class _AsyncDirectoryListerOps {
+ external factory _AsyncDirectoryListerOps(int pointer);
+
+ int getPointer();
+}
+
+class _AsyncDirectoryLister {
+ static const int LIST_FILE = 0;
+ static const int LIST_DIRECTORY = 1;
+ static const int LIST_LINK = 2;
+ static const int LIST_ERROR = 3;
+ static const int LIST_DONE = 4;
+
+ static const int RESPONSE_TYPE = 0;
+ static const int RESPONSE_PATH = 1;
+ static const int RESPONSE_COMPLETE = 1;
+ static const int RESPONSE_ERROR = 2;
+
+ final String path;
+ final bool recursive;
+ final bool followLinks;
+
+ StreamController controller;
+ bool canceled = false;
+ bool nextRunning = false;
+ bool closed = false;
+ _AsyncDirectoryListerOps _ops;
+ Completer closeCompleter = new Completer();
+
+ _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) {
+ controller = new StreamController(onListen: onListen,
+ onResume: onResume,
+ onCancel: onCancel,
+ sync: true);
+ }
+
+ // Calling this function will increase the reference count on the native
+ // object that implements the async directory lister operations. It should
+ // only be called to pass the pointer to the IO Service, which will decrement
+ // the reference count when it is finished with it.
+ int _pointer() {
+ return (_ops == null) ? null : _ops.getPointer();
+ }
+
+ Stream get stream => controller.stream;
+
+ void onListen() {
+ _IOService._dispatch(_DIRECTORY_LIST_START, [path, recursive, followLinks])
+ .then((response) {
+ if (response is int) {
+ _ops = new _AsyncDirectoryListerOps(response);
+ next();
+ } else if (response is Error) {
+ controller.addError(response, response.stackTrace);
+ close();
+ } else {
+ error(response);
+ close();
+ }
+ });
+ }
+
+ void onResume() {
+ if (!nextRunning) {
+ next();
+ }
+ }
+
+ Future onCancel() {
+ canceled = true;
+ // If we are active, but not requesting, close.
+ if (!nextRunning) {
+ close();
+ }
+
+ return closeCompleter.future;
+ }
+
+ void next() {
+ if (canceled) {
+ close();
+ return;
+ }
+ if (controller.isPaused || nextRunning) {
+ return;
+ }
+ var pointer = _pointer();
+ if (pointer == null) {
+ return;
+ }
+ nextRunning = true;
+ _IOService._dispatch(_DIRECTORY_LIST_NEXT, [pointer]).then((result) {
+ nextRunning = false;
+ if (result is List) {
+ next();
+ assert(result.length % 2 == 0);
+ for (int i = 0; i < result.length; i++) {
+ assert(i % 2 == 0);
+ switch (result[i++]) {
+ case LIST_FILE:
+ controller.add(new File(result[i]));
+ break;
+ case LIST_DIRECTORY:
+ controller.add(new Directory(result[i]));
+ break;
+ case LIST_LINK:
+ controller.add(new Link(result[i]));
+ break;
+ case LIST_ERROR:
+ error(result[i]);
+ break;
+ case LIST_DONE:
+ canceled = true;
+ return;
+ }
+ }
+ } else {
+ controller.addError(new FileSystemException("Internal error"));
+ }
+ });
+ }
+
+ void _cleanup() {
+ controller.close();
+ closeCompleter.complete();
+ _ops = null;
+ }
+
+ void close() {
+ if (closed) {
+ return;
+ }
+ if (nextRunning) {
+ return;
+ }
+ closed = true;
+
+ var pointer = _pointer();
+ if (pointer == null) {
+ _cleanup();
+ } else {
+ _IOService._dispatch(_DIRECTORY_LIST_STOP, [pointer])
+ .whenComplete(_cleanup);
+ }
+ }
+
+ void error(message) {
+ var errorType =
+ message[RESPONSE_ERROR][_ERROR_RESPONSE_ERROR_TYPE];
+ if (errorType == _ILLEGAL_ARGUMENT_RESPONSE) {
+ controller.addError(new ArgumentError());
+ } else if (errorType == _OSERROR_RESPONSE) {
+ var responseError = message[RESPONSE_ERROR];
+ var err = new OSError(
+ responseError[_OSERROR_RESPONSE_MESSAGE],
+ responseError[_OSERROR_RESPONSE_ERROR_CODE]);
+ var errorPath = message[RESPONSE_PATH];
+ if (errorPath == null) errorPath = path;
+ controller.addError(
+ new FileSystemException("Directory listing failed",
+ errorPath,
+ err));
+ } else {
+ controller.addError(
+ new FileSystemException("Internal error"));
+ }
+ }
+}
« no previous file with comments | « tool/input_sdk/lib/io/directory.dart ('k') | tool/input_sdk/lib/io/eventhandler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698