Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #library("UnicodeCore"); | |
| 6 | |
| 7 /* | |
| 8 * Test for presence of bug related to the use of UTF-16 code units for | |
|
jat
2012/01/31 15:19:22
I'm not sure I would call it a bug -- it simply is
Dan Rice
2012/01/31 15:59:55
Since strings are immutable, you can at least do a
dcarlson
2012/01/31 22:11:38
The calculation is once, then cached.
| |
| 9 * Dart compiled to JS. | |
| 10 */ | |
| 11 bool _test16BitCodeUnit = null; | |
| 12 bool is16BitCodeUnit() { | |
| 13 if(_test16BitCodeUnit == null) { | |
| 14 _test16BitCodeUnit = (new String.fromCharCodes([0x1D11E])) == | |
|
jat
2012/01/31 15:19:22
I would have expected this to result in a 2-charac
Dan Rice
2012/01/31 15:59:55
Done.
dcarlson
2012/01/31 22:11:38
:)
| |
| 15 (new String.fromCharCodes([0xD11E])); | |
| 16 } | |
| 17 return _test16BitCodeUnit; | |
| 18 } | |
| 19 | |
| 20 | |
| 21 /** | |
| 22 * Invalid codepoints or encodings may be substituted with the value U+fffd. | |
| 23 */ | |
| 24 final int REPLACEMENT_CHARACTER_CODEPOINT = 0xfffd; | |
| 25 | |
| 26 /** | |
| 27 * Encode code points as UTF16 code units. | |
| 28 */ | |
| 29 List<int> codepointsToUtf16CodeUnits(List<int> codepoints, | |
| 30 [int start = 0, int length = -1]) { | |
|
jat
2012/01/31 15:19:22
Seems like null is a better "not-supplied" default
Dan Rice
2012/01/31 15:59:55
Maybe use length = null as the sentinel? The -1 m
dcarlson
2012/01/31 22:11:38
Done.
| |
| 31 List<int> codeUnitsBuffer = <int>[]; | |
| 32 int end = length >= 0 ? Math.min(codepoints.length, start + length) : | |
| 33 codepoints.length; | |
| 34 int i = start; | |
| 35 while (i < end) { | |
| 36 int value = codepoints[i++]; | |
| 37 if ((value >= 0 && value <0xd800) || (value >= 0xe000 && value <0x10000)) { | |
|
Dan Rice
2012/01/31 15:59:55
space after '<'
dcarlson
2012/01/31 22:11:38
Done.
| |
| 38 codeUnitsBuffer.add(value); | |
| 39 } else if (value >= 0x10000 && value < 0x110000){ | |
|
Dan Rice
2012/01/31 15:59:55
Space before '{'
dcarlson
2012/01/31 22:11:38
Done.
| |
| 40 int base = value - 0x10000; | |
| 41 codeUnitsBuffer.add(0xd800 + ((base & 0xffc00) >> 10)); | |
| 42 codeUnitsBuffer.add(0xdc00 + (base & 0x3ff)); | |
|
jat
2012/01/31 15:19:22
These ranges should be in constants rather than re
dcarlson
2012/01/31 22:11:38
Done.
| |
| 43 } else { | |
| 44 codeUnitsBuffer.add(REPLACEMENT_CHARACTER_CODEPOINT); | |
| 45 } | |
| 46 } | |
| 47 return codeUnitsBuffer; | |
| 48 } | |
| 49 | |
| 50 /** | |
| 51 * Decodes the utf16 codeunits to codepoints. | |
| 52 */ | |
| 53 List<int> utf16CodeUnitsToCodepoints(List<int> utf16CodeUnits, | |
| 54 [int start = 0, int length = - 1]) { | |
|
Dan Rice
2012/01/31 15:59:55
length sentinel
dcarlson
2012/01/31 22:11:38
Done.
| |
| 55 List<int> codepointBuffer = <int>[]; | |
| 56 | |
| 57 int end = length >= 0 ? | |
| 58 Math.min(utf16CodeUnits.length, start + length) : | |
| 59 utf16CodeUnits.length; | |
| 60 | |
| 61 int i = start; | |
| 62 // skip the first entry if it is a BOM. | |
| 63 if(end > 0 && utf16CodeUnits[0] == 0xfeff) { | |
|
jat
2012/01/31 15:19:22
If you are checking for BOM, do you want to also c
Dan Rice
2012/01/31 15:59:55
space before '('
dcarlson
2012/01/31 22:11:38
Not here. Only do this when encoding code units to
dcarlson
2012/01/31 22:11:38
Not when going from codepoint to code unit. The BO
| |
| 64 i++; | |
| 65 } | |
| 66 while (i < end) { | |
| 67 int value = utf16CodeUnits[i++]; | |
| 68 if (value >= 0x0) { | |
| 69 if (value < 0xd800 || (value >= 0xe000 && value <= 0xffff)) { | |
| 70 // transfer directly | |
| 71 codepointBuffer.add(value); | |
| 72 } else if (value < 0xdc00 && i < end) { | |
| 73 // merge surrogate pair | |
| 74 value = (value - 0xd800) * 0x400; | |
|
Dan Rice
2012/01/31 15:59:55
can use '<< 10' instead of '* 0x400'
dcarlson
2012/01/31 22:11:38
Done.
| |
| 75 int nextValue = utf16CodeUnits[i++]; | |
| 76 if (nextValue >= 0xdc00 && nextValue < 0xe000) { | |
| 77 value += 0x10000 + (nextValue - 0xdc00); | |
| 78 codepointBuffer.add(value); | |
| 79 } else { | |
| 80 if (nextValue >= 0xd800 && nextValue < 0xdc00) i--; | |
|
Dan Rice
2012/01/31 15:59:55
better not to put the 'then' clause on same line
dcarlson
2012/01/31 22:11:38
Done.
| |
| 81 codepointBuffer.add(REPLACEMENT_CHARACTER_CODEPOINT); | |
| 82 continue; | |
| 83 } | |
| 84 } else { | |
| 85 codepointBuffer.add(REPLACEMENT_CHARACTER_CODEPOINT); | |
| 86 continue; | |
| 87 } | |
| 88 } else { | |
| 89 codepointBuffer.add(REPLACEMENT_CHARACTER_CODEPOINT); | |
| 90 continue; | |
| 91 } | |
| 92 } | |
| 93 return codepointBuffer; | |
| 94 } | |
| OLD | NEW |