Utf16CodeUnitDecoder class
An Iterator<int> of codepoints built on an Iterator of UTF-16 code units. The parameters can override the default Unicode replacement character. Set the replacementCharacter to null to throw an ArgumentError rather than replace the bad value.
class Utf16CodeUnitDecoder implements Iterator<int> {
final _ListRangeIterator utf16CodeUnitIterator;
final int replacementCodepoint;
int _current = null;
Utf16CodeUnitDecoder(List<int> utf16CodeUnits, [int offset = 0, int length,
int this.replacementCodepoint =
UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
utf16CodeUnitIterator =
(new _ListRange(utf16CodeUnits, offset, length)).iterator;
Utf16CodeUnitDecoder.fromListRangeIterator(
_ListRangeIterator this.utf16CodeUnitIterator,
int this.replacementCodepoint);
Iterator<int> get iterator => this;
int get current => _current;
bool moveNext() {
_current = null;
if (!utf16CodeUnitIterator.moveNext()) return false;
int value = utf16CodeUnitIterator.current;
if (value < 0) {
if (replacementCodepoint != null) {
_current = replacementCodepoint;
} else {
throw new ArgumentError(
"Invalid UTF16 at ${utf16CodeUnitIterator.position}");
}
} else if (value < UNICODE_UTF16_RESERVED_LO ||
(value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
// transfer directly
_current = value;
} else if (value < UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
utf16CodeUnitIterator.moveNext()) {
// merge surrogate pair
int nextValue = utf16CodeUnitIterator.current;
if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
nextValue <= UNICODE_UTF16_RESERVED_HI) {
value = (value - UNICODE_UTF16_SURROGATE_UNIT_0_BASE) << 10;
value += UNICODE_UTF16_OFFSET +
(nextValue - UNICODE_UTF16_SURROGATE_UNIT_1_BASE);
_current = value;
} else {
if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_0_BASE &&
nextValue < UNICODE_UTF16_SURROGATE_UNIT_1_BASE) {
utf16CodeUnitIterator.backup();
}
if (replacementCodepoint != null) {
_current = replacementCodepoint;
} else {
throw new ArgumentError(
"Invalid UTF16 at ${utf16CodeUnitIterator.position}");
}
}
} else if (replacementCodepoint != null) {
_current = replacementCodepoint;
} else {
throw new ArgumentError(
"Invalid UTF16 at ${utf16CodeUnitIterator.position}");
}
return true;
}
}
Implements
Constructors
new Utf16CodeUnitDecoder(List<int> utf16CodeUnits, [int offset = 0, int length, int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) #
Utf16CodeUnitDecoder(List<int> utf16CodeUnits, [int offset = 0, int length,
int this.replacementCodepoint =
UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
utf16CodeUnitIterator =
(new _ListRange(utf16CodeUnits, offset, length)).iterator;
new Utf16CodeUnitDecoder.fromListRangeIterator(_ListRangeIterator utf16CodeUnitIterator, int replacementCodepoint) #
Utf16CodeUnitDecoder.fromListRangeIterator( _ListRangeIterator this.utf16CodeUnitIterator, int this.replacementCodepoint);
Properties
final _ListRangeIterator utf16CodeUnitIterator #
final _ListRangeIterator utf16CodeUnitIterator
Methods
bool moveNext() #
Moves to the next element. Returns true if current contains the next element. Returns false, if no element was left.
It is safe to invoke moveNext even when the iterator is already positioned after the last element. In this case moveNext has no effect.
bool moveNext() {
_current = null;
if (!utf16CodeUnitIterator.moveNext()) return false;
int value = utf16CodeUnitIterator.current;
if (value < 0) {
if (replacementCodepoint != null) {
_current = replacementCodepoint;
} else {
throw new ArgumentError(
"Invalid UTF16 at ${utf16CodeUnitIterator.position}");
}
} else if (value < UNICODE_UTF16_RESERVED_LO ||
(value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
// transfer directly
_current = value;
} else if (value < UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
utf16CodeUnitIterator.moveNext()) {
// merge surrogate pair
int nextValue = utf16CodeUnitIterator.current;
if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
nextValue <= UNICODE_UTF16_RESERVED_HI) {
value = (value - UNICODE_UTF16_SURROGATE_UNIT_0_BASE) << 10;
value += UNICODE_UTF16_OFFSET +
(nextValue - UNICODE_UTF16_SURROGATE_UNIT_1_BASE);
_current = value;
} else {
if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_0_BASE &&
nextValue < UNICODE_UTF16_SURROGATE_UNIT_1_BASE) {
utf16CodeUnitIterator.backup();
}
if (replacementCodepoint != null) {
_current = replacementCodepoint;
} else {
throw new ArgumentError(
"Invalid UTF16 at ${utf16CodeUnitIterator.position}");
}
}
} else if (replacementCodepoint != null) {
_current = replacementCodepoint;
} else {
throw new ArgumentError(
"Invalid UTF16 at ${utf16CodeUnitIterator.position}");
}
return true;
}