| 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 // Interface for decoders decoding binary data into string data. The | 5 // Interface for decoders decoding binary data into string data. The |
| 6 // decoder keeps track of line breaks during decoding. | 6 // decoder keeps track of line breaks during decoding. |
| 7 interface _StringDecoder { | 7 interface _StringDecoder { |
| 8 // Add more binary data to be decoded. The ownership of the buffer | 8 // Add more binary data to be decoded. The ownership of the buffer |
| 9 // is transfered to the decoder and the caller most not modify it any more. | 9 // is transfered to the decoder and the caller most not modify it any more. |
| 10 int write(List<int> buffer); | 10 int write(List<int> buffer); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 String toString() => "DecoderException: $message"; | 33 String toString() => "DecoderException: $message"; |
| 34 final String message; | 34 final String message; |
| 35 } | 35 } |
| 36 | 36 |
| 37 | 37 |
| 38 // Utility class for decoding UTF-8 from data delivered as a stream of | 38 // Utility class for decoding UTF-8 from data delivered as a stream of |
| 39 // bytes. | 39 // bytes. |
| 40 class _StringDecoderBase implements _StringDecoder { | 40 class _StringDecoderBase implements _StringDecoder { |
| 41 _StringDecoderBase() | 41 _StringDecoderBase() |
| 42 : _bufferList = new _BufferList(), | 42 : _bufferList = new _BufferList(), |
| 43 _result = new List<int>(), | 43 _result = new List<int>(), |
| 44 _lineBreakEnds = new Queue<int>(); | 44 _lineBreakEnds = new Queue<int>(); |
| 45 | 45 |
| 46 int write(List<int> buffer) { | 46 int write(List<int> buffer) { |
| 47 _bufferList.add(buffer); | 47 _bufferList.add(buffer); |
| 48 // Decode as many bytes into characters as possible. | 48 // Decode as many bytes into characters as possible. |
| 49 while (_bufferList.length > 0) { | 49 while (_bufferList.length > 0) { |
| 50 if (!_processNext()) { | 50 if (!_processNext()) { |
| 51 break; | 51 break; |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 return buffer.length; | 54 return buffer.length; |
| 55 } | 55 } |
| 56 | 56 |
| 57 bool isEmpty() { | 57 bool isEmpty() { |
| 58 return _result.isEmpty(); | 58 return _result.isEmpty(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 int get lineBreaks() => _lineBreaks; | 61 int get lineBreaks() => _lineBreaks; |
| 62 | 62 |
| 63 String get decoded() { | 63 String get decoded() { |
| 64 if (isEmpty()) return null; | 64 if (isEmpty()) return null; |
| 65 | 65 |
| 66 String result = new String.fromCharCodes(_result); | 66 String result; |
| 67 _charOffset += result.length; | 67 if (_resultOffset == 0) { |
| 68 result = new String.fromCharCodes(_result); |
| 69 } else { |
| 70 result = |
| 71 new String.fromCharCodes( |
| 72 _result.getRange(_resultOffset, _result.length - _resultOffset)); |
| 73 } |
| 68 while (!_lineBreakEnds.isEmpty() && _lineBreakEnds.first() < _charOffset) { | 74 while (!_lineBreakEnds.isEmpty() && _lineBreakEnds.first() < _charOffset) { |
| 69 _lineBreakEnds.removeFirst(); | 75 _lineBreakEnds.removeFirst(); |
| 70 _lineBreaks--; | 76 _lineBreaks--; |
| 71 } | 77 } |
| 72 _result = new List<int>(); | 78 _resetResult(); |
| 73 return result; | 79 return result; |
| 74 } | 80 } |
| 75 | 81 |
| 76 String get decodedLine() { | 82 String get decodedLine() { |
| 77 if (_lineBreakEnds.isEmpty()) return null; | 83 if (_lineBreakEnds.isEmpty()) return null; |
| 78 int lineEnd = _lineBreakEnds.removeFirst(); | 84 int lineEnd = _lineBreakEnds.removeFirst(); |
| 79 int terminationSequenceLength = 1; | 85 int terminationSequenceLength = 1; |
| 80 if (_result[lineEnd - _charOffset] == LF && | 86 if (_result[lineEnd - _charOffset] == LF && |
| 81 lineEnd > _charOffset && | 87 lineEnd > _charOffset && |
| 82 _result[lineEnd - _charOffset - 1] == CR) { | 88 _result[lineEnd - _charOffset - 1] == CR) { |
| 83 terminationSequenceLength = 2; | 89 terminationSequenceLength = 2; |
| 84 } | 90 } |
| 85 var lineLength = lineEnd - _charOffset - terminationSequenceLength + 1; | 91 var lineLength = |
| 86 String result = new String.fromCharCodes(_result.getRange(0, lineLength)); | 92 lineEnd - _charOffset - _resultOffset - terminationSequenceLength + 1; |
| 93 String result = |
| 94 new String.fromCharCodes(_result.getRange(_resultOffset, lineLength)); |
| 87 _lineBreaks--; | 95 _lineBreaks--; |
| 88 int removeCount = lineLength + terminationSequenceLength; | 96 _resultOffset += (lineLength + terminationSequenceLength); |
| 89 _result = _result.getRange(removeCount, _result.length - removeCount); | 97 if (_result.length == _resultOffset) _resetResult(); |
| 90 _charOffset = lineEnd + 1; | |
| 91 return result; | 98 return result; |
| 92 } | 99 } |
| 93 | 100 |
| 94 // Add another decoded character. | 101 // Add another decoded character. |
| 95 void addChar(int charCode) { | 102 void addChar(int charCode) { |
| 96 _result.add(charCode); | 103 _result.add(charCode); |
| 97 _charCount++; | 104 _charCount++; |
| 98 // Check for line ends (\r, \n and \r\n). | 105 // Check for line ends (\r, \n and \r\n). |
| 99 if (charCode == LF) { | 106 if (charCode == LF) { |
| 100 _recordLineBreakEnd(_charCount - 1); | 107 _recordLineBreakEnd(_charCount - 1); |
| 101 } else if (_lastCharCode == CR) { | 108 } else if (_lastCharCode == CR) { |
| 102 _recordLineBreakEnd(_charCount - 2); | 109 _recordLineBreakEnd(_charCount - 2); |
| 103 } | 110 } |
| 104 _lastCharCode = charCode; | 111 _lastCharCode = charCode; |
| 105 } | 112 } |
| 106 | 113 |
| 107 void _recordLineBreakEnd(int charPos) { | 114 void _recordLineBreakEnd(int charPos) { |
| 108 _lineBreakEnds.add(charPos); | 115 _lineBreakEnds.add(charPos); |
| 109 _lineBreaks++; | 116 _lineBreaks++; |
| 117 } |
| 118 |
| 119 void _resetResult() { |
| 120 _charOffset += _result.length; |
| 121 _result = new List<int>(); |
| 122 _resultOffset = 0; |
| 110 } | 123 } |
| 111 | 124 |
| 112 abstract bool _processNext(); | 125 abstract bool _processNext(); |
| 113 | 126 |
| 114 _BufferList _bufferList; | 127 _BufferList _bufferList; |
| 128 int _resultOffset = 0; |
| 115 List<int> _result; | 129 List<int> _result; |
| 116 int _lineBreaks = 0; // Number of line breaks in the current list. | 130 int _lineBreaks = 0; // Number of line breaks in the current list. |
| 117 // The positions of the line breaks are tracked in terms of absolute | 131 // The positions of the line breaks are tracked in terms of absolute |
| 118 // character positions from the begining of the decoded data. | 132 // character positions from the begining of the decoded data. |
| 119 Queue<int> _lineBreakEnds; // Character position of known line breaks. | 133 Queue<int> _lineBreakEnds; // Character position of known line breaks. |
| 120 int _charOffset = 0; // Character number of the first character in the list. | 134 int _charOffset = 0; // Character number of the first character in the list. |
| 121 int _charCount = 0; // Total number of characters decodes. | 135 int _charCount = 0; // Total number of characters decodes. |
| 122 int _lastCharCode = -1; | 136 int _lastCharCode = -1; |
| 123 | 137 |
| 124 final int LF = 10; | 138 final int LF = 10; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 InputStream _input; | 333 InputStream _input; |
| 320 String _encoding; | 334 String _encoding; |
| 321 _StringDecoder _decoder; | 335 _StringDecoder _decoder; |
| 322 bool _inputClosed = false; // Is the underlying input stream closed? | 336 bool _inputClosed = false; // Is the underlying input stream closed? |
| 323 bool _closed = false; // Is this stream closed. | 337 bool _closed = false; // Is this stream closed. |
| 324 bool _eof = false; // Has all data been read from the decoder? | 338 bool _eof = false; // Has all data been read from the decoder? |
| 325 var _clientDataHandler; | 339 var _clientDataHandler; |
| 326 var _clientLineHandler; | 340 var _clientLineHandler; |
| 327 var _clientCloseHandler; | 341 var _clientCloseHandler; |
| 328 } | 342 } |
| OLD | NEW |