blob: 3fc066ac88e227b114afea6e6621df8dde3f6397 [file] [log] [blame]
// 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.util;
import 'constants.dart';
import 'list_range.dart';
import 'utf_16_code_unit_decoder.dart';
/// Decodes the utf16 codeunits to codepoints.
List<int> utf16CodeUnitsToCodepoints(List<int> utf16CodeUnits,
[int offset = 0,
int length,
int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
var source = (ListRange(utf16CodeUnits, offset, length)).iterator;
var decoder =
Utf16CodeUnitDecoder.fromListRangeIterator(source, replacementCodepoint);
var codepoints = List<int>(source.remaining);
var i = 0;
while (decoder.moveNext()) {
codepoints[i++] = decoder.current;
}
if (i == codepoints.length) {
return codepoints;
} else {
var codepointTrunc = List<int>(i);
codepointTrunc.setRange(0, i, codepoints);
return codepointTrunc;
}
}
/// Encode code points as UTF16 code units.
List<int> codepointsToUtf16CodeUnits(List<int> codepoints,
[int offset = 0,
int length,
int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
var listRange = ListRange(codepoints, offset, length);
var encodedLength = 0;
for (var value in listRange) {
if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
(value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
encodedLength++;
} else if (value > UNICODE_PLANE_ONE_MAX &&
value <= UNICODE_VALID_RANGE_MAX) {
encodedLength += 2;
} else {
encodedLength++;
}
}
var codeUnitsBuffer = List<int>(encodedLength);
var j = 0;
for (var value in listRange) {
if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
(value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
codeUnitsBuffer[j++] = value;
} else if (value > UNICODE_PLANE_ONE_MAX &&
value <= UNICODE_VALID_RANGE_MAX) {
var base = value - UNICODE_UTF16_OFFSET;
codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_0_BASE +
((base & UNICODE_UTF16_HI_MASK) >> 10);
codeUnitsBuffer[j++] =
UNICODE_UTF16_SURROGATE_UNIT_1_BASE + (base & UNICODE_UTF16_LO_MASK);
} else if (replacementCodepoint != null) {
codeUnitsBuffer[j++] = replacementCodepoint;
} else {
throw ArgumentError('Invalid encoding');
}
}
return codeUnitsBuffer;
}