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

Side by Side Diff: runtime/bin/socket_stream_impl.dart

Issue 11337019: Use patching for dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 1 month 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 class _SocketInputStream implements InputStream {
6 _SocketInputStream(Socket socket) : _socket = socket {
7 if (_socket._closed) _closed = true;
8 _socket.onClosed = _onClosed;
9 }
10
11 List<int> read([int len]) {
12 int bytesToRead = available();
13 if (bytesToRead == 0) return null;
14 if (len !== null) {
15 if (len <= 0) {
16 throw new StreamException("Illegal length $len");
17 } else if (bytesToRead > len) {
18 bytesToRead = len;
19 }
20 }
21 List<int> buffer = new Uint8List(bytesToRead);
22 int bytesRead = _socket.readList(buffer, 0, bytesToRead);
23 if (bytesRead == 0) {
24 // On MacOS when reading from a tty Ctrl-D will result in one
25 // byte reported as available. Attempting to read it out will
26 // result in zero bytes read. When that happens there is no data
27 // which is indicated by a null return value.
28 return null;
29 } else if (bytesRead < bytesToRead) {
30 List<int> newBuffer = new Uint8List(bytesRead);
31 newBuffer.setRange(0, bytesRead, buffer);
32 return newBuffer;
33 } else {
34 return buffer;
35 }
36 }
37
38 int readInto(List<int> buffer, [int offset = 0, int len]) {
39 if (_closed) return null;
40 if (len === null) len = buffer.length;
41 if (offset < 0) throw new StreamException("Illegal offset $offset");
42 if (len < 0) throw new StreamException("Illegal length $len");
43 return _socket.readList(buffer, offset, len);
44 }
45
46 int available() => _socket.available();
47
48 void pipe(OutputStream output, {bool close: true}) {
49 _pipe(this, output, close: close);
50 }
51
52 void close() {
53 if (!_closed) {
54 _socket.close();
55 }
56 }
57
58 bool get closed => _closed;
59
60 void set onData(void callback()) {
61 _socket._onData = callback;
62 }
63
64 void set onClosed(void callback()) {
65 _clientCloseHandler = callback;
66 _socket._onClosed = _onClosed;
67 }
68
69 void set onError(void callback(e)) {
70 _onError = callback;
71 }
72
73 void _onClosed() {
74 _closed = true;
75 if (_clientCloseHandler !== null) {
76 _clientCloseHandler();
77 }
78 }
79
80 void _onSocketError(e) {
81 close();
82 if (_onError != null) {
83 _onError(e);
84 return true;
85 } else {
86 return false;
87 }
88 }
89
90 Socket _socket;
91 bool _closed = false;
92 Function _clientCloseHandler;
93 Function _onError;
94 }
95
96
97 class _SocketOutputStream
98 extends _BaseOutputStream implements OutputStream {
99 _SocketOutputStream(Socket socket)
100 : _socket = socket, _pendingWrites = new _BufferList();
101
102 bool write(List<int> buffer, [bool copyBuffer = true]) {
103 return _write(buffer, 0, buffer.length, copyBuffer);
104 }
105
106 bool writeFrom(List<int> buffer, [int offset = 0, int len]) {
107 return _write(
108 buffer, offset, (len == null) ? buffer.length - offset : len, true);
109 }
110
111 void flush() {
112 // Nothing to do on a socket output stream.
113 }
114
115 void close() {
116 if (_closing && _closed) return;
117 if (!_pendingWrites.isEmpty) {
118 // Mark the socket for close when all data is written.
119 _closing = true;
120 _socket._onWrite = _onWrite;
121 } else {
122 // Close the socket for writing.
123 _socket._closeWrite();
124 _closed = true;
125 // Invoke the callback asynchronously.
126 new Timer(0, (t) {
127 if (_onClosed != null) _onClosed();
128 });
129 }
130 }
131
132 void destroy() {
133 _socket.onWrite = null;
134 _pendingWrites.clear();
135 _socket.close();
136 _closed = true;
137 }
138
139 bool get closed => _closed;
140
141 void set onNoPendingWrites(void callback()) {
142 _onNoPendingWrites = callback;
143 if (_onNoPendingWrites != null) {
144 _socket._onWrite = _onWrite;
145 }
146 }
147
148 void set onClosed(void callback()) {
149 _onClosed = callback;
150 }
151
152 bool _write(List<int> buffer, int offset, int len, bool copyBuffer) {
153 if (_closing || _closed) throw new StreamException("Stream closed");
154 int bytesWritten = 0;
155 if (_pendingWrites.isEmpty) {
156 // If nothing is buffered write as much as possible and buffer
157 // the rest.
158 bytesWritten = _socket.writeList(buffer, offset, len);
159 if (bytesWritten == len) return true;
160 }
161
162 // Place remaining data on the pending writes queue.
163 int notWrittenOffset = offset + bytesWritten;
164 if (copyBuffer) {
165 List<int> newBuffer =
166 buffer.getRange(notWrittenOffset, len - bytesWritten);
167 _pendingWrites.add(newBuffer);
168 } else {
169 assert(offset + len == buffer.length);
170 _pendingWrites.add(buffer, notWrittenOffset);
171 }
172 _socket._onWrite = _onWrite;
173 return false;
174 }
175
176 void _onWrite() {
177 // Write as much buffered data to the socket as possible.
178 while (!_pendingWrites.isEmpty) {
179 List<int> buffer = _pendingWrites.first;
180 int offset = _pendingWrites.index;
181 int bytesToWrite = buffer.length - offset;
182 int bytesWritten;
183 try {
184 bytesWritten = _socket.writeList(buffer, offset, bytesToWrite);
185 } catch (e) {
186 _pendingWrites.clear();
187 _onSocketError(e);
188 return;
189 }
190 _pendingWrites.removeBytes(bytesWritten);
191 if (bytesWritten < bytesToWrite) {
192 _socket._onWrite = _onWrite;
193 return;
194 }
195 }
196
197 // All buffered data was written.
198 if (_closing) {
199 _socket._closeWrite();
200 _closed = true;
201 if (_onClosed != null) {
202 _onClosed();
203 }
204 } else {
205 if (_onNoPendingWrites != null) _onNoPendingWrites();
206 }
207 if (_onNoPendingWrites == null) {
208 _socket._onWrite = null;
209 } else {
210 _socket._onWrite = _onWrite;
211 }
212 }
213
214 bool _onSocketError(e) {
215 close();
216 if (_onError != null) {
217 _onError(e);
218 return true;
219 } else {
220 return false;
221 }
222 }
223
224 Socket _socket;
225 _BufferList _pendingWrites;
226 Function _onNoPendingWrites;
227 Function _onClosed;
228 bool _closing = false;
229 bool _closed = false;
230 }
OLDNEW
« runtime/bin/io.dart ('K') | « runtime/bin/socket_patch.dart ('k') | runtime/bin/stdio.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698