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 |