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

Side by Side Diff: sdk/lib/io/io_sink.dart

Issue 14208007: Improve WebSocket interface by making it implement StreamSink. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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
« no previous file with comments | « no previous file | sdk/lib/io/websocket.dart » ('j') | sdk/lib/io/websocket.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart.io; 5 part of dart.io;
6 6
7 /** 7 /**
8 * Helper class to wrap a [StreamConsumer<List<int>>] and provide 8 * Helper class to wrap a [StreamConsumer<List<int>>] and provide
9 * utility functions for writing to the StreamConsumer directly. The 9 * utility functions for writing to the StreamConsumer directly. The
10 * [IOSink] buffers the input given by all [StringSink] methods and will delay 10 * [IOSink] buffers the input given by all [StringSink] methods and will delay
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 */ 45 */
46 Future close(); 46 Future close();
47 47
48 /** 48 /**
49 * Get a future that will complete when all synchronous have completed, or an 49 * Get a future that will complete when all synchronous have completed, or an
50 * error happened. This future is identical to the future returned from close. 50 * error happened. This future is identical to the future returned from close.
51 */ 51 */
52 Future get done; 52 Future get done;
53 } 53 }
54 54
55 55 class _StreamSinkImpl<T> implements StreamSink<T> {
Søren Gjesse 2013/04/16 12:41:31 Should this class be public in dart:async to enabl
Anders Johnsen 2013/04/16 13:46:22 Maybe. I'll consider moving it later on, after tal
56 class _IOSinkImpl implements IOSink { 56 final StreamConsumer<T> _target;
57 final StreamConsumer<List<int>> _target;
58 Completer _doneCompleter = new Completer(); 57 Completer _doneCompleter = new Completer();
59 Future _doneFuture; 58 Future _doneFuture;
60 StreamController<List<int>> _controllerInstance; 59 StreamController<T> _controllerInstance;
61 Completer _controllerCompleter; 60 Completer _controllerCompleter;
62 Encoding _encoding;
63 bool _isClosed = false; 61 bool _isClosed = false;
64 bool _isBound = false; 62 bool _isBound = false;
65 bool _encodingMutable = true;
66 63
67 _IOSinkImpl(StreamConsumer<List<int>> this._target, this._encoding) { 64 _StreamSinkImpl(StreamConsumer<T> this._target) {
68 _doneFuture = _doneCompleter.future; 65 _doneFuture = _doneCompleter.future;
69 } 66 }
70 67
71 Encoding get encoding => _encoding; 68 void add(T data) {
72
73 void set encoding(Encoding value) {
74 if (!_encodingMutable) {
75 throw new StateError("IOSink encoding is not mutable");
76 }
77 _encoding = value;
78 }
79
80 void write(Object obj) {
81 // This comment is copied from runtime/lib/string_buffer_patch.dart.
82 // TODO(srdjan): The following four lines could be replaced by
83 // '$obj', but apparently this is too slow on the Dart VM.
84 String string;
85 if (obj is String) {
86 string = obj;
87 } else {
88 string = obj.toString();
89 if (string is! String) {
90 throw new ArgumentError('toString() did not return a string');
91 }
92 }
93 if (string.isEmpty) return;
94 add(_encodeString(string, _encoding));
95 }
96
97 void writeAll(Iterable objects, [String separator = ""]) {
98 Iterator iterator = objects.iterator;
99 if (!iterator.moveNext()) return;
100 if (separator.isEmpty) {
101 do {
102 write(iterator.current);
103 } while (iterator.moveNext());
104 } else {
105 write(iterator.current);
106 while (iterator.moveNext()) {
107 write(separator);
108 write(iterator.current);
109 }
110 }
111 }
112
113 void writeln([Object obj = ""]) {
114 write(obj);
115 write("\n");
116 }
117
118 void writeCharCode(int charCode) {
119 write(new String.fromCharCode(charCode));
120 }
121
122 void add(List<int> data) {
123 _controller.add(data); 69 _controller.add(data);
124 } 70 }
125 71
126 void addError(error) { 72 void addError(error) {
127 _controller.addError(error); 73 _controller.addError(error);
128 } 74 }
129 75
130 Future addStream(Stream<List<int>> stream) { 76 Future addStream(Stream<T> stream) {
131 if (_isBound) { 77 if (_isBound) {
132 throw new StateError("IOSink is already bound to a stream"); 78 throw new StateError("StreamSink is already bound to a stream");
133 } 79 }
134 _isBound = true; 80 _isBound = true;
135 // Wait for any sync operations to complete. 81 // Wait for any sync operations to complete.
136 Future targetAddStream() { 82 Future targetAddStream() {
137 return _target.addStream(stream) 83 return _target.addStream(stream)
138 .whenComplete(() { 84 .whenComplete(() {
139 _isBound = false; 85 _isBound = false;
140 }); 86 });
141 } 87 }
142 if (_controllerInstance == null) return targetAddStream(); 88 if (_controllerInstance == null) return targetAddStream();
143 var future = _controllerCompleter.future; 89 var future = _controllerCompleter.future;
144 _controllerInstance.close(); 90 _controllerInstance.close();
145 return future.then((_) => targetAddStream()); 91 return future.then((_) => targetAddStream());
146 } 92 }
147 93
148 Future close() { 94 Future close() {
149 if (_isBound) { 95 if (_isBound) {
150 throw new StateError("IOSink is bound to a stream"); 96 throw new StateError("StreamSink is bound to a stream");
151 } 97 }
152 if (!_isClosed) { 98 if (!_isClosed) {
153 _isClosed = true; 99 _isClosed = true;
154 if (_controllerInstance != null) { 100 if (_controllerInstance != null) {
155 _controllerInstance.close(); 101 _controllerInstance.close();
156 } else { 102 } else {
157 _closeTarget(); 103 _closeTarget();
158 } 104 }
159 } 105 }
160 return done; 106 return done;
(...skipping 11 matching lines...) Expand all
172 if (_doneCompleter == null) return; 118 if (_doneCompleter == null) return;
173 var tmp = _doneCompleter; 119 var tmp = _doneCompleter;
174 _doneCompleter = null; 120 _doneCompleter = null;
175 if (error == null) { 121 if (error == null) {
176 tmp.complete(value); 122 tmp.complete(value);
177 } else { 123 } else {
178 tmp.completeError(error); 124 tmp.completeError(error);
179 } 125 }
180 } 126 }
181 127
182 StreamController<List<int>> get _controller { 128 StreamController<T> get _controller {
183 if (_isBound) { 129 if (_isBound) {
184 throw new StateError("IOSink is bound to a stream"); 130 throw new StateError("StreamSink is bound to a stream");
185 } 131 }
186 if (_isClosed) { 132 if (_isClosed) {
187 throw new StateError("IOSink is closed"); 133 throw new StateError("StreamSink is closed");
188 } 134 }
189 if (_controllerInstance == null) { 135 if (_controllerInstance == null) {
190 _controllerInstance = new StreamController<List<int>>(); 136 _controllerInstance = new StreamController<T>();
191 _controllerCompleter = new Completer(); 137 _controllerCompleter = new Completer();
192 _target.addStream(_controller.stream) 138 _target.addStream(_controller.stream)
193 .then( 139 .then(
194 (_) { 140 (_) {
195 if (_isBound) { 141 if (_isBound) {
196 // A new stream takes over - forward values to that stream. 142 // A new stream takes over - forward values to that stream.
197 var completer = _controllerCompleter; 143 var completer = _controllerCompleter;
198 _controllerCompleter = null; 144 _controllerCompleter = null;
199 _controllerInstance = null; 145 _controllerInstance = null;
200 completer.complete(); 146 completer.complete();
(...skipping 12 matching lines...) Expand all
213 } else { 159 } else {
214 // No new stream. No need to close target, as it have already 160 // No new stream. No need to close target, as it have already
215 // failed. 161 // failed.
216 _completeDone(error: error); 162 _completeDone(error: error);
217 } 163 }
218 }); 164 });
219 } 165 }
220 return _controllerInstance; 166 return _controllerInstance;
221 } 167 }
222 } 168 }
169
170
171 class _IOSinkImpl extends _StreamSinkImpl<List<int>> implements IOSink {
172 Encoding _encoding;
173 bool _encodingMutable = true;
174
175 _IOSinkImpl(StreamConsumer<List<int>> target, this._encoding)
176 : super(target);
177
178 Encoding get encoding => _encoding;
179
180 void set encoding(Encoding value) {
181 if (!_encodingMutable) {
182 throw new StateError("IOSink encoding is not mutable");
183 }
184 _encoding = value;
185 }
186
187 void write(Object obj) {
188 // This comment is copied from runtime/lib/string_buffer_patch.dart.
189 // TODO(srdjan): The following four lines could be replaced by
190 // '$obj', but apparently this is too slow on the Dart VM.
191 String string;
192 if (obj is String) {
193 string = obj;
194 } else {
195 string = obj.toString();
196 if (string is! String) {
197 throw new ArgumentError('toString() did not return a string');
198 }
199 }
200 if (string.isEmpty) return;
201 add(_encodeString(string, _encoding));
202 }
203
204 void writeAll(Iterable objects, [String separator = ""]) {
205 Iterator iterator = objects.iterator;
206 if (!iterator.moveNext()) return;
207 if (separator.isEmpty) {
208 do {
209 write(iterator.current);
210 } while (iterator.moveNext());
211 } else {
212 write(iterator.current);
213 while (iterator.moveNext()) {
214 write(separator);
215 write(iterator.current);
216 }
217 }
218 }
219
220 void writeln([Object obj = ""]) {
221 write(obj);
222 write("\n");
223 }
224
225 void writeCharCode(int charCode) {
226 write(new String.fromCharCode(charCode));
227 }
228 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/io/websocket.dart » ('j') | sdk/lib/io/websocket.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698