Files
sdk/runtime/bin/directory_impl.dart
T
regis@google.com b86a40f48f Fix type checking of void type.
Fix library and tests accordingly.
Add new test.
Disable new test for dart2js.
Disable some now failing co19 tests (new issue 158 filed).
Hide internal VM String types from user (not complete).
Review URL: https://chromiumcodereview.appspot.com//10787021

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@9681 260f80e4-7a28-3924-810f-c04153c831b5
2012-07-16 21:34:07 +00:00

295 lines
8.8 KiB
Dart

// 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.
class _Directory implements Directory {
static final CREATE_REQUEST = 0;
static final DELETE_REQUEST = 1;
static final EXISTS_REQUEST = 2;
static final CREATE_TEMP_REQUEST = 3;
static final LIST_REQUEST = 4;
static final RENAME_REQUEST = 5;
static final SUCCESS_RESPONSE = 0;
static final ILLEGAL_ARGUMENT_RESPONSE = 1;
static final OSERROR_RESPONSE = 2;
_Directory(String this._path);
_Directory.fromPath(Path path) : this(path.toNativePath());
_Directory.current() : this(_current());
static String _current() native "Directory_Current";
static _createTemp(String template) native "Directory_CreateTemp";
static int _exists(String path) native "Directory_Exists";
static _create(String path) native "Directory_Create";
static _delete(String path, bool recursive) native "Directory_Delete";
static _rename(String path, String newPath) native "Directory_Rename";
static SendPort _newServicePort() native "Directory_NewServicePort";
Future<bool> exists() {
_ensureDirectoryService();
List request = new List(2);
request[0] = EXISTS_REQUEST;
request[1] = _path;
return _directoryService.call(request).transform((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Exists failed");
}
return response == 1;
});
}
bool existsSync() {
if (_path is !String) {
throw new IllegalArgumentException();
}
var result = _exists(_path);
if (result is OSError) {
throw new DirectoryIOException("Exists failed", _path, result);
}
return (result == 1);
}
Future<Directory> create() {
_ensureDirectoryService();
List request = new List(2);
request[0] = CREATE_REQUEST;
request[1] = _path;
return _directoryService.call(request).transform((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Creation failed");
}
return this;
});
}
void createSync() {
if (_path is !String) {
throw new IllegalArgumentException();
}
var result = _create(_path);
if (result is OSError) {
throw new DirectoryIOException("Creation failed", _path, result);
}
}
Future<Directory> createTemp() {
_ensureDirectoryService();
List request = new List(2);
request[0] = CREATE_TEMP_REQUEST;
request[1] = _path;
return _directoryService.call(request).transform((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Creation of temporary directory failed");
}
return new Directory(response);
});
}
Directory createTempSync() {
if (_path is !String) {
throw new IllegalArgumentException();
}
var result = _createTemp(path);
if (result is OSError) {
throw new DirectoryIOException("Creation of temporary directory failed",
_path,
result);
}
return new Directory(result);
}
Future<Directory> _deleteHelper(bool recursive, String errorMsg) {
_ensureDirectoryService();
List request = new List(3);
request[0] = DELETE_REQUEST;
request[1] = _path;
request[2] = recursive;
return _directoryService.call(request).transform((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, errorMsg);
}
return this;
});
return completer.future;
}
Future<Directory> delete() {
return _deleteHelper(false, "Deletion failed");
}
void deleteSync() {
if (_path is !String) {
throw new IllegalArgumentException();
}
var result = _delete(_path, false);
if (result is OSError) {
throw new DirectoryIOException("Deletion failed", _path, result);
}
}
Future<Directory> deleteRecursively() {
return _deleteHelper(true, "Deletion failed");
}
void deleteRecursivelySync() {
if (_path is !String) {
throw new IllegalArgumentException();
}
var result = _delete(_path, true);
if (result is OSError) {
throw new DirectoryIOException("Deletion failed", _path, result);
}
}
Future<Directory> rename(String newPath) {
_ensureDirectoryService();
List request = new List(3);
request[0] = RENAME_REQUEST;
request[1] = _path;
request[2] = newPath;
return _directoryService.call(request).transform((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Rename failed");
}
return new Directory(newPath);
});
}
Directory renameSync(String newPath) {
if (_path is !String || newPath is !String) {
throw new IllegalArgumentException();
}
var result = _rename(_path, newPath);
if (result is OSError) {
throw new DirectoryIOException("Rename failed", _path, result);
}
return new Directory(newPath);
}
DirectoryLister list([bool recursive = false]) {
return new _DirectoryLister(_path, recursive);
}
String get path() { return _path; }
bool _isErrorResponse(response) {
return response is List && response[0] != _FileUtils.SUCCESS_RESPONSE;
}
Exception _exceptionFromResponse(response, String message) {
assert(_isErrorResponse(response));
switch (response[_FileUtils.ERROR_RESPONSE_ERROR_TYPE]) {
case _FileUtils.ILLEGAL_ARGUMENT_RESPONSE:
return new IllegalArgumentException();
case _FileUtils.OSERROR_RESPONSE:
var err = new OSError(response[_FileUtils.OSERROR_RESPONSE_MESSAGE],
response[_FileUtils.OSERROR_RESPONSE_ERROR_CODE]);
return new DirectoryIOException(message, _path, err);
default:
return new Exception("Unknown error");
}
}
void _ensureDirectoryService() {
if (_directoryService == null) {
_directoryService = _newServicePort();
}
}
final String _path;
SendPort _directoryService;
}
class _DirectoryLister implements DirectoryLister {
_DirectoryLister(String path, bool recursive) {
final int LIST_DIRECTORY = 0;
final int LIST_FILE = 1;
final int LIST_ERROR = 2;
final int LIST_DONE = 3;
final int RESPONSE_TYPE = 0;
final int RESPONSE_PATH = 1;
final int RESPONSE_COMPLETE = 1;
final int RESPONSE_ERROR = 2;
List request = new List(3);
request[0] = _Directory.LIST_REQUEST;
request[1] = path;
request[2] = recursive;
ReceivePort responsePort = new ReceivePort();
// Use a separate directory service port for each listing as
// listing operations on the same directory can run in parallel.
_Directory._newServicePort().send(request, responsePort.toSendPort());
responsePort.receive((message, replyTo) {
if (message is !List || message[RESPONSE_TYPE] is !int) {
responsePort.close();
_reportError(new DirectoryIOException("Internal error"));
return;
}
switch (message[RESPONSE_TYPE]) {
case LIST_DIRECTORY:
if (_onDir != null) _onDir(message[RESPONSE_PATH]);
break;
case LIST_FILE:
if (_onFile != null) _onFile(message[RESPONSE_PATH]);
break;
case LIST_ERROR:
var errorType =
message[RESPONSE_ERROR][_FileUtils.ERROR_RESPONSE_ERROR_TYPE];
if (errorType == _FileUtils.ILLEGAL_ARGUMENT_RESPONSE) {
_reportError(new IllegalArgumentException());
} else if (errorType == _FileUtils.OSERROR_RESPONSE) {
var responseError = message[RESPONSE_ERROR];
var err = new OSError(
responseError[_FileUtils.OSERROR_RESPONSE_MESSAGE],
responseError[_FileUtils.OSERROR_RESPONSE_ERROR_CODE]);
var errorPath = message[RESPONSE_PATH];
if (errorPath == null) errorPath = path;
_reportError(new DirectoryIOException("Directory listing failed",
errorPath,
err));
} else {
_reportError(new DirectoryIOException("Internal error"));
}
break;
case LIST_DONE:
responsePort.close();
if (_onDone != null) _onDone(message[RESPONSE_COMPLETE]);
break;
}
});
}
void set onDir(void onDir(String dir)) {
_onDir = onDir;
}
void set onFile(void onFile(String file)) {
_onFile = onFile;
}
void set onDone(void onDone(bool completed)) {
_onDone = onDone;
}
void set onError(void onError(e)) {
_onError = onError;
}
void _reportError(e) {
if (_onError != null) {
_onError(e);
} else {
throw e;
}
}
Function _onDir;
Function _onFile;
Function _onDone;
Function _onError;
}