Index: sdk/lib/utf/utf8.dart |
diff --git a/sdk/lib/utf/utf8.dart b/sdk/lib/utf/utf8.dart |
index fff010bdb5fcc5ba7c12502bc514a9678e47dae0..4bf216f8095ea5b657e82409b523a2b08546523a 100644 |
--- a/sdk/lib/utf/utf8.dart |
+++ b/sdk/lib/utf/utf8.dart |
@@ -86,7 +86,7 @@ List<int> codepointsToUtf8( |
} |
} |
- List<int> encoded = new List<int>(encodedLength); |
+ List<int> encoded = new List<int>.fixedLength(encodedLength); |
int insertAt = 0; |
for (int value in source) { |
if (value < 0 || value > UNICODE_VALID_RANGE_MAX) { |
@@ -129,7 +129,9 @@ List<int> utf8ToCodepoints( |
* provides an iterator on demand and the iterator will only translate bytes |
* as requested by the user of the iterator. (Note: results are not cached.) |
*/ |
-class IterableUtf8Decoder implements Iterable<int> { |
+// TODO(floitsch): Consider removing the extend and switch to implements since |
+// that's cheaper to allocate. |
+class IterableUtf8Decoder extends Iterable<int> { |
final List<int> bytes; |
final int offset; |
final int length; |
@@ -138,8 +140,8 @@ class IterableUtf8Decoder implements Iterable<int> { |
IterableUtf8Decoder(this.bytes, [this.offset = 0, this.length = null, |
this.replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]); |
- Utf8Decoder iterator() => new Utf8Decoder(bytes, offset, length, |
- replacementCodepoint); |
+ Utf8Decoder get iterator => |
+ new Utf8Decoder(bytes, offset, length, replacementCodepoint); |
} |
/** |
@@ -153,55 +155,63 @@ class IterableUtf8Decoder implements Iterable<int> { |
class Utf8Decoder implements Iterator<int> { |
final _ListRangeIterator utf8EncodedBytesIterator; |
final int replacementCodepoint; |
+ int _current = null; |
Utf8Decoder(List<int> utf8EncodedBytes, [int offset = 0, int length, |
this.replacementCodepoint = |
UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) : |
- utf8EncodedBytesIterator = (new _ListRange(utf8EncodedBytes, offset, |
- length)).iterator(); |
+ utf8EncodedBytesIterator = |
+ (new _ListRange(utf8EncodedBytes, offset, length)).iterator; |
Utf8Decoder._fromListRangeIterator(_ListRange source, [ |
this.replacementCodepoint = |
UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) : |
- utf8EncodedBytesIterator = source.iterator(); |
+ utf8EncodedBytesIterator = source.iterator; |
/** Decode the remaininder of the characters in this decoder |
* into a [List<int>]. |
*/ |
List<int> decodeRest() { |
- List<int> codepoints = new List<int>(utf8EncodedBytesIterator.remaining); |
+ List<int> codepoints = new List<int>.fixedLength(utf8EncodedBytesIterator.remaining); |
int i = 0; |
- while (hasNext) { |
- codepoints[i++] = next(); |
+ while (moveNext()) { |
+ codepoints[i++] = current; |
} |
if (i == codepoints.length) { |
return codepoints; |
} else { |
- List<int> truncCodepoints = new List<int>(i); |
+ List<int> truncCodepoints = new List<int>.fixedLength(i); |
truncCodepoints.setRange(0, i, codepoints); |
return truncCodepoints; |
} |
} |
- bool get hasNext => utf8EncodedBytesIterator.hasNext; |
+ int get current => _current; |
- int next() { |
- int value = utf8EncodedBytesIterator.next(); |
+ bool moveNext() { |
+ _current = null; |
+ |
+ if (!utf8EncodedBytesIterator.moveNext()) return false; |
+ |
+ int value = utf8EncodedBytesIterator.current; |
int additionalBytes = 0; |
if (value < 0) { |
if (replacementCodepoint != null) { |
- return replacementCodepoint; |
+ _current = replacementCodepoint; |
+ return true; |
} else { |
throw new ArgumentError( |
"Invalid UTF8 at ${utf8EncodedBytesIterator.position}"); |
} |
} else if (value <= _UTF8_ONE_BYTE_MAX) { |
- return value; |
+ _current = value; |
+ return true; |
} else if (value < _UTF8_FIRST_BYTE_OF_TWO_BASE) { |
if (replacementCodepoint != null) { |
- return replacementCodepoint; |
+ _current = replacementCodepoint; |
+ return true; |
} else { |
throw new ArgumentError( |
"Invalid UTF8 at ${utf8EncodedBytesIterator.position}"); |
@@ -222,14 +232,15 @@ class Utf8Decoder implements Iterator<int> { |
value -= _UTF8_FIRST_BYTE_OF_SIX_BASE; |
additionalBytes = 5; |
} else if (replacementCodepoint != null) { |
- return replacementCodepoint; |
+ _current = replacementCodepoint; |
+ return true; |
} else { |
throw new ArgumentError( |
"Invalid UTF8 at ${utf8EncodedBytesIterator.position}"); |
} |
int j = 0; |
- while (j < additionalBytes && utf8EncodedBytesIterator.hasNext) { |
- int nextValue = utf8EncodedBytesIterator.next(); |
+ while (j < additionalBytes && utf8EncodedBytesIterator.moveNext()) { |
+ int nextValue = utf8EncodedBytesIterator.current; |
if (nextValue > _UTF8_ONE_BYTE_MAX && |
nextValue < _UTF8_FIRST_BYTE_OF_TWO_BASE) { |
value = ((value << 6) | (nextValue & _UTF8_LO_SIX_BIT_MASK)); |
@@ -251,9 +262,11 @@ class Utf8Decoder implements Iterator<int> { |
(additionalBytes == 3 && value > _UTF8_THREE_BYTE_MAX); |
bool inRange = value <= UNICODE_VALID_RANGE_MAX; |
if (validSequence && nonOverlong && inRange) { |
- return value; |
+ _current = value; |
+ return true; |
} else if (replacementCodepoint != null) { |
- return replacementCodepoint; |
+ _current = replacementCodepoint; |
+ return true; |
} else { |
throw new ArgumentError( |
"Invalid UTF8 at ${utf8EncodedBytesIterator.position - j}"); |