OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 class PbInputStreamReader implements PbReader { |
| 6 |
| 7 PbInputStreamReader(InputStream this._inputStream) |
| 8 : _buffer = new PbByteBuffer(); |
| 9 |
| 10 bool get closed() => _inputStream.closed && _buffer.isEmpty; |
| 11 |
| 12 int get position() => _position; |
| 13 |
| 14 Future<int> readByte() => |
| 15 readBytes(1).transform((List<int> b) => b.length > 0 ? b[0] : null); |
| 16 |
| 17 Future<List<int>> readBytes([int count = -1]) { |
| 18 if (_completer != null) throw new PbBufferBusyStateException(); |
| 19 if (count == 0) { |
| 20 return new Future.immediate(<int>[]); |
| 21 } else if ((count > 0 && _buffer.length >= count) || _inputStream.closed) { |
| 22 return new Future.immediate(_buffer.readBytes(count)); |
| 23 } else { |
| 24 _completer = new Completer<List<int>>(); |
| 25 _bytesToReturn = count; |
| 26 _bytesToRead = (count >= 0) && (_bytesToRead >= 0) ? |
| 27 Math.max(count, _bytesToRead) : -1; |
| 28 _readIntoPbByteBuffer(); |
| 29 return _completer.future; |
| 30 } |
| 31 } |
| 32 |
| 33 void setReadAhead([int count]) { |
| 34 _bytesToRead = (count >= 0) && (_bytesToRead >= 0) ? |
| 35 Math.max(count, _bytesToRead) : -1; |
| 36 _readIntoPbByteBuffer(); |
| 37 } |
| 38 |
| 39 void _fulfillRequest() { |
| 40 if (_completer != null && |
| 41 ((_bytesToReturn > 0 && _buffer.length >= _bytesToReturn) || |
| 42 _inputStream.closed)) { |
| 43 Completer c = _completer; |
| 44 _completer = null; |
| 45 |
| 46 List<int> bytes = _buffer.readBytes(_bytesToReturn); |
| 47 _position += bytes.length; |
| 48 c.complete(bytes); |
| 49 } |
| 50 } |
| 51 |
| 52 void _handleDataReadToLength() { |
| 53 int availableBytes = _inputStream.available(); |
| 54 if (availableBytes > 0) { |
| 55 int readSize = Math.min(availableBytes, _bytesToRead); |
| 56 List<int> data = _inputStream.read(readSize); |
| 57 if (null != data) { |
| 58 _buffer.add(data); |
| 59 _bytesToRead -= data.length; |
| 60 if (_bytesToRead == 0) { |
| 61 _reset(); |
| 62 } |
| 63 } |
| 64 } |
| 65 _fulfillRequest(); |
| 66 } |
| 67 |
| 68 void _handleDataReadToEnd() { |
| 69 if (_inputStream.available() > 0) { |
| 70 List<int> data = _inputStream.read(); |
| 71 if (null !== data) { |
| 72 _buffer.add(data); |
| 73 } |
| 74 } |
| 75 _fulfillRequest(); |
| 76 } |
| 77 |
| 78 void _handleClose() { |
| 79 _reset(); |
| 80 _fulfillRequest(); |
| 81 } |
| 82 |
| 83 void _handleError(Exception e) { |
| 84 _reset(); |
| 85 _completer.completeException(e); |
| 86 } |
| 87 |
| 88 /** |
| 89 * Reads the bytes requested and mark their availability with the |
| 90 * returned Future. |
| 91 */ |
| 92 void _readIntoPbByteBuffer() { |
| 93 if(_bytesToRead < 0) { |
| 94 _inputStream.onClosed = _handleClose; |
| 95 _inputStream.onError = _handleError; |
| 96 _inputStream.onData = _handleDataReadToEnd; |
| 97 } else if (_bytesToRead > 0) { |
| 98 _inputStream.onClosed = _handleClose; |
| 99 _inputStream.onError = _handleError; |
| 100 _inputStream.onData = _handleDataReadToLength; |
| 101 } |
| 102 } |
| 103 |
| 104 void _reset() { |
| 105 _inputStream.onData = null; |
| 106 _inputStream.onClosed = null; |
| 107 _inputStream.onError = null; |
| 108 } |
| 109 |
| 110 InputStream _inputStream; |
| 111 PbByteBuffer _buffer; |
| 112 int _bytesToReturn; |
| 113 int _bytesToRead = 0; |
| 114 Completer<List<int>> _completer; |
| 115 int _position = 0; |
| 116 } |
OLD | NEW |