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; |