| OLD | NEW |
| 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 library watcher.directory_watcher.polling; | 5 library watcher.directory_watcher.polling; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:crypto/crypto.dart'; | 10 import 'package:crypto/crypto.dart'; |
| 11 import 'package:stack_trace/stack_trace.dart'; |
| 11 | 12 |
| 12 import '../async_queue.dart'; | 13 import '../async_queue.dart'; |
| 13 import '../stat.dart'; | 14 import '../stat.dart'; |
| 14 import '../utils.dart'; | 15 import '../utils.dart'; |
| 15 import '../watch_event.dart'; | 16 import '../watch_event.dart'; |
| 16 import 'resubscribable.dart'; | 17 import 'resubscribable.dart'; |
| 17 | 18 |
| 18 /// Periodically polls a directory for changes. | 19 /// Periodically polls a directory for changes. |
| 19 class PollingDirectoryWatcher extends ResubscribableDirectoryWatcher { | 20 class PollingDirectoryWatcher extends ResubscribableDirectoryWatcher { |
| 20 /// Creates a new polling watcher monitoring [directory]. | 21 /// Creates a new polling watcher monitoring [directory]. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 _polledFiles.clear(); | 99 _polledFiles.clear(); |
| 99 | 100 |
| 100 endListing() { | 101 endListing() { |
| 101 assert(!_events.isClosed); | 102 assert(!_events.isClosed); |
| 102 _listSubscription = null; | 103 _listSubscription = null; |
| 103 | 104 |
| 104 // Null tells the queue consumer that we're done listing. | 105 // Null tells the queue consumer that we're done listing. |
| 105 _filesToProcess.add(null); | 106 _filesToProcess.add(null); |
| 106 } | 107 } |
| 107 | 108 |
| 108 var stream = new Directory(directory).list(recursive: true); | 109 var stream = Chain.track(new Directory(directory).list(recursive: true)); |
| 109 _listSubscription = stream.listen((entity) { | 110 _listSubscription = stream.listen((entity) { |
| 110 assert(!_events.isClosed); | 111 assert(!_events.isClosed); |
| 111 | 112 |
| 112 if (entity is! File) return; | 113 if (entity is! File) return; |
| 113 _filesToProcess.add(entity.path); | 114 _filesToProcess.add(entity.path); |
| 114 }, onError: (error, stackTrace) { | 115 }, onError: (error, stackTrace) { |
| 115 if (!isDirectoryNotFoundException(error)) { | 116 if (!isDirectoryNotFoundException(error)) { |
| 116 // It's some unknown error. Pipe it over to the event stream so the | 117 // It's some unknown error. Pipe it over to the event stream so the |
| 117 // user can see it. | 118 // user can see it. |
| 118 _events.addError(error, stackTrace); | 119 _events.addError(error, stackTrace); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 | 179 |
| 179 // Wait and then poll again. | 180 // Wait and then poll again. |
| 180 return new Future.delayed(_pollingDelay).then((_) { | 181 return new Future.delayed(_pollingDelay).then((_) { |
| 181 if (_events.isClosed) return; | 182 if (_events.isClosed) return; |
| 182 _poll(); | 183 _poll(); |
| 183 }); | 184 }); |
| 184 } | 185 } |
| 185 | 186 |
| 186 /// Calculates the SHA-1 hash of the file at [path]. | 187 /// Calculates the SHA-1 hash of the file at [path]. |
| 187 Future<List<int>> _hashFile(String path) { | 188 Future<List<int>> _hashFile(String path) { |
| 188 return new File(path).readAsBytes().then((bytes) { | 189 return Chain.track(new File(path).readAsBytes()).then((bytes) { |
| 189 var sha1 = new SHA1(); | 190 var sha1 = new SHA1(); |
| 190 sha1.add(bytes); | 191 sha1.add(bytes); |
| 191 return sha1.close(); | 192 return sha1.close(); |
| 192 }); | 193 }); |
| 193 } | 194 } |
| 194 | 195 |
| 195 /// Returns `true` if [a] and [b] are the same hash value, i.e. the same | 196 /// Returns `true` if [a] and [b] are the same hash value, i.e. the same |
| 196 /// series of byte values. | 197 /// series of byte values. |
| 197 bool _sameHash(List<int> a, List<int> b) { | 198 bool _sameHash(List<int> a, List<int> b) { |
| 198 // Hashes should always be the same size. | 199 // Hashes should always be the same size. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 209 class _FileStatus { | 210 class _FileStatus { |
| 210 /// The last time the file was modified. | 211 /// The last time the file was modified. |
| 211 DateTime modified; | 212 DateTime modified; |
| 212 | 213 |
| 213 /// The SHA-1 hash of the contents of the file. | 214 /// The SHA-1 hash of the contents of the file. |
| 214 List<int> hash; | 215 List<int> hash; |
| 215 | 216 |
| 216 _FileStatus(this.modified, this.hash); | 217 _FileStatus(this.modified, this.hash); |
| 217 } | 218 } |
| 218 | 219 |
| OLD | NEW |