Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Side by Side Diff: utils/string_encoding/UnicodeCore.dart

Issue 9233041: String encoding utility methods and tests for Unicode, UTF-8, -16 and -32. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: remove notes to self Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, 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
9 * Dart compiled to JS.
10 */
11 bool _test16BitCodeUnit = null;
12 // TODO is16BitCodeUnit() is used to work around a bug with frog/dartc
13 // (http://code.google.com/p/dart/issues/detail?id=1357). Consider
14 // removing after this issue is resolved.
15 bool is16BitCodeUnit() {
16 if (_test16BitCodeUnit == null) {
17 _test16BitCodeUnit = (new String.fromCharCodes([0x1D11E])) ==
18 (new String.fromCharCodes([0xD11E]));
19 }
20 return _test16BitCodeUnit;
21 }
22
23
24 /**
25 * Invalid codepoints or encodings may be substituted with the value U+fffd.
26 */
27 final int UNICODE_REPLACEMENT_CHARACTER_CODEPOINT = 0xfffd;
28 final int UNICODE_BOM = 0xfeff;
29 final int UNICODE_UTF_BOM_LO = 0xff;
30 final int UNICODE_UTF_BOM_HI = 0xfe;
31
32 final int UNICODE_BYTE_ZERO_MASK = 0xff;
33 final int UNICODE_BYTE_ONE_MASK = 0xff00;
34 final int UNICODE_VALID_RANGE_MAX = 0x10ffff;
35 final int UNICODE_PLANE_ONE_MAX = 0xffff;
36 final int UNICODE_UTF16_RESERVED_LO = 0xd800;
37 final int UNICODE_UTF16_RESERVED_HI = 0xdfff;
38 final int UNICODE_UTF16_OFFSET = 0x10000;
39 final int UNICODE_UTF16_SURROGATE_UNIT_0_BASE = 0xd800;
40 final int UNICODE_UTF16_SURROGATE_UNIT_1_BASE = 0xdc00;
41 final int UNICODE_UTF16_HI_MASK = 0xffc00;
42 final int UNICODE_UTF16_LO_MASK = 0x3ff;
43
44 /**
45 * Encode code points as UTF16 code units.
Søren Gjesse 2012/02/01 11:25:25 Please be consistent with UTF16/utf16 in comments.
dcarlson 2012/02/01 22:18:46 Done. I went ahead and made sure all the variants
46 */
47 List<int> codepointsToUtf16CodeUnits(List<int> codepoints,
48 [int start = 0, int length = null]) {
49 if (!(start >= 0)) {
50 throw new IllegalArgumentException("start");
51 }
52
53 if (!(length == null || length >= 0)) {
54 throw new IllegalArgumentException("length");
55 }
56
57 int end = length != null ?
58 Math.min(codepoints.length, start + length) :
59 codepoints.length;
60
61 List<int> codeUnitsBuffer = <int>[];
62 int i = start;
63 while (i < end) {
64 int value = codepoints[i++];
65 if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
66 (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
67 codeUnitsBuffer.add(value);
68 } else if (value > UNICODE_PLANE_ONE_MAX &&
69 value <= UNICODE_VALID_RANGE_MAX) {
70 int base = value - UNICODE_UTF16_OFFSET;
71 codeUnitsBuffer.add(UNICODE_UTF16_SURROGATE_UNIT_0_BASE +
72 ((base & UNICODE_UTF16_HI_MASK) >> 10));
73 codeUnitsBuffer.add(UNICODE_UTF16_SURROGATE_UNIT_1_BASE +
74 (base & UNICODE_UTF16_LO_MASK));
75 } else {
76 codeUnitsBuffer.add(UNICODE_REPLACEMENT_CHARACTER_CODEPOINT);
77 }
78 }
79 return codeUnitsBuffer;
80 }
81
82 /**
83 * Decodes the utf16 codeunits to codepoints.
84 */
85 List<int> utf16CodeUnitsToCodepoints(List<int> utf16CodeUnits,
86 [int start = 0, int length = null]) {
Søren Gjesse 2012/02/01 11:25:25 Normally we don't split argument lists like this.
dcarlson 2012/02/01 22:18:46 Not always (other lines), but done with a simple l
87 if (!(start >= 0)) {
88 throw new IllegalArgumentException("start");
89 }
90
91 if (!(length == null || length >= 0)) {
92 throw new IllegalArgumentException("length");
93 }
94
95 int end = length != null ?
96 Math.min(utf16CodeUnits.length, start + length) :
97 utf16CodeUnits.length;
98
99 List<int> codepointBuffer = <int>[];
100 int i = start;
101 // skip the first entry if it is a BOM.
102 if (end > 0 && utf16CodeUnits[0] == UNICODE_BOM) {
103 i++;
104 }
105 while (i < end) {
106 int value = utf16CodeUnits[i++];
107 if (value < 0) {
108 codepointBuffer.add(UNICODE_REPLACEMENT_CHARACTER_CODEPOINT);
109 continue;
110 }
111 if (value < UNICODE_UTF16_RESERVED_LO ||
112 (value > UNICODE_UTF16_RESERVED_HI &&
113 value <= UNICODE_PLANE_ONE_MAX)) {
114 // transfer directly
115 codepointBuffer.add(value);
116 } else if (value < UNICODE_UTF16_SURROGATE_UNIT_1_BASE && i < end) {
117 // merge surrogate pair
118 value = (value - UNICODE_UTF16_SURROGATE_UNIT_0_BASE) << 10;
119 int nextValue = utf16CodeUnits[i++];
120 if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
121 nextValue <= UNICODE_UTF16_RESERVED_HI) {
122 value += UNICODE_UTF16_OFFSET +
123 (nextValue - UNICODE_UTF16_SURROGATE_UNIT_1_BASE);
124 codepointBuffer.add(value);
125 } else {
126 if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_0_BASE &&
127 nextValue < UNICODE_UTF16_SURROGATE_UNIT_1_BASE) {
128 i--;
129 }
130 codepointBuffer.add(UNICODE_REPLACEMENT_CHARACTER_CODEPOINT);
131 continue;
132 }
133 } else {
134 codepointBuffer.add(UNICODE_REPLACEMENT_CHARACTER_CODEPOINT);
135 continue;
136 }
137 }
138 return codepointBuffer;
139 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698