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

Side by Side Diff: sdk/lib/core/string.dart

Issue 12094056: Runes, a bi-directional code-point iterator/iterable. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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
« no previous file with comments | « sdk/lib/core/iterable.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of dart.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * The String class represents character strings. Strings are 8 * The String class represents character strings. Strings are
9 * immutable. A string is represented by a list of 32-bit Unicode 9 * immutable. A string is represented by a list of 32-bit Unicode
10 * scalar character codes accessible through the [charCodeAt] or the 10 * scalar character codes accessible through the [charCodeAt] or the
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 * where all characters are made lower case. Returns [:this:] otherwise. 182 * where all characters are made lower case. Returns [:this:] otherwise.
183 */ 183 */
184 String toLowerCase(); 184 String toLowerCase();
185 185
186 /** 186 /**
187 * If this string is not already all uper case, returns a new string 187 * If this string is not already all uper case, returns a new string
188 * where all characters are made upper case. Returns [:this:] otherwise. 188 * where all characters are made upper case. Returns [:this:] otherwise.
189 */ 189 */
190 String toUpperCase(); 190 String toUpperCase();
191 } 191 }
192
193 class Runes implements Iterable<int> {
194 String _string;
195 Runes(this._string);
196 RuneIterator get iterator => new RuneIterator(_string);
197 }
198
199 /** [Iterator] for reading Unicode code points out of a Dart string. */
200 class RuneIterator implements BiDirectionalIterator<int> {
201 /** String being iterated. */
202 final String _string;
203 /** Position before the current code point. */
204 int _position;
205 /** Position after the current code point. */
206 int _nextPosition;
207 /**
208 * Current code point.
209 *
210 * If the iterator has hit either end, the [_currentCodePoint] is null
211 * and [: _position == _nextPosition :].
212 */
213 int _currentCodePoint;
214
215 /** Create an iterator positioned at the beginning of the string. */
216 RuneIterator(String string)
217 : _string = string, _position = 0, _nextPosition = 0;
218
219 /**
220 * Create an iterator positioned before the [start]th code unit of the string.
221 *
222 * A [moveNext] will make the following code point the current value, and a
223 * [movePrevious] will make the preceding code pount the current value.
224 *
225 * If the [start] position is in the middle of a surrogate pair, then the
226 * first result in either direction will be an unmatched surrogate.
227 */
228 RuneIterator.at(String string, int start)
229 : _string = string, _position = start, _nextPosition = start {
230 if (start < 0 || start > string.length) {
231 throw new RangeError.range(start, 0, string.length);
232 }
233 }
234
235 int get current => _currentCodePoint;
236
237 bool moveNext() {
erikcorry 2013/01/30 13:26:55 This one is factored into two functions, whereas t
Lasse Reichstein Nielsen 2013/01/30 14:03:37 ACK. I was using _readCharForward in the .at const
238 _position = _nextPosition;
239 if (_position == _string.length) {
240 _currentCodePoint = null;
241 return false;
242 }
243 _readCharForward();
244 return true;
245 }
246
247 // Decodes code units at _position, updates _currentCodePoint, _nextPosition.
248 void _readCharForward() {
249 int codeUnit = _string.charCodeAt(_position);
250 int nextPosition = _position + 1;
251 if ((codeUnit & 0xFC00) == 0xD800 && nextPosition < _string.length) {
252 int nextCodeUnit = _string.charCodeAt(nextPosition);
253 if ((nextCodeUnit & 0xFC00) == 0xDC00) {
254 _nextPosition = nextPosition + 1;
255 _currentCodePoint =
256 0x10000 + ((nextCodeUnit & 0x3FF) << 10) | (codeUnit & 0x3FF);
Lasse Reichstein Nielsen 2013/01/30 14:03:37 Good catch, these two are swapped (copy-n-paste bu
257 return;
258 }
259 }
260 _nextPosition = nextPosition;
261 _currentCodePoint = codeUnit;
262 }
263
264 bool movePrevious() {
265 if (_position == 0) {
266 _currentCodePoint = null;
267 return false;
268 }
269 int position = _position - 1;
270 _nextPosition = _position;
271 int codeUnit = _string.charCodeAt(position);
272 if ((codeUnit & 0xFC00) == 0xDC00 && position > 0) {
273 int prevCodeUnit = _string.charCodeAt(position - 1);
274 if ((prevCodeUnit & 0xFC00) == 0xD800) {
275 _position = position - 1;
276 _currentCodePoint =
277 0x10000 + ((prevCodeUnit & 0x3FF) << 10) | (codeUnit & 0x3FF);
278 return true;
279 }
280 }
281 _position = position;
282 _currentCodePoint = codeUnit;
283 return true;
284 }
285 }
OLDNEW
« no previous file with comments | « sdk/lib/core/iterable.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698