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

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

Issue 12316036: Merge IO v2 branch to bleeding edge (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased to r18818 Created 7 years, 10 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 | « sdk/lib/io/socket.dart ('k') | sdk/lib/io/stdio.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of dart.io;
6
7 class _SocketInputStream implements InputStream {
8 _SocketInputStream(Socket socket) : _socket = socket {
9 if (_socket._closed) _closed = true;
10 _socket.onClosed = _onClosed;
11 }
12
13 List<int> read([int len]) {
14 return _socket.read(len);
15 }
16
17 int readInto(List<int> buffer, [int offset = 0, int len]) {
18 if (_closed) return null;
19 if (len == null) len = buffer.length;
20 if (offset < 0) throw new StreamException("Illegal offset $offset");
21 if (len < 0) throw new StreamException("Illegal length $len");
22 return _socket.readList(buffer, offset, len);
23 }
24
25 int available() => _socket.available();
26
27 void pipe(OutputStream output, {bool close: true}) {
28 _pipe(this, output, close: close);
29 }
30
31 void close() {
32 if (!_closed) {
33 _socket.close();
34 }
35 }
36
37 bool get closed => _closed;
38
39 void set onData(void callback()) {
40 _socket._onData = callback;
41 }
42
43 void set onClosed(void callback()) {
44 _clientCloseHandler = callback;
45 _socket._onClosed = _onClosed;
46 }
47
48 void set onError(void callback(e)) {
49 _onError = callback;
50 }
51
52 void _onClosed() {
53 _closed = true;
54 if (_clientCloseHandler != null) {
55 _clientCloseHandler();
56 }
57 }
58
59 bool _onSocketError(e) {
60 close();
61 if (_onError != null) {
62 _onError(e);
63 return true;
64 } else {
65 return false;
66 }
67 }
68
69 Socket _socket;
70 bool _closed = false;
71 Function _clientCloseHandler;
72 Function _onError;
73 }
74
75
76 class _SocketOutputStream
77 extends _BaseOutputStream implements OutputStream {
78 _SocketOutputStream(Socket socket)
79 : _socket = socket, _pendingWrites = new _BufferList();
80
81 bool write(List<int> buffer, [bool copyBuffer = true]) {
82 return _write(buffer, 0, buffer.length, copyBuffer);
83 }
84
85 bool writeFrom(List<int> buffer, [int offset = 0, int len]) {
86 return _write(
87 buffer, offset, (len == null) ? buffer.length - offset : len, true);
88 }
89
90 void flush() {
91 // Nothing to do on a socket output stream.
92 }
93
94 void close() {
95 if (_closing) return;
96 _closing = true;
97 if (!_pendingWrites.isEmpty) {
98 // Mark the socket for close when all data is written.
99 _socket._onWrite = _onWrite;
100 } else {
101 // Close the socket for writing.
102 _socket._closeWrite();
103 _closed = true;
104 // Invoke the callback asynchronously.
105 Timer.run(() {
106 if (_onClosed != null) _onClosed();
107 });
108 }
109 }
110
111 void destroy() {
112 _socket._onWrite = null;
113 _pendingWrites.clear();
114 _socket.close();
115 _closed = true;
116 }
117
118 bool get closed => _closed;
119
120 void set onNoPendingWrites(void callback()) {
121 _onNoPendingWrites = callback;
122 if (_onNoPendingWrites != null) {
123 _socket._onWrite = _onWrite;
124 }
125 }
126
127 void set onClosed(void callback()) {
128 _onClosed = callback;
129 }
130
131 bool _write(List<int> buffer, int offset, int len, bool copyBuffer) {
132 if (_closing || _closed) {
133 if (_error) return false;
134 _error = true;
135 var e = new StreamException.streamClosed();
136 if (_onError != null) {
137 _onError(e);
138 return false;
139 } else {
140 throw e;
141 }
142 }
143 int bytesWritten = 0;
144 if (_pendingWrites.isEmpty) {
145 // If nothing is buffered write as much as possible and buffer
146 // the rest.
147 try {
148 bytesWritten = _socket.writeList(buffer, offset, len);
149 if (bytesWritten == len) return true;
150 } catch (e) {
151 if (_error) return false;
152 _error = true;
153 if (_onError != null) {
154 _onError(e);
155 return false;
156 } else {
157 throw e;
158 }
159 }
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 if (_onError != null) _onError(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 destroy();
216 if (_error) return true;
217 if (_onError != null) {
218 _onError(e);
219 return true;
220 } else {
221 throw e;
222 }
223 }
224
225 Socket _socket;
226 _BufferList _pendingWrites;
227 Function _onNoPendingWrites;
228 Function _onClosed;
229 bool _closing = false;
230 bool _closed = false;
231 bool _error = false;
232 }
OLDNEW
« no previous file with comments | « sdk/lib/io/socket.dart ('k') | sdk/lib/io/stdio.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698