7f9dfb1890
BUG= R=sgjesse@google.com Review URL: https://codereview.chromium.org//46183007 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@29536 260f80e4-7a28-3924-810f-c04153c831b5
183 lines
6.6 KiB
Dart
183 lines
6.6 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.
|
|
|
|
patch class _File {
|
|
/* patch */ static _exists(String path) native "File_Exists";
|
|
/* patch */ static _create(String path) native "File_Create";
|
|
/* patch */ static _createLink(String path, String target)
|
|
native "File_CreateLink";
|
|
/* patch */ static _linkTarget(String path) native "File_LinkTarget";
|
|
/* patch */ static _deleteNative(String path) native "File_Delete";
|
|
/* patch */ static _deleteLinkNative(String path) native "File_DeleteLink";
|
|
/* patch */ static _rename(String oldPath, String newPath)
|
|
native "File_Rename";
|
|
/* patch */ static _renameLink(String oldPath, String newPath)
|
|
native "File_RenameLink";
|
|
/* patch */ static _lengthFromPath(String path) native "File_LengthFromPath";
|
|
/* patch */ static _lastModified(String path) native "File_LastModified";
|
|
/* patch */ static _open(String path, int mode) native "File_Open";
|
|
/* patch */ static int _openStdio(int fd) native "File_OpenStdio";
|
|
}
|
|
|
|
patch class _RandomAccessFile {
|
|
/* patch */ static int _close(int id) native "File_Close";
|
|
/* patch */ static _readByte(int id) native "File_ReadByte";
|
|
/* patch */ static _read(int id, int bytes) native "File_Read";
|
|
/* patch */ static _readInto(int id, List<int> buffer, int start, int end)
|
|
native "File_ReadInto";
|
|
/* patch */ static _writeByte(int id, int value) native "File_WriteByte";
|
|
/* patch */ static _writeFrom(int id, List<int> buffer, int start, int end)
|
|
native "File_WriteFrom";
|
|
/* patch */ static _position(int id) native "File_Position";
|
|
/* patch */ static _setPosition(int id, int position)
|
|
native "File_SetPosition";
|
|
/* patch */ static _truncate(int id, int length) native "File_Truncate";
|
|
/* patch */ static _length(int id) native "File_Length";
|
|
/* patch */ static _flush(int id) native "File_Flush";
|
|
}
|
|
|
|
patch class _FileSystemWatcher {
|
|
/* patch */ factory _FileSystemWatcher(
|
|
String path, int events, bool recursive)
|
|
=> new _FileSystemWatcherImpl(path, events, recursive);
|
|
|
|
/* patch */ static bool get isSupported => _FileSystemWatcherImpl.isSupported;
|
|
}
|
|
|
|
class _FileSystemWatcherImpl
|
|
extends NativeFieldWrapperClass1
|
|
implements _FileSystemWatcher {
|
|
final String _path;
|
|
final int _events;
|
|
final bool _recursive;
|
|
|
|
StreamController _controller;
|
|
StreamSubscription _subscription;
|
|
|
|
_FileSystemWatcherImpl(this._path, this._events, this._recursive) {
|
|
if (!isSupported) {
|
|
throw new FileSystemException(
|
|
"File system watching is not supported on this system",
|
|
_path);
|
|
}
|
|
_controller = new StreamController.broadcast(onListen: _listen,
|
|
onCancel: _cancel);
|
|
}
|
|
|
|
void _listen() {
|
|
int socketId;
|
|
try {
|
|
socketId = _watchPath(_path, _events, identical(true, _recursive));
|
|
} catch (e) {
|
|
_controller.addError(new FileSystemException(
|
|
"Failed to watch path", _path, e));
|
|
_controller.close();
|
|
return;
|
|
}
|
|
var socket = new _RawSocket(new _NativeSocket.watch(socketId));
|
|
_subscription = socket.expand((event) {
|
|
bool stop = false;
|
|
var events = [];
|
|
var pair = {};
|
|
if (event == RawSocketEvent.READ) {
|
|
String getPath(event) {
|
|
var path = _path;
|
|
if (event[2] != null && event[2].isNotEmpty) {
|
|
path += Platform.pathSeparator;
|
|
path += event[2];
|
|
}
|
|
return path;
|
|
}
|
|
bool getIsDir(event) {
|
|
if (Platform.isWindows) {
|
|
// Windows does not get 'isDir' as part of the event.
|
|
return FileSystemEntity.isDirectorySync(getPath(event));
|
|
}
|
|
return (event[0] & FileSystemEvent._IS_DIR) != 0;
|
|
}
|
|
void add(event) {
|
|
if ((event.type & _events) == 0) return;
|
|
events.add(event);
|
|
}
|
|
void rewriteMove(event, isDir) {
|
|
if (event[3]) {
|
|
add(new FileSystemCreateEvent._(getPath(event), isDir));
|
|
} else {
|
|
add(new FileSystemDeleteEvent._(getPath(event), isDir));
|
|
}
|
|
}
|
|
while (socket.available() > 0) {
|
|
for (var event in _readEvents()) {
|
|
if (event == null) continue;
|
|
bool isDir = getIsDir(event);
|
|
var path = getPath(event);
|
|
if ((event[0] & FileSystemEvent.CREATE) != 0) {
|
|
add(new FileSystemCreateEvent._(path, isDir));
|
|
}
|
|
if ((event[0] & FileSystemEvent.MODIFY) != 0) {
|
|
add(new FileSystemModifyEvent._(path, isDir, true));
|
|
}
|
|
if ((event[0] & FileSystemEvent._MODIFY_ATTRIBUTES) != 0) {
|
|
add(new FileSystemModifyEvent._(path, isDir, false));
|
|
}
|
|
if ((event[0] & FileSystemEvent.MOVE) != 0) {
|
|
int link = event[1];
|
|
if (link > 0) {
|
|
if (pair.containsKey(link)) {
|
|
events.add(new FileSystemMoveEvent._(
|
|
getPath(pair[link]), isDir, path));
|
|
pair.remove(link);
|
|
} else {
|
|
pair[link] = event;
|
|
}
|
|
} else {
|
|
rewriteMove(event, isDir);
|
|
}
|
|
}
|
|
if ((event[0] & FileSystemEvent.DELETE) != 0) {
|
|
add(new FileSystemDeleteEvent._(path, isDir));
|
|
}
|
|
if ((event[0] & FileSystemEvent._DELETE_SELF) != 0) {
|
|
add(new FileSystemDeleteEvent._(path, isDir));
|
|
stop = true;
|
|
}
|
|
}
|
|
}
|
|
for (var event in pair.values) {
|
|
rewriteMove(event, getIsDir(event));
|
|
}
|
|
} else if (event == RawSocketEvent.CLOSED) {
|
|
} else if (event == RawSocketEvent.READ_CLOSED) {
|
|
} else {
|
|
assert(false);
|
|
}
|
|
if (stop) socket.close();
|
|
return events;
|
|
})
|
|
.listen(_controller.add, onDone: _cancel);
|
|
}
|
|
|
|
void _cancel() {
|
|
if (_subscription != null) {
|
|
_unwatchPath();
|
|
_subscription.cancel();
|
|
_subscription = null;
|
|
}
|
|
_controller.close();
|
|
}
|
|
|
|
Stream<FileSystemEvent> get stream => _controller.stream;
|
|
|
|
static bool get isSupported native "FileSystemWatcher_IsSupported";
|
|
|
|
int _watchPath(String path, int events, bool recursive)
|
|
native "FileSystemWatcher_WatchPath";
|
|
void _unwatchPath() native "FileSystemWatcher_UnwatchPath";
|
|
List _readEvents() native "FileSystemWatcher_ReadEvents";
|
|
}
|
|
|
|
Uint8List _makeUint8ListView(Uint8List source, int offsetInBytes, int length) {
|
|
return new Uint8List.view(source.buffer, offsetInBytes, length);
|
|
}
|