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

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

Issue 9323077: Optimize special cases in utf8 and utf16 where input can be copied to output. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: respond to comments, move throw up a little, fix unit test types. 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library("unicode_core"); 5 #library("unicode_core");
6 6
7 /* 7 /*
8 * Test for presence of bug related to the use of UTF-16 code units for 8 * Test for presence of bug related to the use of UTF-16 code units for
9 * Dart compiled to JS. 9 * Dart compiled to JS.
10 */ 10 */
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 throw new IllegalArgumentException("length"); 54 throw new IllegalArgumentException("length");
55 } 55 }
56 56
57 int end = length != null ? 57 int end = length != null ?
58 Math.min(codepoints.length, offset + length) : 58 Math.min(codepoints.length, offset + length) :
59 codepoints.length; 59 codepoints.length;
60 60
61 int encodedLength = 0; 61 int encodedLength = 0;
62 for (int i = offset; i < end; i++) { 62 for (int i = offset; i < end; i++) {
63 int value = codepoints[i]; 63 int value = codepoints[i];
64 if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) || 64 if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
65 (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) { 65 (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
66 encodedLength++; 66 encodedLength++;
67 } else if (value > UNICODE_PLANE_ONE_MAX && 67 } else if (value > UNICODE_PLANE_ONE_MAX &&
68 value <= UNICODE_VALID_RANGE_MAX) { 68 value <= UNICODE_VALID_RANGE_MAX) {
69 encodedLength += 2; 69 encodedLength += 2;
70 } else { 70 } else {
71 encodedLength++; 71 encodedLength++;
72 } 72 }
73 } 73 }
74 74
75 void addReplacementCodepoint(List<int> codepointBuffer, int offset, 75 void addReplacementCodepoint(List<int> codepointBuffer, int offset,
76 int replacementCodepoint) { 76 int replacementCodepoint) {
77 if(replacementCodepoint != null) { 77 if (replacementCodepoint != null) {
78 codepointBuffer[offset] = replacementCodepoint; 78 codepointBuffer[offset] = replacementCodepoint;
79 } else { 79 } else {
80 throw new IllegalArgumentException("Invalid encoding"); 80 throw new IllegalArgumentException("Invalid encoding");
81 } 81 }
82 } 82 }
83
83 List<int> codeUnitsBuffer = new List<int>(encodedLength); 84 List<int> codeUnitsBuffer = new List<int>(encodedLength);
84 int j = 0; 85 int j = 0;
85 for (int i = offset; i < end; i++) { 86 for (int i = offset; i < end; i++) {
86 int value = codepoints[i]; 87 int value = codepoints[i];
87 if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) || 88 if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
88 (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) { 89 (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
89 codeUnitsBuffer[j++] = value; 90 codeUnitsBuffer[j++] = value;
90 } else if (value > UNICODE_PLANE_ONE_MAX && 91 } else if (value > UNICODE_PLANE_ONE_MAX &&
91 value <= UNICODE_VALID_RANGE_MAX) { 92 value <= UNICODE_VALID_RANGE_MAX) {
92 int base = value - UNICODE_UTF16_OFFSET; 93 int base = value - UNICODE_UTF16_OFFSET;
93 codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_0_BASE + 94 codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_0_BASE +
94 ((base & UNICODE_UTF16_HI_MASK) >> 10); 95 ((base & UNICODE_UTF16_HI_MASK) >> 10);
95 codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_1_BASE + 96 codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_1_BASE +
96 (base & UNICODE_UTF16_LO_MASK); 97 (base & UNICODE_UTF16_LO_MASK);
97 } else { 98 } else {
98 addReplacementCodepoint(codeUnitsBuffer, j++, replacementCodepoint); 99 addReplacementCodepoint(codeUnitsBuffer, j++, replacementCodepoint);
99 } 100 }
100 } 101 }
(...skipping 11 matching lines...) Expand all
112 } 113 }
113 114
114 if (!(length == null || length >= 0)) { 115 if (!(length == null || length >= 0)) {
115 throw new IllegalArgumentException("length"); 116 throw new IllegalArgumentException("length");
116 } 117 }
117 118
118 int end = length != null ? 119 int end = length != null ?
119 Math.min(utf16CodeUnits.length, offset + length) : 120 Math.min(utf16CodeUnits.length, offset + length) :
120 utf16CodeUnits.length; 121 utf16CodeUnits.length;
121 122
122 void addReplacementCodepoint(void f(int v), int replacementCodepoint) { 123 void decode(void f(int v)) {
123 if(replacementCodepoint != null) {
124 f(replacementCodepoint);
125 } else {
126 throw new IllegalArgumentException("Invalid encoding");
127 }
128 }
129
130 void apply(void f(int v)) {
131 int i = offset; 124 int i = offset;
132 // skip the first entry if it is a BOM. 125 // skip the first entry if it is a BOM.
133 if (end > 0 && utf16CodeUnits[0] == UNICODE_BOM) { 126 if (end > 0 && utf16CodeUnits[0] == UNICODE_BOM) {
134 i++; 127 i++;
135 } 128 }
136 while (i < end) { 129 while (i < end) {
137 int value = utf16CodeUnits[i++]; 130 int value = utf16CodeUnits[i++];
138 if (value < 0) { 131 if (value < 0) {
139 addReplacementCodepoint(f, replacementCodepoint); 132 f(null);
140 continue; 133 continue;
141 } 134 }
142 if (value < UNICODE_UTF16_RESERVED_LO || 135 if (value < UNICODE_UTF16_RESERVED_LO ||
143 (value > UNICODE_UTF16_RESERVED_HI && 136 (value > UNICODE_UTF16_RESERVED_HI &&
144 value <= UNICODE_PLANE_ONE_MAX)) { 137 value <= UNICODE_PLANE_ONE_MAX)) {
145 // transfer directly 138 // transfer directly
146 f(value); 139 f(value);
147 } else if (value < UNICODE_UTF16_SURROGATE_UNIT_1_BASE && i < end) { 140 } else if (value < UNICODE_UTF16_SURROGATE_UNIT_1_BASE && i < end) {
148 // merge surrogate pair 141 // merge surrogate pair
149 int nextValue = utf16CodeUnits[i++]; 142 int nextValue = utf16CodeUnits[i++];
150 if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_1_BASE && 143 if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
151 nextValue <= UNICODE_UTF16_RESERVED_HI) { 144 nextValue <= UNICODE_UTF16_RESERVED_HI) {
152 value = (value - UNICODE_UTF16_SURROGATE_UNIT_0_BASE) << 10; 145 value = (value - UNICODE_UTF16_SURROGATE_UNIT_0_BASE) << 10;
153 value += UNICODE_UTF16_OFFSET + 146 value += UNICODE_UTF16_OFFSET +
154 (nextValue - UNICODE_UTF16_SURROGATE_UNIT_1_BASE); 147 (nextValue - UNICODE_UTF16_SURROGATE_UNIT_1_BASE);
155 f(value); 148 f(value);
156 } else { 149 } else {
157 if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_0_BASE && 150 if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_0_BASE &&
158 nextValue < UNICODE_UTF16_SURROGATE_UNIT_1_BASE) { 151 nextValue < UNICODE_UTF16_SURROGATE_UNIT_1_BASE) {
159 i--; 152 i--;
160 } 153 }
161 addReplacementCodepoint(f, replacementCodepoint); 154 f(null);
162 continue; 155 continue;
163 } 156 }
164 } else { 157 } else {
165 addReplacementCodepoint(f, replacementCodepoint); 158 f(null);
166 continue; 159 continue;
167 } 160 }
168 } 161 }
169 } 162 }
163
164 // First pass through data to 1) size the output buffer and 2) check for
165 // special case optimization where A) the length stays the same and B)
166 // no special replacement characters are used. If these criteria are met
167 // we can just copy input to the output.
170 int codepointBufferLength = 0; 168 int codepointBufferLength = 0;
171 apply(void _(int value) { 169 bool hasReplacements = false;
170 decode(void _(int value) {
172 codepointBufferLength++; 171 codepointBufferLength++;
172 if (value == null) {
173 hasReplacements = true;
174 }
173 }); 175 });
174 176
177 // If the string calls for replacements, but we the method is called
Søren Gjesse 2012/02/06 22:13:29 Remove 'we' in 'but we the'
dcarlson 2012/02/13 16:37:51 weird typo -- corrected to "when"
178 // with replacementCodepoint explicitly set to null, then throw an exception.
179 if (hasReplacements && replacementCodepoint == null) {
180 throw new IllegalArgumentException("Invalid encoding");
181 }
182
183 int _length = end - offset;
175 List<int> codepointBuffer = new List<int>(codepointBufferLength); 184 List<int> codepointBuffer = new List<int>(codepointBufferLength);
176 int i = 0; 185 if (_length == codepointBufferLength && !hasReplacements) {
177 apply(void _(int value) { 186 codepointBuffer.setRange(0, _length, utf16CodeUnits, offset);
178 codepointBuffer[i++] = value; 187 } else {
179 }); 188 int i = 0;
189 decode(
190 void _(int value) {
191 if (value != null) {
192 codepointBuffer[i++] = value;
193 } else {
194 codepointBuffer[i++] = replacementCodepoint;
195 }
196 }
197 );
198 }
180 return codepointBuffer; 199 return codepointBuffer;
181 } 200 }
OLDNEW
« no previous file with comments | « no previous file | utils/string_encoding/utf8_impl.dart » ('j') | utils/string_encoding/utf8_impl.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698