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

Side by Side Diff: utils/string_encoding/Utf32.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: updates from initial review. 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) 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("UTF32");
6 #import("UnicodeCore.dart");
7 #import("Unicode.dart");
8
9 /**
10 * Produce a String from a sequence of UTF32 encoded bytes.
11 */
12 String decodeFromUtf32(List<int> bytes) =>
13 codepointsToString(_utf32ToCodePoints(bytes));
14
15 /**
16 * Produce a String from a sequence of UTF32-BE encoded bytes.
17 */
18 String decodeFromUtf32be(List<int> bytes) =>
19 codepointsToString(_utf32beToCodePoints(bytes));
20
21 /**
22 * Produce a String from a sequence of UTF32-LE encoded bytes.
23 */
24 String decodeFromUtf32le(List<int> bytes) =>
25 codepointsToString(_utf32leToCodePoints(bytes));
26
27 /**
28 * Produce a sequence of UTF32 encoded bytes.
29 */
30 List<int> encodeAsUtf32(String str) => encodeAsUtf32be(str);
31
32 /**
33 * Produce a sequence of UTF32-BE encoded bytes.
34 */
35 List<int> encodeAsUtf32be(String str) {
36 List<int> utf32CodeUnits = stringToCodepoints(str);
37 List<int> encoding = <int>[0, 0, 0xfe, 0xff];
38 for (int unit in utf32CodeUnits) {
39 encoding.add((unit >> 24) & 0xff);
40 encoding.add((unit >> 16) & 0xff);
41 encoding.add((unit >> 8) & 0xff);
42 encoding.add(unit & 0xff);
43 }
44 return encoding;
45 }
46
47 /**
48 * Produce a sequence of UTF32-LE encoded bytes.
49 */
50 List<int> encodeAsUtf32le(String str) {
51 List<int> utf32CodeUnits = stringToCodepoints(str);
52 List<int> encoding = <int>[0xff, 0xfe, 0, 0];
53 for (int unit in utf32CodeUnits) {
54 encoding.add((unit) & 0xff);
55 encoding.add((unit >> 8) & 0xff);
56 encoding.add((unit >> 16) & 0xff);
57 encoding.add((unit >> 24) & 0xff);
58 }
59 return encoding;
60 }
61
62 /**
63 * Joins groups of 4 bytes (0-255) UTF32-BE to produce single code points.
64 */
65 List<int> _utf32beToCodePoints(List<int> utf32beEncodedBytes,
66 [int start = 0, int length = - 1]) {
67 List<int> codepoints = <int>[];
68 int end = length >= 0 ?
69 Math.min(utf32beEncodedBytes.length, start + length) :
70 utf32beEncodedBytes.length;
71
72 int i = start;
73 int lastIndex = end - 3;
74
75 if((start + 3 < end) && utf32beEncodedBytes[start] == 0 &&
76 utf32beEncodedBytes[start + 1] == 0 &&
77 utf32beEncodedBytes[start + 2] == 0xfe &&
78 utf32beEncodedBytes[start + 3] == 0xff) {
79 i += 4;
80 }
81
82 while (i < lastIndex) {
83 int value = utf32beEncodedBytes[i++];
84 value = (256 * value) + utf32beEncodedBytes[i++];
85 value = (256 * value) + utf32beEncodedBytes[i++];
86 value = (256 * value) + utf32beEncodedBytes[i++];
87 codepoints.add(_filterValidCodepoint(value));
88 }
89 return codepoints;
90 }
91
92 /**
93 * Joins groups of 4 bytes (0-255) UTF32-LE to produce single code points.
94 */
95 List<int> _utf32leToCodePoints(List<int> utf32leEncodedBytes,
96 [int start = 0, int length = - 1]) {
97 List<int> codepoints = <int>[];
98 int end = length >= 0 ?
99 Math.min(utf32leEncodedBytes.length, start + length) :
100 utf32leEncodedBytes.length;
101
102 int i = start;
103 int lastIndex = end - 3;
104
105 if((start + 3 < end) && utf32leEncodedBytes[start] == 0xff &&
106 utf32leEncodedBytes[start + 1] == 0xfe &&
107 utf32leEncodedBytes[start + 2] == 0 &&
108 utf32leEncodedBytes[start + 3] == 0) {
109 i += 4;
110 }
111
112 while (i < lastIndex) {
113 int value = utf32leEncodedBytes[i+3];
114 value = (256 * value) + utf32leEncodedBytes[i+2];
115 value = (256 * value) + utf32leEncodedBytes[i+1];
116 value = (256 * value) + utf32leEncodedBytes[i];
117 i += 4;
118 codepoints.add(_filterValidCodepoint(value));
119 }
120 return codepoints;
121 }
122
123 /**
124 * Joins groups of 4 bytes (0-255) UTF32 to produce single code points.
125 */
126 List<int> _utf32ToCodePoints(List<int> utf32EncodedBytes,
127 [int start = 0, int length = - 1]) {
128 int end = length >= 0 ?
129 Math.min(utf32EncodedBytes.length, start + length) :
130 utf32EncodedBytes.length;
131
132 if((start + 3 < end) &&
133 utf32EncodedBytes[start] == 0 &&
134 utf32EncodedBytes[start + 1] == 0 &&
135 utf32EncodedBytes[start + 2] == 0xfe &&
136 utf32EncodedBytes[start + 3] == 0xff) {
137 return _utf32beToCodePoints(utf32EncodedBytes, start + 4,
138 end - (start + 4));
139 } else if((start + 3 < end) &&
140 utf32EncodedBytes[start] == 0xff &&
141 utf32EncodedBytes[start + 1] == 0xfe &&
142 utf32EncodedBytes[start + 2] == 0 &&
143 utf32EncodedBytes[start + 3] == 0) {
144 return _utf32leToCodePoints(utf32EncodedBytes, start + 4,
145 end - (start + 4));
146 } else {
147 return _utf32beToCodePoints(utf32EncodedBytes, start, end - start);
148 }
149 }
150
151 int _filterValidCodepoint(int codepoint) {
152 if ((codepoint >= 0 && codepoint < 0xd800) ||
153 (codepoint >= 0x10000 && codepoint < 0x110000)) {
154 return codepoint;
155 } else {
156 return REPLACEMENT_CHARACTER_CODEPOINT;
157 }
158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698