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

Side by Side Diff: utils/string_encoding/Utf16.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("UTF16");
Søren Gjesse 2012/02/01 11:25:25 Maybe utf16?
dcarlson 2012/02/01 22:18:46 Done.
6 #import("UnicodeCore.dart");
7 #import("Unicode.dart");
8
9 /**
10 * Produce a String from a sequence of UTF16 encoded bytes.
11 */
12 String decodeFromUtf16(List<int> bytes) {
13 List<int> codeUnits = _utf16ToUtf16CodeUnits(bytes);
14 // TODO is16BitCodeUnit() is used to work around a bug with frog/dartc
15 // (http://code.google.com/p/dart/issues/detail?id=1357). Consider
16 // removing after this issue is resolved.
17 if (is16BitCodeUnit()) {
18 return new String.fromCharCodes(codeUnits);
19 } else {
20 return new String.fromCharCodes(utf16CodeUnitsToCodepoints(codeUnits));
21 }
22 }
23
24 /**
25 * Produce a String from a sequence of UTF16-BE encoded bytes.
26 */
27 String decodeFromUtf16be(List<int> bytes) {
28 List<int> codeUnits = _utf16beToUtf16CodeUnits(bytes);
29 // TODO is16BitCodeUnit() is used to work around a bug with frog/dartc
30 // (http://code.google.com/p/dart/issues/detail?id=1357). Consider
31 // removing after this issue is resolved.
32 if (is16BitCodeUnit()) {
33 return new String.fromCharCodes(codeUnits);
34 } else {
35 return new String.fromCharCodes(utf16CodeUnitsToCodepoints(codeUnits));
36 }
37 }
38
39 /**
40 * Produce a String from a sequence of UTF16-LE encoded bytes.
41 */
42 String decodeFromUtf16le(List<int> bytes) {
43 List<int> codeUnits = _utf16leToUtf16CodeUnits(bytes);
44 // TODO is16BitCodeUnit() is used to work around a bug with frog/dartc
45 // (http://code.google.com/p/dart/issues/detail?id=1357). Consider
46 // removing after this issue is resolved.
47 if (is16BitCodeUnit()) {
48 return new String.fromCharCodes(codeUnits);
49 } else {
50 return new String.fromCharCodes(utf16CodeUnitsToCodepoints(codeUnits));
51 }
52 }
53
54 /**
55 * Produce a sequence of UTF16 encoded bytes.
56 */
57 List<int> encodeAsUtf16(String str, [bool writeBOM = true]) =>
58 encodeAsUtf16be(str, writeBOM);
59
60 /**
61 * Produce a sequence of UTF16-BE encoded bytes.
62 */
63 List<int> encodeAsUtf16be(String str, [bool writeBOM = false]) {
64 List<int> utf16CodeUnits = _stringToUtf16CodeUnits(str);
65 List<int> encoding = new List<int>(2 * utf16CodeUnits.length +
66 (writeBOM ? 2 : 0));
67 int i = 0;
68 if (writeBOM) {
69 encoding[i++] = UNICODE_UTF_BOM_HI;
70 encoding[i++] = UNICODE_UTF_BOM_LO;
71 }
72 for (int unit in utf16CodeUnits) {
73 encoding[i++] = (unit & UNICODE_BYTE_ONE_MASK) >> 8;
74 encoding[i++] = unit & UNICODE_BYTE_ZERO_MASK;
75 }
76 return encoding;
77 }
78
79 /**
80 * Produce a sequence of UTF16-LE encoded bytes.
81 */
82 List<int> encodeAsUtf16le(String str, [bool writeBOM = false]) {
83 List<int> utf16CodeUnits = _stringToUtf16CodeUnits(str);
84 List<int> encoding = new List<int>(2 * utf16CodeUnits.length +
85 (writeBOM ? 2 : 0));
86 int i = 0;
87 if (writeBOM) {
88 encoding[i++] = UNICODE_UTF_BOM_LO;
89 encoding[i++] = UNICODE_UTF_BOM_HI;
90 }
91 for (int unit in utf16CodeUnits) {
92 encoding[i++] = unit & UNICODE_BYTE_ZERO_MASK;
93 encoding[i++] = (unit & UNICODE_BYTE_ONE_MASK) >> 8;
94 }
95 return encoding;
96 }
97
98 List<int> _stringToUtf16CodeUnits(String str) {
99 List<int> codepoints = <int>[];
100 // TODO is16BitCodeUnit() is used to work around a bug with frog/dartc
101 // (http://code.google.com/p/dart/issues/detail?id=1357). Consider
102 // removing after this issue is resolved.
103 if (is16BitCodeUnit()) {
104 return str.charCodes();
105 } else {
106 return codepointsToUtf16CodeUnits(str.charCodes());
107 }
108 }
109
110 /**
111 * Convert UTF-16BE encoded bytes to utf16 code units by grouping 1-2 bytes
112 * to produce the code unit (0-(2^16)-1).
113 */
114 List<int> _utf16beToUtf16CodeUnits(List<int> utf16beEncodedBytes,
115 [int start = 0, int length = null]) {
116 if (!(start >= 0)) {
117 throw new IllegalArgumentException("start");
118 }
119
120 if (!(length == null || length >= 0)) {
121 throw new IllegalArgumentException("length");
122 }
123
124 int end = length != null ?
125 Math.min(utf16beEncodedBytes.length, start + length) :
126 utf16beEncodedBytes.length;
127
128 List<int> codeUnits = <int>[];
129 int i = start;
130 int lastIndex = end - 1;
131 while (i < lastIndex) {
132 int hi = utf16beEncodedBytes[i++];
133 int lo = utf16beEncodedBytes[i++];
134 codeUnits.add((hi << 8) | lo);
135 }
136 return codeUnits;
137 }
138
139 /**
140 * Convert UTF-16LE encoded bytes to utf16 code units by grouping 1-2 bytes
141 * to produce the code unit (0-(2^16)-1).
142 */
143 List<int> _utf16leToUtf16CodeUnits(List<int> utf16leEncodedBytes,
144 [int start = 0, int length = null]) {
145 if (!(start >= 0)) {
146 throw new IllegalArgumentException("start");
147 }
148
149 if (!(length == null || length >= 0)) {
150 throw new IllegalArgumentException("length");
151 }
152
153 int end = length != null ?
154 Math.min(utf16leEncodedBytes.length, start + length) :
155 utf16leEncodedBytes.length;
156
157 List<int> codeUnits = <int>[];
158 int i = start;
159 int lastIndex = end - 1;
160 while (i < lastIndex) {
161 int lo = utf16leEncodedBytes[i++];
162 int hi = utf16leEncodedBytes[i++];
163 codeUnits.add((hi << 8) | lo);
164 }
165 return codeUnits;
166 }
167
168 /**
169 * Convert UTF-16 encoded bytes to utf16 code units by grouping 1-2 bytes
170 * to produce the code unit (0-(2^16)-1). Relies on BOM to determine
171 * endian-ness, and defaults to BE.
172 */
173 List<int> _utf16ToUtf16CodeUnits(List<int> utf16EncodedBytes,
174 [int start = 0, int length = null]) {
175 if (!(start >= 0)) {
176 throw new IllegalArgumentException("start");
177 }
178
179 if (!(length == null || length >= 0)) {
180 throw new IllegalArgumentException("length");
181 }
182
183 int end = length != null ?
184 Math.min(utf16EncodedBytes.length, start + length) :
185 utf16EncodedBytes.length;
186
187 if ((start + 1 < end) && utf16EncodedBytes[start] == UNICODE_UTF_BOM_HI &&
188 utf16EncodedBytes[start + 1] == UNICODE_UTF_BOM_LO) {
189 return _utf16beToUtf16CodeUnits(utf16EncodedBytes, start + 2,
190 end - (start + 2));
191 } else if ((start + 1 < end) &&
192 utf16EncodedBytes[start] == UNICODE_UTF_BOM_LO &&
193 utf16EncodedBytes[start + 1] == UNICODE_UTF_BOM_HI) {
194 return _utf16leToUtf16CodeUnits(utf16EncodedBytes, start + 2,
195 end - (start + 2));
196 } else {
197 return _utf16beToUtf16CodeUnits(utf16EncodedBytes, start, end - start);
198 }
199 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698