| Index: mojo/public/dart/third_party/utf/lib/src/utf_16_code_unit_decoder.dart
|
| diff --git a/mojo/public/dart/third_party/utf/lib/src/utf_16_code_unit_decoder.dart b/mojo/public/dart/third_party/utf/lib/src/utf_16_code_unit_decoder.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a0a4b3c386c99fa7f1f703729d92664e7240291b
|
| --- /dev/null
|
| +++ b/mojo/public/dart/third_party/utf/lib/src/utf_16_code_unit_decoder.dart
|
| @@ -0,0 +1,83 @@
|
| +// Copyright (c) 2012, 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.
|
| +
|
| +library utf.utf_16_code_unit_decoder;
|
| +
|
| +import 'constants.dart';
|
| +import 'list_range.dart';
|
| +
|
| +/**
|
| + * 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> {
|
| + // TODO(kevmoo): should this field be private?
|
| + 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;
|
| + }
|
| +}
|
| +
|
|
|