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

Side by Side Diff: sdk/lib/async/stream_pipe.dart

Issue 11862008: Make Streams also cosider a thrown AsyncError a rethrow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix indentation. Created 7 years, 11 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) 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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698