| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 class SocketInputStream implements InputStream { | 5 class SocketInputStream implements InputStream { |
| 6 SocketInputStream(Socket socket) { | 6 SocketInputStream(Socket socket) { |
| 7 _socket = socket; | 7 _socket = socket; |
| 8 _buffer = null; | |
| 9 } | 8 } |
| 10 | 9 |
| 11 bool read(List<int> buffer, int offset, int len, void callback()) { | 10 List<int> read([int len]) { |
| 12 // Read data just out of the buffer. | 11 int bytesToRead = available(); |
| 13 if (_buffer !== null && len <= _buffer.length) { | 12 if (bytesToRead == 0) return null; |
| 14 buffer.copyFrom(_buffer, 0, offset, len); | 13 if (len != null) { |
| 15 int remainder = _buffer.length - len; | 14 if (len <= 0) { |
| 16 if (remainder > 0) { | 15 throw new StreamException("Illegal length $len"); |
| 17 List<int> newBuffer = new List<int>(remainder); | 16 } else if (bytesToRead > len) { |
| 18 newBuffer.copyFrom(_buffer, 0, len, remainder); | 17 bytesToRead = len; |
| 19 _buffer = newBuffer; | |
| 20 } else { | |
| 21 _buffer = null; | |
| 22 } | 18 } |
| 23 return true; | |
| 24 } | 19 } |
| 25 // Read data out of the buffer if available and from the socket. | 20 List<int> buffer = new List<int>(bytesToRead); |
| 26 else { | 21 int bytesRead = _socket.readList(buffer, 0, bytesToRead); |
| 27 int bytesRead = 0; | 22 if (bytesRead < bytesToRead) { |
| 28 if (_buffer !== null) { | 23 List<int> newBuffer = new List<int>(bytesRead); |
| 29 buffer.copyFrom(_buffer, offset, 0, _buffer.length); | 24 newBuffer.copyFrom(buffer, 0, 0, bytesRead); |
| 30 bytesRead = _buffer.length; | 25 return newBuffer; |
| 31 _buffer = null; | 26 } else { |
| 32 } | 27 return buffer; |
| 33 | |
| 34 bytesRead += | |
| 35 _socket.readList(buffer, offset + bytesRead, len - bytesRead); | |
| 36 | |
| 37 if (bytesRead == len) { | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 void doRead() { | |
| 42 bytesRead += | |
| 43 _socket.readList(buffer, offset + bytesRead, len - bytesRead); | |
| 44 if (bytesRead < len) { | |
| 45 _socket.setDataHandler(doRead); | |
| 46 } else { | |
| 47 assert(bytesRead == len); | |
| 48 _socket.setDataHandler(null); | |
| 49 if (callback !== null) { | |
| 50 callback(); | |
| 51 } | |
| 52 } | |
| 53 } | |
| 54 | |
| 55 _socket.setDataHandler(doRead); | |
| 56 return false; | |
| 57 } | 28 } |
| 58 } | 29 } |
| 59 | 30 |
| 60 int _matchPattern(List<int> buffer, List<int> pattern, int start) { | 31 int readInto(List<int> buffer, int offset, int len) { |
| 61 int j; | 32 if (offset == null) offset = 0; |
| 62 if (pattern.length > buffer.length) { | 33 if (len == null) len = buffer.length; |
| 63 return -1; | 34 if (offset < 0) throw new StreamException("Illegal offset $offset"); |
| 64 } | 35 if (len < 0) throw new StreamException("Illegal length $len"); |
| 65 for (int i = start; i < (buffer.length - pattern.length + 1); i++) { | 36 return _socket.readList(buffer, offset, len); |
| 66 for (j = 0; j < pattern.length; j++) { | |
| 67 if (buffer[i + j] != pattern[j]) { | |
| 68 break; | |
| 69 } | |
| 70 } | |
| 71 if (j == pattern.length) { | |
| 72 return i; | |
| 73 } | |
| 74 } | |
| 75 return -1; | |
| 76 } | 37 } |
| 77 | 38 |
| 78 /* | 39 int available() { |
| 79 * Appends the newBuffer to the buffer (if available), sets the buffer to | 40 return _socket.available(); |
| 80 * null, and returns the merged buffer. | |
| 81 */ | |
| 82 List<int> _getBufferedData(List<int> newBuffer, int appendingBufferSpace) { | |
| 83 List<int> buffer; | |
| 84 int newDataStart = 0; | |
| 85 if (_buffer !== null) { | |
| 86 buffer = new List<int>(_buffer.length + appendingBufferSpace); | |
| 87 buffer.copyFrom(_buffer, 0, 0, _buffer.length); | |
| 88 newDataStart = _buffer.length; | |
| 89 _buffer = null; | |
| 90 } else { | |
| 91 buffer = new List<int>(appendingBufferSpace); | |
| 92 } | |
| 93 buffer.copyFrom(newBuffer, 0, newDataStart, appendingBufferSpace); | |
| 94 return buffer; | |
| 95 } | 41 } |
| 96 | 42 |
| 97 void readUntil(List<int> pattern, void callback(List<int> resultBuffer)) { | 43 void set dataHandler(void callback()) { |
| 98 void doRead() { | 44 _socket.setDataHandler(callback); |
| 99 List<int> newBuffer; | 45 } |
| 100 int available = _socket.available(); | |
| 101 if (available > 0) { | |
| 102 List<int> buffer = new List<int>(available); | |
| 103 int result = _socket.readList(buffer, 0, buffer.length); | |
| 104 if (result > 0) { | |
| 105 // TODO(hpayer): Avoid copying of data before pattern matching. | |
| 106 newBuffer = _getBufferedData(buffer, result); | |
| 107 } | |
| 108 } else if (_buffer != null) { | |
| 109 newBuffer = _buffer; | |
| 110 } else { | |
| 111 _socket.setDataHandler(doRead); | |
| 112 return; | |
| 113 } | |
| 114 | 46 |
| 115 int index = _matchPattern(newBuffer, pattern, 0); | 47 void set closeHandler(void callback()) { |
| 116 // If pattern was found return the data including pattern and store the | 48 _socket.setCloseHandler(callback); |
| 117 // remainder in the buffer. | 49 } |
| 118 if (index != -1) { | |
| 119 int finalBufferSize = index + pattern.length; | |
| 120 List<int> finalBuffer = new List<int>(finalBufferSize); | |
| 121 finalBuffer.copyFrom(newBuffer, 0, 0, finalBufferSize); | |
| 122 if (finalBufferSize < newBuffer.length) { | |
| 123 List<int> remainder = | |
| 124 new List<int>(newBuffer.length - finalBufferSize); | |
| 125 remainder.copyFrom(newBuffer, finalBufferSize, 0, remainder.length); | |
| 126 _buffer = remainder; | |
| 127 } else { | |
| 128 _buffer = null; | |
| 129 } | |
| 130 _socket.setDataHandler(null); | |
| 131 callback(finalBuffer); | |
| 132 } else { | |
| 133 _buffer = newBuffer; | |
| 134 _socket.setDataHandler(doRead); | |
| 135 } | |
| 136 } | |
| 137 | 50 |
| 138 // Register callback for data available. | 51 void set errorHandler(void callback()) { |
| 139 _socket.setDataHandler(doRead); | 52 _socket.setErrorHandler(callback); |
| 140 | |
| 141 // If data is already buffered schedule a data available callback. | |
| 142 if (_buffer != null) { | |
| 143 _socket._scheduleEvent(_SocketBase._IN_EVENT); | |
| 144 } | |
| 145 } | 53 } |
| 146 | 54 |
| 147 Socket _socket; | 55 Socket _socket; |
| 148 | |
| 149 /* | |
| 150 * Read and readUntil read data out of that buffer first before reading new | |
| 151 * data out of the socket. | |
| 152 */ | |
| 153 List<int> _buffer; | |
| 154 } | 56 } |
| 155 | 57 |
| 58 |
| 156 class SocketOutputStream implements OutputStream { | 59 class SocketOutputStream implements OutputStream { |
| 157 SocketOutputStream(Socket socket) { | 60 SocketOutputStream(Socket socket) : _socket = socket; |
| 158 _socket = socket; | |
| 159 } | |
| 160 | 61 |
| 161 bool write(List<int> buffer, int offset, int len, void callback()) { | 62 bool write(List<int> buffer, int offset, int len, void callback()) { |
| 162 int bytesWritten = _socket.writeList(buffer, offset, len); | 63 int bytesWritten = _socket.writeList(buffer, offset, len); |
| 163 | 64 |
| 164 void finishWrite() { | 65 void finishWrite() { |
| 165 bytesWritten += _socket.writeList( | 66 bytesWritten += _socket.writeList( |
| 166 buffer, offset + bytesWritten, len - bytesWritten); | 67 buffer, offset + bytesWritten, len - bytesWritten); |
| 167 if (bytesWritten < len) { | 68 if (bytesWritten < len) { |
| 168 _socket.setWriteHandler(finishWrite); | 69 _socket.setWriteHandler(finishWrite); |
| 169 } else { | 70 } else { |
| 170 assert(bytesWritten == len); | 71 assert(bytesWritten == len); |
| 171 if (callback !== null) { | 72 if (callback !== null) { |
| 172 callback(); | 73 callback(); |
| 173 } | 74 } |
| 174 } | 75 } |
| 175 } | 76 } |
| 176 | 77 |
| 177 if (bytesWritten == len) { | 78 if (bytesWritten == len) { |
| 178 return true; | 79 return true; |
| 179 } | 80 } |
| 180 _socket.setWriteHandler(finishWrite); | 81 _socket.setWriteHandler(finishWrite); |
| 181 return false; | 82 return false; |
| 182 } | 83 } |
| 183 | 84 |
| 184 Socket _socket; | 85 Socket _socket; |
| 185 } | 86 } |
| OLD | NEW |