| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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.async; | 5 part of dart.async; |
| 6 | 6 |
| 7 /** Utility function to create an [AsyncError] if [error] isn't one already. */ |
| 8 AsyncError _asyncError(Object error, Object stackTrace, [AsyncError cause]) { |
| 9 if (error is AsyncError) return error; |
| 10 if (cause == null) return new AsyncError(error, stackTrace); |
| 11 return new AsyncError.withCause(error, stackTrace, cause); |
| 12 } |
| 13 |
| 14 /** Runs user code and takes actions depending on success or failure. */ |
| 15 _runUserCode(userCode(), onSuccess(value), onError(AsyncError error), |
| 16 { AsyncError cause }) { |
| 17 var result; |
| 18 try { |
| 19 result = userCode(); |
| 20 } on AsyncError catch (e) { |
| 21 return onError(e); |
| 22 } catch (e, s) { |
| 23 if (cause == null) { |
| 24 onError(new AsyncError(e, s)); |
| 25 } else { |
| 26 onError(new AsyncError.withCause(e, s, cause)); |
| 27 } |
| 28 } |
| 29 onSuccess(result); |
| 30 } |
| 31 |
| 32 /** Helper function to make an onError argument to [_runUserCode]. */ |
| 33 _cancelAndError(StreamSubscription subscription, _FutureImpl future) => |
| 34 (AsyncError error) { |
| 35 subscription.cancel(); |
| 36 future._setError(error); |
| 37 }; |
| 38 |
| 39 |
| 7 /** | 40 /** |
| 8 * A wrapper around a stream that allows independent subscribers. | 41 * A wrapper around a stream that allows independent subscribers. |
| 9 * | 42 * |
| 10 * By default [this] subscribes to [_source] and forwards all events to its own | 43 * By default [this] subscribes to [_source] and forwards all events to its own |
| 11 * subscribers. It does not subscribe until there is a subscriber, and | 44 * subscribers. It does not subscribe until there is a subscriber, and |
| 12 * unsubscribes again when there are no subscribers left. | 45 * unsubscribes again when there are no subscribers left. |
| 13 * | 46 * |
| 14 * The events are passed through the [_handleData], [_handleError] and | 47 * The events are passed through the [_handleData], [_handleError] and |
| 15 * [_handleDone] methods. Subclasses are supposed to add handling of some of | 48 * [_handleDone] methods. Subclasses are supposed to add handling of some of |
| 16 * the events by overriding these methods. | 49 * the events by overriding these methods. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 | 101 |
| 69 void _handleDone() { | 102 void _handleDone() { |
| 70 _close(); | 103 _close(); |
| 71 } | 104 } |
| 72 } | 105 } |
| 73 | 106 |
| 74 | 107 |
| 75 abstract class _ForwardingTransformer<S, T> extends _ForwardingMultiStream<S, T> | 108 abstract class _ForwardingTransformer<S, T> extends _ForwardingMultiStream<S, T> |
| 76 implements StreamTransformer<S, T> { | 109 implements StreamTransformer<S, T> { |
| 77 Stream<T> bind(Stream<S> source) { | 110 Stream<T> bind(Stream<S> source) { |
| 78 assert(_source == null); | 111 if (_source != null) throw new StateError("Already bound to source."); |
| 79 _source = source; | 112 _source = source; |
| 80 if (_hasSubscribers) { | 113 if (_hasSubscribers) { |
| 81 _subscribeToSource(); | 114 _subscribeToSource(); |
| 82 } | 115 } |
| 83 return this; | 116 return this; |
| 84 } | 117 } |
| 85 } | 118 } |
| 86 | 119 |
| 87 // ------------------------------------------------------------------- | 120 // ------------------------------------------------------------------- |
| 88 // Stream transformers used by the default Stream implementation. | 121 // Stream transformers used by the default Stream implementation. |
| 89 // ------------------------------------------------------------------- | 122 // ------------------------------------------------------------------- |
| 90 | 123 |
| 91 typedef bool _Predicate<T>(T value); | 124 typedef bool _Predicate<T>(T value); |
| 92 | 125 |
| 93 class WhereStream<T> extends _ForwardingTransformer<T, T> { | 126 class WhereStream<T> extends _ForwardingTransformer<T, T> { |
| 94 final _Predicate<T> _test; | 127 final _Predicate<T> _test; |
| 95 | 128 |
| 96 WhereStream(bool test(T value)) | 129 WhereStream(bool test(T value)) |
| 97 : this._test = test; | 130 : this._test = test; |
| 98 | 131 |
| 99 void _handleData(T inputEvent) { | 132 void _handleData(T inputEvent) { |
| 100 bool satisfies; | 133 bool satisfies; |
| 101 try { | 134 try { |
| 102 satisfies = _test(inputEvent); | 135 satisfies = _test(inputEvent); |
| 103 } catch (e, s) { | 136 } catch (e, s) { |
| 104 _signalError(new AsyncError(e, s)); | 137 _signalError(_asyncError(e, s)); |
| 105 return; | 138 return; |
| 106 } | 139 } |
| 107 if (satisfies) { | 140 if (satisfies) { |
| 108 _add(inputEvent); | 141 _add(inputEvent); |
| 109 } | 142 } |
| 110 } | 143 } |
| 111 } | 144 } |
| 112 | 145 |
| 113 | 146 |
| 114 typedef T _Transformation<S, T>(S value); | 147 typedef T _Transformation<S, T>(S value); |
| 115 | 148 |
| 116 /** | 149 /** |
| 117 * A stream pipe that converts data events before passing them on. | 150 * A stream pipe that converts data events before passing them on. |
| 118 */ | 151 */ |
| 119 class MapStream<S, T> extends _ForwardingTransformer<S, T> { | 152 class MapStream<S, T> extends _ForwardingTransformer<S, T> { |
| 120 final _Transformation _transform; | 153 final _Transformation _transform; |
| 121 | 154 |
| 122 MapStream(T transform(S event)) | 155 MapStream(T transform(S event)) |
| 123 : this._transform = transform; | 156 : this._transform = transform; |
| 124 | 157 |
| 125 void _handleData(S inputEvent) { | 158 void _handleData(S inputEvent) { |
| 126 T outputEvent; | 159 T outputEvent; |
| 127 try { | 160 try { |
| 128 outputEvent = _transform(inputEvent); | 161 outputEvent = _transform(inputEvent); |
| 129 } catch (e, s) { | 162 } catch (e, s) { |
| 130 _signalError(new AsyncError(e, s)); | 163 _signalError(_asyncError(e, s)); |
| 131 return; | 164 return; |
| 132 } | 165 } |
| 133 _add(outputEvent); | 166 _add(outputEvent); |
| 134 } | 167 } |
| 135 } | 168 } |
| 136 | 169 |
| 137 /** | 170 /** |
| 138 * A stream pipe that converts data events before passing them on. | 171 * A stream pipe that converts data events before passing them on. |
| 139 */ | 172 */ |
| 140 class ExpandStream<S, T> extends _ForwardingTransformer<S, T> { | 173 class ExpandStream<S, T> extends _ForwardingTransformer<S, T> { |
| 141 final _Transformation<S, Iterable<T>> _expand; | 174 final _Transformation<S, Iterable<T>> _expand; |
| 142 | 175 |
| 143 ExpandStream(Iterable<T> expand(S event)) | 176 ExpandStream(Iterable<T> expand(S event)) |
| 144 : this._expand = expand; | 177 : this._expand = expand; |
| 145 | 178 |
| 146 void _handleData(S inputEvent) { | 179 void _handleData(S inputEvent) { |
| 147 try { | 180 try { |
| 148 for (T value in _expand(inputEvent)) { | 181 for (T value in _expand(inputEvent)) { |
| 149 _add(value); | 182 _add(value); |
| 150 } | 183 } |
| 151 } catch (e, s) { | 184 } catch (e, s) { |
| 152 // If either _expand or iterating the generated iterator throws, | 185 // If either _expand or iterating the generated iterator throws, |
| 153 // we abort the iteration. | 186 // we abort the iteration. |
| 154 _signalError(new AsyncError(e, s)); | 187 _signalError(_asyncError(e, s)); |
| 155 } | 188 } |
| 156 } | 189 } |
| 157 } | 190 } |
| 158 | 191 |
| 159 | 192 |
| 160 typedef AsyncError _ErrorTransformation(AsyncError error); | 193 typedef void _ErrorTransformation(AsyncError error); |
| 194 typedef bool _ErrorTest(error); |
| 161 | 195 |
| 162 /** | 196 /** |
| 163 * A stream pipe that converts or disposes error events | 197 * A stream pipe that converts or disposes error events |
| 164 * before passing them on. | 198 * before passing them on. |
| 165 */ | 199 */ |
| 166 class HandleErrorStream<T> extends _ForwardingTransformer<T, T> { | 200 class HandleErrorStream<T> extends _ForwardingTransformer<T, T> { |
| 167 final _ErrorTransformation _transform; | 201 final _ErrorTransformation _transform; |
| 202 final _ErrorTest _test; |
| 168 | 203 |
| 169 HandleErrorStream(AsyncError transform(AsyncError event)) | 204 HandleErrorStream(void transform(AsyncError event), bool test(error)) |
| 170 : this._transform = transform; | 205 : this._transform = transform, this._test = test; |
| 171 | 206 |
| 172 void _handleError(AsyncError error) { | 207 void _handleError(AsyncError error) { |
| 173 try { | 208 bool matches = true; |
| 174 error = _transform(error); | 209 if (_test != null) { |
| 175 if (error == null) return; | 210 try { |
| 176 } catch (e, s) { | 211 matches = _test(error.error); |
| 177 error = new AsyncError.withCause(e, s, error); | 212 } catch (e, s) { |
| 213 _signalError(_asyncError(e, s, error)); |
| 214 return; |
| 215 } |
| 178 } | 216 } |
| 179 _signalError(error); | 217 if (matches) { |
| 218 try { |
| 219 _transform(error); |
| 220 } catch (e, s) { |
| 221 _signalError(_asyncError(e, s, error)); |
| 222 return; |
| 223 } |
| 224 } else { |
| 225 _signalError(error); |
| 226 } |
| 180 } | 227 } |
| 181 } | 228 } |
| 182 | 229 |
| 183 | 230 |
| 184 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink); | 231 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink); |
| 185 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink); | 232 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink); |
| 186 typedef void _TransformDoneHandler<T>(StreamSink<T> sink); | 233 typedef void _TransformDoneHandler<T>(StreamSink<T> sink); |
| 187 | 234 |
| 188 /** | 235 /** |
| 189 * A stream pipe that intercepts all events and can generate any event as | 236 * A stream pipe that intercepts all events and can generate any event as |
| (...skipping 17 matching lines...) Expand all Loading... |
| 207 this._onError = (onError == null ? _defaultHandleError : onError), | 254 this._onError = (onError == null ? _defaultHandleError : onError), |
| 208 this._onDone = (onDone == null ? _defaultHandleDone : onDone) { | 255 this._onDone = (onDone == null ? _defaultHandleDone : onDone) { |
| 209 // Cache the sink wrapper to avoid creating a new one for each event. | 256 // Cache the sink wrapper to avoid creating a new one for each event. |
| 210 this._sink = new _StreamImplSink(this); | 257 this._sink = new _StreamImplSink(this); |
| 211 } | 258 } |
| 212 | 259 |
| 213 void _handleData(S data) { | 260 void _handleData(S data) { |
| 214 try { | 261 try { |
| 215 return _onData(data, _sink); | 262 return _onData(data, _sink); |
| 216 } catch (e, s) { | 263 } catch (e, s) { |
| 217 _signalError(new AsyncError(e, s)); | 264 _signalError(_asyncError(e, s)); |
| 218 } | 265 } |
| 219 } | 266 } |
| 220 | 267 |
| 221 void _handleError(AsyncError error) { | 268 void _handleError(AsyncError error) { |
| 222 try { | 269 try { |
| 223 _onError(error, _sink); | 270 _onError(error, _sink); |
| 224 } catch (e, s) { | 271 } catch (e, s) { |
| 225 _signalError(new AsyncError.withCause(e, s, error)); | 272 _signalError(_asyncError(e, s, error)); |
| 226 } | 273 } |
| 227 } | 274 } |
| 228 | 275 |
| 229 void _handleDone() { | 276 void _handleDone() { |
| 230 try { | 277 try { |
| 231 _onDone(_sink); | 278 _onDone(_sink); |
| 232 } catch (e, s) { | 279 } catch (e, s) { |
| 233 _signalError(new AsyncError(e, s)); | 280 _signalError(_asyncError(e, s)); |
| 234 } | 281 } |
| 235 } | 282 } |
| 236 | 283 |
| 237 /** Default data handler forwards all data. */ | 284 /** Default data handler forwards all data. */ |
| 238 static void _defaultHandleData(dynamic data, StreamSink sink) { | 285 static void _defaultHandleData(dynamic data, StreamSink sink) { |
| 239 sink.add(data); | 286 sink.add(data); |
| 240 } | 287 } |
| 241 /** Default error handler forwards all errors. */ | 288 /** Default error handler forwards all errors. */ |
| 242 static void _defaultHandleError(AsyncError error, StreamSink sink) { | 289 static void _defaultHandleError(AsyncError error, StreamSink sink) { |
| 243 sink.signalError(error); | 290 sink.signalError(error); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 273 TransformStream(StreamTransformer<S, T> transform) | 320 TransformStream(StreamTransformer<S, T> transform) |
| 274 : this._transform = transform { | 321 : this._transform = transform { |
| 275 // Cache the sink wrapper to avoid creating a new one for each event. | 322 // Cache the sink wrapper to avoid creating a new one for each event. |
| 276 this._sink = new _StreamImplSink(this); | 323 this._sink = new _StreamImplSink(this); |
| 277 } | 324 } |
| 278 | 325 |
| 279 void _handleData(S data) { | 326 void _handleData(S data) { |
| 280 try { | 327 try { |
| 281 return _transform.handleData(data, _sink); | 328 return _transform.handleData(data, _sink); |
| 282 } catch (e, s) { | 329 } catch (e, s) { |
| 283 _controller.signalError(new AsyncError(e, s)); | 330 _controller.signalError(_asyncError(e, s)); |
| 284 } | 331 } |
| 285 } | 332 } |
| 286 | 333 |
| 287 void _handleError(AsyncError error) { | 334 void _handleError(AsyncError error) { |
| 288 try { | 335 try { |
| 289 _transform.handleError(error, _sink); | 336 _transform.handleError(error, _sink); |
| 290 } catch (e, s) { | 337 } catch (e, s) { |
| 291 _controller.signalError(new AsyncError.withCause(e, s, error)); | 338 _controller.signalError(_asyncError(e, s, error)); |
| 292 } | 339 } |
| 293 } | 340 } |
| 294 | 341 |
| 295 void _handleDone() { | 342 void _handleDone() { |
| 296 try { | 343 try { |
| 297 _transform.handleDone(_sink); | 344 _transform.handleDone(_sink); |
| 298 } catch (e, s) { | 345 } catch (e, s) { |
| 299 _controller.signalError(new AsyncError(e, s)); | 346 _controller.signalError(_asyncError(e, s)); |
| 300 } | 347 } |
| 301 } | 348 } |
| 302 } | 349 } |
| 303 | 350 |
| 304 | 351 |
| 305 /** Helper class for transforming three functions into a StreamTransformer. */ | 352 /** Helper class for transforming three functions into a StreamTransformer. */ |
| 306 class _StreamTransformerFunctionWrapper<S, T> | 353 class _StreamTransformerFunctionWrapper<S, T> |
| 307 extends _StreamTransformer<S, T> { | 354 extends _StreamTransformer<S, T> { |
| 308 final _TransformDataHandler<S, T> _handleData; | 355 final _TransformDataHandler<S, T> _handleData; |
| 309 final _TransformErrorHandler<T> _handleError; | 356 final _TransformErrorHandler<T> _handleError; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 final _Predicate<T> _test; | 407 final _Predicate<T> _test; |
| 361 | 408 |
| 362 TakeWhileStream(bool test(T value)) | 409 TakeWhileStream(bool test(T value)) |
| 363 : this._test = test; | 410 : this._test = test; |
| 364 | 411 |
| 365 void _handleData(T inputEvent) { | 412 void _handleData(T inputEvent) { |
| 366 bool satisfies; | 413 bool satisfies; |
| 367 try { | 414 try { |
| 368 satisfies = _test(inputEvent); | 415 satisfies = _test(inputEvent); |
| 369 } catch (e, s) { | 416 } catch (e, s) { |
| 370 _signalError(new AsyncError(e, s)); | 417 _signalError(_asyncError(e, s)); |
| 371 // The test didn't say true. Didn't say false either, but we stop anyway. | 418 // The test didn't say true. Didn't say false either, but we stop anyway. |
| 372 _close(); | 419 _close(); |
| 373 return; | 420 return; |
| 374 } | 421 } |
| 375 if (satisfies) { | 422 if (satisfies) { |
| 376 _add(inputEvent); | 423 _add(inputEvent); |
| 377 } else { | 424 } else { |
| 378 _close(); | 425 _close(); |
| 379 } | 426 } |
| 380 } | 427 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 407 : this._test = test; | 454 : this._test = test; |
| 408 | 455 |
| 409 void _handleData(T inputEvent) { | 456 void _handleData(T inputEvent) { |
| 410 if (_hasFailed) { | 457 if (_hasFailed) { |
| 411 _add(inputEvent); | 458 _add(inputEvent); |
| 412 } | 459 } |
| 413 bool satisfies; | 460 bool satisfies; |
| 414 try { | 461 try { |
| 415 satisfies = _test(inputEvent); | 462 satisfies = _test(inputEvent); |
| 416 } catch (e, s) { | 463 } catch (e, s) { |
| 417 _signalError(new AsyncError(e, s)); | 464 _signalError(_asyncError(e, s)); |
| 418 // A failure to return a boolean is considered "not matching". | 465 // A failure to return a boolean is considered "not matching". |
| 419 _hasFailed = true; | 466 _hasFailed = true; |
| 420 return; | 467 return; |
| 421 } | 468 } |
| 422 if (!satisfies) { | 469 if (!satisfies) { |
| 423 _hasFailed = true; | 470 _hasFailed = true; |
| 424 _add(inputEvent); | 471 _add(inputEvent); |
| 425 } | 472 } |
| 426 } | 473 } |
| 427 } | 474 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 443 return _add(inputEvent); | 490 return _add(inputEvent); |
| 444 } else { | 491 } else { |
| 445 bool isEqual; | 492 bool isEqual; |
| 446 try { | 493 try { |
| 447 if (_equals == null) { | 494 if (_equals == null) { |
| 448 isEqual = (_previous == inputEvent); | 495 isEqual = (_previous == inputEvent); |
| 449 } else { | 496 } else { |
| 450 isEqual = _equals(_previous, inputEvent); | 497 isEqual = _equals(_previous, inputEvent); |
| 451 } | 498 } |
| 452 } catch (e, s) { | 499 } catch (e, s) { |
| 453 _signalError(new AsyncError(e, s)); | 500 _signalError(_asyncError(e, s)); |
| 454 return null; | 501 return null; |
| 455 } | 502 } |
| 456 if (!isEqual) { | 503 if (!isEqual) { |
| 457 _add(inputEvent); | 504 _add(inputEvent); |
| 458 _previous = inputEvent; | 505 _previous = inputEvent; |
| 459 } | 506 } |
| 460 } | 507 } |
| 461 } | 508 } |
| 462 } | 509 } |
| OLD | NEW |