Chromium Code Reviews| Index: sdk/lib/convert/line_splitter.dart |
| diff --git a/sdk/lib/convert/line_splitter.dart b/sdk/lib/convert/line_splitter.dart |
| index 0af2f2f63dd59c0a01b438c1008a9a60dcdb5e82..1501c439709329da63d838addee6bb7d9badadab 100644 |
| --- a/sdk/lib/convert/line_splitter.dart |
| +++ b/sdk/lib/convert/line_splitter.dart |
| @@ -27,26 +27,9 @@ class LineSplitter extends Converter<String, List<String>> { |
| /// `lines.substring(start, end)`. The [start] and [end] values must |
| /// specify a valid sub-range of [lines] |
| /// (`0 <= start <= end <= lines.length`). |
| - static Iterable<String> split(String lines, [int start = 0, int end]) sync* { |
| + static Iterable<String> split(String lines, [int start = 0, int end]) { |
| end = RangeError.checkValidRange(start, end, lines.length); |
| - int sliceStart = start; |
| - int char = 0; |
| - for (int i = start; i < end; i++) { |
| - int previousChar = char; |
| - char = lines.codeUnitAt(i); |
| - if (char != _CR) { |
| - if (char != _LF) continue; |
| - if (previousChar == _CR) { |
| - sliceStart = i + 1; |
| - continue; |
| - } |
| - } |
| - yield lines.substring(sliceStart, i); |
| - sliceStart = i + 1; |
| - } |
| - if (sliceStart < end) { |
| - yield lines.substring(sliceStart, end); |
| - } |
| + return new _LineIterable(lines, start, end); |
| } |
| List<String> convert(String data) => split(data).toList(); |
| @@ -59,6 +42,54 @@ class LineSplitter extends Converter<String, List<String>> { |
| } |
| } |
| +class _LineIterable extends Iterable<String> { |
| + final String _string; |
| + final int _start; |
| + final int _end; |
| + _LineIterable(this._string, this._start, this._end); |
| + Iterator<String> get iterator => new _LineIterator(_string, _start, _end); |
| + |
| + bool get isEmpty => _start < _end; |
| + bool get isNotEmpty => _start >= end; |
| +} |
| + |
| +class _LineIterator implements Iterator<String> { |
| + final String _string; |
| + final int _end; |
| + int _index; |
| + String _current; |
| + _LineIterator(this._string, this._index, this._end); |
| + |
| + String get current => _current; |
| + |
| + bool moveNext() { |
| + if (_index < _end) { |
| + int terminatorLength = 1; |
| + int i = _index; |
| + findEnd: { |
| + while (i < _end) { |
| + int char = _string.codeUnitAt(i++); |
| + if (char != _LF) { |
| + if (char != _CR) continue; |
| + // Break on CR or CR+LF |
|
floitsch
2016/03/08 12:35:34
Finish with "."
|
| + if (i < _end && _string.codeUnitAt(i) == _LF) { |
| + terminatorLength = 2; |
| + i++; |
| + } |
| + } |
| + break findEnd; |
| + } |
| + terminatorLength = 0; // Terminated by the end, not a char. |
| + } |
| + _current = _string.substring(_index, i - terminatorLength); |
| + _index = i; |
| + return true; |
| + } |
| + _current = null; |
| + return false; |
| + } |
| +} |
| + |
| // TODO(floitsch): deal with utf8. |
| class _LineSplitterSink extends StringConversionSinkBase { |
| final StringConversionSink _sink; |