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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cc9ad943527479f6286d5f4e38f1357fb4c3140f |
| --- /dev/null |
| +++ b/sdk/lib/convert/line_splitter.dart |
| @@ -0,0 +1,90 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +part of dart.convert; |
| + |
| +/** |
| + * This class splits [String] values into individual lines. |
| + */ |
| +class LineSplitter extends Converter<String, List<String>> { |
| + List<String> convert(String data) { |
| + var lines = new List<String>(); |
| + |
| + _LineSplitterSink._addSlice(data, 0, data.length, true, lines.add); |
| + |
| + return lines; |
| + } |
| + |
| + StringConversionSink startChunkedConversion( |
| + ChunkedConversionSink<String> sink) { |
| + |
| + if (sink is! StringConversionSink) { |
| + sink = new StringConversionSink.from(sink); |
| + } |
| + return new _LineSplitterSink(sink); |
| + } |
| +} |
| + |
| +// TODO(floitsch): deal with utf8. |
| +class _LineSplitterSink extends StringConversionSinkBase { |
| + static const int _LF = 10; |
| + static const int _CR = 13; |
| + |
| + final StringConversionSink _sink; |
| + |
| + String _carry; |
| + |
| + _LineSplitterSink(this._sink); |
| + |
| + void addSlice(String chunk, int start, int end, bool isLast) { |
| + if(_carry != null) { |
|
Søren Gjesse
2013/08/12 12:57:27
Space between if and (.
|
| + chunk = _carry + chunk.substring(start, end); |
| + start = 0; |
| + end = chunk.length; |
| + _carry = null; |
| + } |
| + _carry = _addSlice(chunk, start, end, isLast, _sink.add); |
| + if(isLast) _sink.close(); |
|
Søren Gjesse
2013/08/12 12:57:27
Ditto.
|
| + } |
| + |
| + void close() { |
| + addSlice('', 0, 0, true); |
| + } |
| + |
| + static String _addSlice(String chunk, int start, int end, bool isLast, void adder(String val)) { |
|
Søren Gjesse
2013/08/12 12:57:27
Long line.
|
| + int pos = start; |
| + while (pos < end) { |
| + int skip = 0; |
| + int char = chunk.codeUnitAt(pos); |
| + if (char == _LF) { |
| + skip = 1; |
| + } else if (char == _CR) { |
| + skip = 1; |
| + if (pos + 1 < end) { |
| + if (chunk.codeUnitAt(pos + 1) == _LF) { |
| + skip = 2; |
| + } |
| + } else if (!isLast) { |
| + return chunk.substring(start, end); |
| + } |
| + } |
| + if (skip > 0) { |
| + adder(chunk.substring(start, pos)); |
| + start = pos = pos + skip; |
| + } else { |
| + pos++; |
| + } |
| + } |
| + if (pos != start) { |
| + var carry = chunk.substring(start, pos); |
| + if(isLast) { |
|
Søren Gjesse
2013/08/12 12:57:27
Space between if and (.
|
| + // Add remaining |
| + adder(carry); |
| + } else { |
| + return carry; |
| + } |
| + } |
| + return null; |
| + } |
| +} |