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

Side by Side Diff: sdk/lib/io/file_system_entity.dart

Issue 19263003: Add FileSystemWatcher class to dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Simplify watching by removing FileSystemWatcher and adding FileSystemEntity.watch. Created 7 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.io; 5 part of dart.io;
6 6
7 class FileSystemEntityType { 7 class FileSystemEntityType {
8 static const FILE = const FileSystemEntityType._internal(0); 8 static const FILE = const FileSystemEntityType._internal(0);
9 static const DIRECTORY = const FileSystemEntityType._internal(1); 9 static const DIRECTORY = const FileSystemEntityType._internal(1);
10 static const LINK = const FileSystemEntityType._internal(2); 10 static const LINK = const FileSystemEntityType._internal(2);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 * Identical to [:FileStat.statSync(this.path):]. 310 * Identical to [:FileStat.statSync(this.path):].
311 * 311 *
312 * Returns a [FileStat] object containing the data returned by stat(). 312 * Returns a [FileStat] object containing the data returned by stat().
313 * 313 *
314 * If the call fails, returns a [FileStat] object with .type set to 314 * If the call fails, returns a [FileStat] object with .type set to
315 * FileSystemEntityType.NOT_FOUND and the other fields invalid. 315 * FileSystemEntityType.NOT_FOUND and the other fields invalid.
316 */ 316 */
317 FileStat statSync(); 317 FileStat statSync();
318 318
319 319
320
321 Stream<FileSystemEvent> watch({int events: FileSystemEvent.ALL_EVENTS,
322 bool recursive: false})
323 => new _FileSystemWatcher(path, events, recursive).stream;
324
325
320 /** 326 /**
321 * Finds the type of file system object that a path points to. Returns 327 * Finds the type of file system object that a path points to. Returns
322 * a [:Future<FileSystemEntityType>:] that completes with the result. 328 * a [:Future<FileSystemEntityType>:] that completes with the result.
323 * 329 *
324 * [FileSystemEntityType] has the constant instances FILE, DIRECTORY, 330 * [FileSystemEntityType] has the constant instances FILE, DIRECTORY,
325 * LINK, and NOT_FOUND. [type] will return LINK only if the optional 331 * LINK, and NOT_FOUND. [type] will return LINK only if the optional
326 * named argument [followLinks] is false, and [path] points to a link. 332 * named argument [followLinks] is false, and [path] points to a link.
327 * If the path does not point to a file system object, or any other error 333 * If the path does not point to a file system object, or any other error
328 * occurs in looking up the path, NOT_FOUND is returned. The only 334 * occurs in looking up the path, NOT_FOUND is returned. The only
329 * error or exception that may be put on the returned future is ArgumentError, 335 * error or exception that may be put on the returned future is ArgumentError,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 (_getTypeSync(path, true) == FileSystemEntityType.FILE._type); 389 (_getTypeSync(path, true) == FileSystemEntityType.FILE._type);
384 390
385 /** 391 /**
386 * Synchronously checks if typeSync(path) returns 392 * Synchronously checks if typeSync(path) returns
387 * FileSystemEntityType.DIRECTORY. 393 * FileSystemEntityType.DIRECTORY.
388 */ 394 */
389 static bool isDirectorySync(String path) => 395 static bool isDirectorySync(String path) =>
390 (_getTypeSync(path, true) == FileSystemEntityType.DIRECTORY._type); 396 (_getTypeSync(path, true) == FileSystemEntityType.DIRECTORY._type);
391 397
392 398
393 static _throwIfError(Object result, String msg) { 399 static _throwIfError(Object result, String msg, [String path]) {
394 if (result is OSError) { 400 if (result is OSError) {
395 throw new FileException(msg, result); 401 throw new FileException(msg, result, path);
396 } else if (result is ArgumentError) { 402 } else if (result is ArgumentError) {
397 throw result; 403 throw result;
398 } 404 }
399 } 405 }
400 } 406 }
407
408
409 /**
410 * Base event class emitted by FileSystemWatcher.
411 */
412 class FileSystemEvent {
413 static const int CREATE_EVENT = 1 << 0;
Søren Gjesse 2013/08/26 07:51:55 How about removing the _EVENT prefix?
Anders Johnsen 2013/09/03 11:36:23 Done.
414 static const int MODIFY_EVENT = 1 << 1;
415 static const int DELETE_EVENT = 1 << 2;
416 static const int MOVE_EVENT = 1 << 3;
Søren Gjesse 2013/08/26 07:51:55 Two spaces after =.
Anders Johnsen 2013/09/03 11:36:23 Done.
417 static const int ALL_EVENTS =
418 CREATE_EVENT | MODIFY_EVENT | DELETE_EVENT | MOVE_EVENT;
419
420 static const int _MODIFY_ATTRIBUTES_EVENT = 1 << 4;
Søren Gjesse 2013/08/26 07:51:55 Add empty line.
Anders Johnsen 2013/09/03 11:36:23 Done.
421 /**
422 * The type of event. See [FileSystemEvent] for a list of events.
423 */
424 final int type;
425
426 /**
427 * The path that triggered the event.
Søren Gjesse 2013/08/26 07:51:55 Some doc on whether this is absolute or maybe ŕela
Anders Johnsen 2013/09/03 11:36:23 Done.
428 */
429 final String path;
430
431 FileSystemEvent._(this.type, this.path);
432 }
433
434
435 /**
436 * File system event for newly created file system objects.
437 */
438 class FileSystemCreateEvent extends FileSystemEvent {
439 FileSystemCreateEvent._(path)
440 : super._(FileSystemEvent.CREATE_EVENT, path);
441
442 String toString() => "FileSystemCreateEvent('$path')";
443 }
444
445
446 /**
447 * File system event for modifications of file system objects.
448 */
449 class FileSystemModifyEvent extends FileSystemEvent {
450 /**
451 * If the content was changed and not only the attributes, [contentChanged]
452 * is `true`.
453 */
454 final bool contentChanged;
455
456 FileSystemModifyEvent._(path, this.contentChanged)
457 : super._(FileSystemEvent.MODIFY_EVENT, path);
458
459 String toString() =>
460 "FileSystemModifyEvent('$path', contentChanged=$contentChanged)";
461 }
462
463
464 /**
465 * File system event for deletion of file system objects.
466 */
467 class FileSystemDeleteEvent extends FileSystemEvent {
468 FileSystemDeleteEvent._(path)
469 : super._(FileSystemEvent.DELETE_EVENT, path);
470
471 String toString() => "FileSystemDeleteEvent('$path')";
472 }
473
474
475 /**
476 * File system event for moving of file system objects.
477 */
478 class FileSystemMoveEvent extends FileSystemEvent {
479 /**
480 * If the underlaying implementation is able to identify the destination of
481 * the moved file, [destination] will be set. Otherwise, it will be `null`.
482 */
483 final String destination;
484
485 FileSystemMoveEvent._(path, this.destination)
486 : super._(FileSystemEvent.MOVE_EVENT, path);
487
488 String toString() {
489 var buffer = new StringBuffer();
490 buffer.write("FileSystemMoveEvent('$path'");
491 if (destination != null) buffer.write(", '$destination'");
492 buffer.write(')');
493 return buffer.toString();
494 }
495 }
496
497
498 class _FileSystemWatcher {
499 final String _path;
500 final int _events;
501
502 StreamController _controller;
503 int _id;
504 _RawSocket _socket;
505
506 _FileSystemWatcher(this._path, this._events, bool recursive) {
507
508 _controller = new StreamController(
509 onListen: () {
510 print("in listen");
Søren Gjesse 2013/08/26 07:51:55 Debug print.
Anders Johnsen 2013/09/03 11:36:23 Done.
511 _id = _watchPath(_path, _events, recursive);
512 FileSystemEntity._throwIfError(_id, "Failed to watch path", _path);
513 _listen();
514 },
515 onCancel: () {
516 if (_socket != null) {
517 _socket.close();
518 }
519 });
520 }
521
522 void _stop() {
523 _controller.close();
524 _unwatchPath(_id);
525 }
526
527 void _listen() {
Søren Gjesse 2013/08/26 07:51:55 I think we should do _NativeSocket setup the same
Anders Johnsen 2013/09/03 11:36:23 I've tried to simplify as much as possible.
528 int socketId = _getSocketId(_id);
529 var native = new _NativeSocket.normal();
530 native.isClosedWrite = true;
531 native.setSocketId(socketId);
532 _socket = new _RawSocket(native);
533 print(socketId);
Søren Gjesse 2013/08/26 07:51:55 Debug print.
Anders Johnsen 2013/09/03 11:36:23 Done.
534 _socket.expand((event) {
535 print(event);
536 var events = [];
537 var pair = {};
538 if (event == RawSocketEvent.READ) {
539 String getPath(event) {
540 var path = _path;
541 if (event[2] != null) {
542 path += Platform.pathSeparator;
543 path += event[2];
544 }
545 return path;
546 }
547 while (_socket.available() > 0) {
548 for (var event in _readEvents(_id)) {
549 print(event);
Søren Gjesse 2013/08/26 07:51:55 Debug print.
Anders Johnsen 2013/09/03 11:36:23 Done.
550 var path = getPath(event);
551 if ((event[0] & FileSystemEvent.CREATE_EVENT) != 0) {
552 events.add(new FileSystemCreateEvent._(path));
553 }
554 if ((event[0] & FileSystemEvent.MODIFY_EVENT) != 0) {
555 events.add(new FileSystemModifyEvent._(path, true));
556 }
557 if ((event[0] & FileSystemEvent._MODIFY_ATTRIBUTES_EVENT) != 0) {
558 events.add(new FileSystemModifyEvent._(path, false));
559 }
560 if ((event[0] & FileSystemEvent.MOVE_EVENT) != 0) {
561 int link = event[3];
562 if (link > 0) {
563 if (pair.containsKey(link)) {
564 events.add(
565 new FileSystemMoveEvent._(getPath(pair[link]), path));
566 pair.remove(link);
567 } else {
568 pair[link] = event;
569 }
570 } else {
571 events.add(new FileSystemMoveEvent._(path, null));
572 }
573 }
574 if ((event[0] & FileSystemEvent.DELETE_EVENT) != 0) {
575 events.add(new FileSystemDeleteEvent._(path));
576 }
577 }
578 }
579 for (var event in pair.values) {
580 events.add(new FileSystemMoveEvent._(getPath(event), null));
581 }
582 } else if (event == RawSocketEvent.CLOSED) {
583 _stop();
584 } else if (event == RawSocketEvent.READ_CLOSED) {
585 } else {
586 assert(false);
587 }
588 print(events);
589 return events;
590 }).where((event) => (event.type & _events) != 0).listen(_controller.add);
591 }
592
593 Stream<FileSystemEvent> get stream => _controller.stream;
594
595 external _watchPath(String path, int events, bool recursive);
596 external void _unwatchPath(int id);
597 external int _getSocketId(int id);
598 external List _readEvents(int id);
599 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698