Chromium Code Reviews| 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 /** | 7 /** |
| 8 * A wrapper around a stream that allows independent subscribers. | 8 * A wrapper around a stream that allows independent subscribers. |
| 9 * | 9 * |
| 10 * By default [this] subscribes to [_source] and forwards all events to its own | 10 * By default [this] subscribes to [_source] and forwards all events to its own |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 _add(outputEvent); | 62 _add(outputEvent); |
| 63 } | 63 } |
| 64 | 64 |
| 65 void _handleError(AsyncError error) { | 65 void _handleError(AsyncError error) { |
| 66 _signalError(error); | 66 _signalError(error); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void _handleDone() { | 69 void _handleDone() { |
| 70 _close(); | 70 _close(); |
| 71 } | 71 } |
| 72 | |
| 73 AsyncError _asyncError(Object error, Object stackTrace, [AsyncError cause]) { | |
| 74 if (error is AsyncError) return error; | |
| 75 if (cause == null) return new AsyncError(error, stackTrace); | |
| 76 return new AsyncError.withCause(error, stackTrace, cause); | |
| 77 } | |
| 72 } | 78 } |
| 73 | 79 |
| 74 | 80 |
| 75 abstract class _ForwardingTransformer<S, T> extends _ForwardingMultiStream<S, T> | 81 abstract class _ForwardingTransformer<S, T> extends _ForwardingMultiStream<S, T> |
| 76 implements StreamTransformer<S, T> { | 82 implements StreamTransformer<S, T> { |
| 77 Stream<T> bind(Stream<S> source) { | 83 Stream<T> bind(Stream<S> source) { |
| 78 assert(_source == null); | 84 if (_source != null) throw new StateError("Already bound to source."); |
| 79 _source = source; | 85 _source = source; |
| 80 if (_hasSubscribers) { | 86 if (_hasSubscribers) { |
| 81 _subscribeToSource(); | 87 _subscribeToSource(); |
| 82 } | 88 } |
| 83 return this; | 89 return this; |
| 84 } | 90 } |
| 85 } | 91 } |
| 86 | 92 |
| 87 // ------------------------------------------------------------------- | 93 // ------------------------------------------------------------------- |
| 88 // Stream transformers used by the default Stream implementation. | 94 // Stream transformers used by the default Stream implementation. |
| 89 // ------------------------------------------------------------------- | 95 // ------------------------------------------------------------------- |
| 90 | 96 |
| 91 typedef bool _Predicate<T>(T value); | 97 typedef bool _Predicate<T>(T value); |
| 92 | 98 |
| 93 class WhereStream<T> extends _ForwardingTransformer<T, T> { | 99 class WhereStream<T> extends _ForwardingTransformer<T, T> { |
| 94 final _Predicate<T> _test; | 100 final _Predicate<T> _test; |
| 95 | 101 |
| 96 WhereStream(bool test(T value)) | 102 WhereStream(bool test(T value)) |
| 97 : this._test = test; | 103 : this._test = test; |
| 98 | 104 |
| 99 void _handleData(T inputEvent) { | 105 void _handleData(T inputEvent) { |
| 100 bool satisfies; | 106 bool satisfies; |
| 101 try { | 107 try { |
| 102 satisfies = _test(inputEvent); | 108 satisfies = _test(inputEvent); |
| 103 } catch (e, s) { | 109 } catch (e, s) { |
| 104 _signalError(new AsyncError(e, s)); | 110 _signalError(_asyncError(e, s)); |
| 105 return; | 111 return; |
| 106 } | 112 } |
| 107 if (satisfies) { | 113 if (satisfies) { |
| 108 _add(inputEvent); | 114 _add(inputEvent); |
| 109 } | 115 } |
| 110 } | 116 } |
| 111 } | 117 } |
| 112 | 118 |
| 113 | 119 |
| 114 typedef T _Transformation<S, T>(S value); | 120 typedef T _Transformation<S, T>(S value); |
| 115 | 121 |
| 116 /** | 122 /** |
| 117 * A stream pipe that converts data events before passing them on. | 123 * A stream pipe that converts data events before passing them on. |
| 118 */ | 124 */ |
| 119 class MapStream<S, T> extends _ForwardingTransformer<S, T> { | 125 class MapStream<S, T> extends _ForwardingTransformer<S, T> { |
| 120 final _Transformation _transform; | 126 final _Transformation _transform; |
| 121 | 127 |
| 122 MapStream(T transform(S event)) | 128 MapStream(T transform(S event)) |
| 123 : this._transform = transform; | 129 : this._transform = transform; |
| 124 | 130 |
| 125 void _handleData(S inputEvent) { | 131 void _handleData(S inputEvent) { |
| 126 T outputEvent; | 132 T outputEvent; |
| 127 try { | 133 try { |
| 128 outputEvent = _transform(inputEvent); | 134 outputEvent = _transform(inputEvent); |
| 129 } catch (e, s) { | 135 } catch (e, s) { |
| 130 _signalError(new AsyncError(e, s)); | 136 _signalError(_asyncError(e, s)); |
| 131 return; | 137 return; |
| 132 } | 138 } |
| 133 _add(outputEvent); | 139 _add(outputEvent); |
| 134 } | 140 } |
| 135 } | 141 } |
| 136 | 142 |
| 137 /** | 143 /** |
| 138 * A stream pipe that converts data events before passing them on. | 144 * A stream pipe that converts data events before passing them on. |
| 139 */ | 145 */ |
| 140 class ExpandStream<S, T> extends _ForwardingTransformer<S, T> { | 146 class ExpandStream<S, T> extends _ForwardingTransformer<S, T> { |
| 141 final _Transformation<S, Iterable<T>> _expand; | 147 final _Transformation<S, Iterable<T>> _expand; |
| 142 | 148 |
| 143 ExpandStream(Iterable<T> expand(S event)) | 149 ExpandStream(Iterable<T> expand(S event)) |
| 144 : this._expand = expand; | 150 : this._expand = expand; |
| 145 | 151 |
| 146 void _handleData(S inputEvent) { | 152 void _handleData(S inputEvent) { |
| 147 try { | 153 try { |
| 148 for (T value in _expand(inputEvent)) { | 154 for (T value in _expand(inputEvent)) { |
| 149 _add(value); | 155 _add(value); |
| 150 } | 156 } |
| 151 } catch (e, s) { | 157 } catch (e, s) { |
| 152 // If either _expand or iterating the generated iterator throws, | 158 // If either _expand or iterating the generated iterator throws, |
| 153 // we abort the iteration. | 159 // we abort the iteration. |
| 154 _signalError(new AsyncError(e, s)); | 160 _signalError(_asyncError(e, s)); |
| 155 } | 161 } |
| 156 } | 162 } |
| 157 } | 163 } |
| 158 | 164 |
| 159 | 165 |
| 160 typedef AsyncError _ErrorTransformation(AsyncError error); | 166 typedef AsyncError _ErrorTransformation(AsyncError error); |
| 167 typedef bool _ErrorTest(error); | |
| 161 | 168 |
| 162 /** | 169 /** |
| 163 * A stream pipe that converts or disposes error events | 170 * A stream pipe that converts or disposes error events |
| 164 * before passing them on. | 171 * before passing them on. |
| 165 */ | 172 */ |
| 166 class HandleErrorStream<T> extends _ForwardingTransformer<T, T> { | 173 class HandleErrorStream<T> extends _ForwardingTransformer<T, T> { |
| 167 final _ErrorTransformation _transform; | 174 final _ErrorTransformation _transform; |
|
floitsch
2013/01/11 13:23:33
Type is not right anymore. It's a void function no
Lasse Reichstein Nielsen
2013/01/14 08:33:30
Done.
| |
| 175 final _ErrorTest _test; | |
| 168 | 176 |
| 169 HandleErrorStream(AsyncError transform(AsyncError event)) | 177 HandleErrorStream(void transform(AsyncError event), bool test(error)) |
| 170 : this._transform = transform; | 178 : this._transform = transform, this._test = test; |
| 171 | 179 |
| 172 void _handleError(AsyncError error) { | 180 void _handleError(AsyncError error) { |
| 173 try { | 181 bool matches = true; |
| 174 error = _transform(error); | 182 if (_test != null) { |
| 175 if (error == null) return; | 183 try { |
| 176 } catch (e, s) { | 184 matches = _test(error.error); |
| 177 error = new AsyncError.withCause(e, s, error); | 185 } catch (e, s) { |
| 186 _signalError(_asyncError(e, s, error)); | |
| 187 return; | |
| 188 } | |
| 178 } | 189 } |
| 179 _signalError(error); | 190 if (matches) { |
| 191 try { | |
| 192 _transform(error); | |
| 193 } catch (e, s) { | |
| 194 _signalError(_asyncError(e, s, error)); | |
| 195 return; | |
| 196 } | |
| 197 } else { | |
| 198 _signalError(error); | |
| 199 } | |
| 180 } | 200 } |
| 181 } | 201 } |
| 182 | 202 |
| 183 | 203 |
| 184 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink); | 204 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink); |
| 185 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink); | 205 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink); |
| 186 typedef void _TransformDoneHandler<T>(StreamSink<T> sink); | 206 typedef void _TransformDoneHandler<T>(StreamSink<T> sink); |
| 187 | 207 |
| 188 /** | 208 /** |
| 189 * A stream pipe that intercepts all events and can generate any event as | 209 * 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), | 227 this._onError = (onError == null ? _defaultHandleError : onError), |
| 208 this._onDone = (onDone == null ? _defaultHandleDone : onDone) { | 228 this._onDone = (onDone == null ? _defaultHandleDone : onDone) { |
| 209 // Cache the sink wrapper to avoid creating a new one for each event. | 229 // Cache the sink wrapper to avoid creating a new one for each event. |
| 210 this._sink = new _StreamImplSink(this); | 230 this._sink = new _StreamImplSink(this); |
| 211 } | 231 } |
| 212 | 232 |
| 213 void _handleData(S data) { | 233 void _handleData(S data) { |
| 214 try { | 234 try { |
| 215 return _onData(data, _sink); | 235 return _onData(data, _sink); |
| 216 } catch (e, s) { | 236 } catch (e, s) { |
| 217 _signalError(new AsyncError(e, s)); | 237 _signalError(_asyncError(e, s)); |
| 218 } | 238 } |
| 219 } | 239 } |
| 220 | 240 |
| 221 void _handleError(AsyncError error) { | 241 void _handleError(AsyncError error) { |
| 222 try { | 242 try { |
| 223 _onError(error, _sink); | 243 _onError(error, _sink); |
| 224 } catch (e, s) { | 244 } catch (e, s) { |
| 225 _signalError(new AsyncError.withCause(e, s, error)); | 245 _signalError(_asyncError(e, s, error)); |
| 226 } | 246 } |
| 227 } | 247 } |
| 228 | 248 |
| 229 void _handleDone() { | 249 void _handleDone() { |
| 230 try { | 250 try { |
| 231 _onDone(_sink); | 251 _onDone(_sink); |
| 232 } catch (e, s) { | 252 } catch (e, s) { |
| 233 _signalError(new AsyncError(e, s)); | 253 _signalError(_asyncError(e, s)); |
| 234 } | 254 } |
| 235 } | 255 } |
| 236 | 256 |
| 237 /** Default data handler forwards all data. */ | 257 /** Default data handler forwards all data. */ |
| 238 static void _defaultHandleData(dynamic data, StreamSink sink) { | 258 static void _defaultHandleData(dynamic data, StreamSink sink) { |
| 239 sink.add(data); | 259 sink.add(data); |
| 240 } | 260 } |
| 241 /** Default error handler forwards all errors. */ | 261 /** Default error handler forwards all errors. */ |
| 242 static void _defaultHandleError(AsyncError error, StreamSink sink) { | 262 static void _defaultHandleError(AsyncError error, StreamSink sink) { |
| 243 sink.signalError(error); | 263 sink.signalError(error); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 273 TransformStream(StreamTransformer<S, T> transform) | 293 TransformStream(StreamTransformer<S, T> transform) |
| 274 : this._transform = transform { | 294 : this._transform = transform { |
| 275 // Cache the sink wrapper to avoid creating a new one for each event. | 295 // Cache the sink wrapper to avoid creating a new one for each event. |
| 276 this._sink = new _StreamImplSink(this); | 296 this._sink = new _StreamImplSink(this); |
| 277 } | 297 } |
| 278 | 298 |
| 279 void _handleData(S data) { | 299 void _handleData(S data) { |
| 280 try { | 300 try { |
| 281 return _transform.handleData(data, _sink); | 301 return _transform.handleData(data, _sink); |
| 282 } catch (e, s) { | 302 } catch (e, s) { |
| 283 _controller.signalError(new AsyncError(e, s)); | 303 _controller.signalError(_asyncError(e, s)); |
| 284 } | 304 } |
| 285 } | 305 } |
| 286 | 306 |
| 287 void _handleError(AsyncError error) { | 307 void _handleError(AsyncError error) { |
| 288 try { | 308 try { |
| 289 _transform.handleError(error, _sink); | 309 _transform.handleError(error, _sink); |
| 290 } catch (e, s) { | 310 } catch (e, s) { |
| 291 _controller.signalError(new AsyncError.withCause(e, s, error)); | 311 _controller.signalError(_asyncError(e, s, error)); |
| 292 } | 312 } |
| 293 } | 313 } |
| 294 | 314 |
| 295 void _handleDone() { | 315 void _handleDone() { |
| 296 try { | 316 try { |
| 297 _transform.handleDone(_sink); | 317 _transform.handleDone(_sink); |
| 298 } catch (e, s) { | 318 } catch (e, s) { |
| 299 _controller.signalError(new AsyncError(e, s)); | 319 _controller.signalError(_asyncError(e, s)); |
| 300 } | 320 } |
| 301 } | 321 } |
| 302 } | 322 } |
| 303 | 323 |
| 304 | 324 |
| 305 /** Helper class for transforming three functions into a StreamTransformer. */ | 325 /** Helper class for transforming three functions into a StreamTransformer. */ |
| 306 class _StreamTransformerFunctionWrapper<S, T> | 326 class _StreamTransformerFunctionWrapper<S, T> |
| 307 extends _StreamTransformer<S, T> { | 327 extends _StreamTransformer<S, T> { |
| 308 final _TransformDataHandler<S, T> _handleData; | 328 final _TransformDataHandler<S, T> _handleData; |
| 309 final _TransformErrorHandler<T> _handleError; | 329 final _TransformErrorHandler<T> _handleError; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 final _Predicate<T> _test; | 380 final _Predicate<T> _test; |
| 361 | 381 |
| 362 TakeWhileStream(bool test(T value)) | 382 TakeWhileStream(bool test(T value)) |
| 363 : this._test = test; | 383 : this._test = test; |
| 364 | 384 |
| 365 void _handleData(T inputEvent) { | 385 void _handleData(T inputEvent) { |
| 366 bool satisfies; | 386 bool satisfies; |
| 367 try { | 387 try { |
| 368 satisfies = _test(inputEvent); | 388 satisfies = _test(inputEvent); |
| 369 } catch (e, s) { | 389 } catch (e, s) { |
| 370 _signalError(new AsyncError(e, s)); | 390 _signalError(_asyncError(e, s)); |
| 371 // The test didn't say true. Didn't say false either, but we stop anyway. | 391 // The test didn't say true. Didn't say false either, but we stop anyway. |
| 372 _close(); | 392 _close(); |
| 373 return; | 393 return; |
| 374 } | 394 } |
| 375 if (satisfies) { | 395 if (satisfies) { |
| 376 _add(inputEvent); | 396 _add(inputEvent); |
| 377 } else { | 397 } else { |
| 378 _close(); | 398 _close(); |
| 379 } | 399 } |
| 380 } | 400 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 407 : this._test = test; | 427 : this._test = test; |
| 408 | 428 |
| 409 void _handleData(T inputEvent) { | 429 void _handleData(T inputEvent) { |
| 410 if (_hasFailed) { | 430 if (_hasFailed) { |
| 411 _add(inputEvent); | 431 _add(inputEvent); |
| 412 } | 432 } |
| 413 bool satisfies; | 433 bool satisfies; |
| 414 try { | 434 try { |
| 415 satisfies = _test(inputEvent); | 435 satisfies = _test(inputEvent); |
| 416 } catch (e, s) { | 436 } catch (e, s) { |
| 417 _signalError(new AsyncError(e, s)); | 437 _signalError(_asyncError(e, s)); |
| 418 // A failure to return a boolean is considered "not matching". | 438 // A failure to return a boolean is considered "not matching". |
| 419 _hasFailed = true; | 439 _hasFailed = true; |
| 420 return; | 440 return; |
| 421 } | 441 } |
| 422 if (!satisfies) { | 442 if (!satisfies) { |
| 423 _hasFailed = true; | 443 _hasFailed = true; |
| 424 _add(inputEvent); | 444 _add(inputEvent); |
| 425 } | 445 } |
| 426 } | 446 } |
| 427 } | 447 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 443 return _add(inputEvent); | 463 return _add(inputEvent); |
| 444 } else { | 464 } else { |
| 445 bool isEqual; | 465 bool isEqual; |
| 446 try { | 466 try { |
| 447 if (_equals == null) { | 467 if (_equals == null) { |
| 448 isEqual = (_previous == inputEvent); | 468 isEqual = (_previous == inputEvent); |
| 449 } else { | 469 } else { |
| 450 isEqual = _equals(_previous, inputEvent); | 470 isEqual = _equals(_previous, inputEvent); |
| 451 } | 471 } |
| 452 } catch (e, s) { | 472 } catch (e, s) { |
| 453 _signalError(new AsyncError(e, s)); | 473 _signalError(_asyncError(e, s)); |
| 454 return null; | 474 return null; |
| 455 } | 475 } |
| 456 if (!isEqual) { | 476 if (!isEqual) { |
| 457 _add(inputEvent); | 477 _add(inputEvent); |
| 458 _previous = inputEvent; | 478 _previous = inputEvent; |
| 459 } | 479 } |
| 460 } | 480 } |
| 461 } | 481 } |
| 462 } | 482 } |
| OLD | NEW |