OLD | NEW |
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 * A sequence of characters. | 8 * A sequence of characters. |
9 * | 9 * |
10 * A string can be either single or multiline. Single line strings are | 10 * A string can be either single or multiline. Single line strings are |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 * var clef = new String.fromCharCodes([0x1D11E]); | 104 * var clef = new String.fromCharCodes([0x1D11E]); |
105 * clef.codeUnitAt(0); // 0xD834 | 105 * clef.codeUnitAt(0); // 0xD834 |
106 * clef.codeUnitAt(1); // 0xDD1E | 106 * clef.codeUnitAt(1); // 0xDD1E |
107 * | 107 * |
108 * If [start] and [end] is provided, only the values of [charCodes] | 108 * If [start] and [end] is provided, only the values of [charCodes] |
109 * at positions from `start` to, but not including, `end`, are used. | 109 * at positions from `start` to, but not including, `end`, are used. |
110 * The `start` and `end` values must satisfy | 110 * The `start` and `end` values must satisfy |
111 * `0 <= start <= end <= charCodes.length`. | 111 * `0 <= start <= end <= charCodes.length`. |
112 */ | 112 */ |
113 external factory String.fromCharCodes(Iterable<int> charCodes, | 113 external factory String.fromCharCodes(Iterable<int> charCodes, |
114 [int start = 0, int end]); | 114 [int start = 0, int end]); |
115 | 115 |
116 /** | 116 /** |
117 * Allocates a new String for the specified [charCode]. | 117 * Allocates a new String for the specified [charCode]. |
118 * | 118 * |
119 * If the [charCode] can be represented by a single UTF-16 code unit, the new | 119 * If the [charCode] can be represented by a single UTF-16 code unit, the new |
120 * string contains a single code unit. Otherwise, the [length] is 2 and | 120 * string contains a single code unit. Otherwise, the [length] is 2 and |
121 * the code units form a surrogate pair. See documentation for | 121 * the code units form a surrogate pair. See documentation for |
122 * [fromCharCodes]. | 122 * [fromCharCodes]. |
123 * | 123 * |
124 * Creating a String with half of a surrogate pair is allowed. | 124 * Creating a String with half of a surrogate pair is allowed. |
(...skipping 12 matching lines...) Expand all Loading... |
137 * | 137 * |
138 * Example of getting a value: | 138 * Example of getting a value: |
139 * | 139 * |
140 * const String.fromEnvironment("defaultFloo", defaultValue: "no floo") | 140 * const String.fromEnvironment("defaultFloo", defaultValue: "no floo") |
141 * | 141 * |
142 * Example of checking whether a declaration is there at all: | 142 * Example of checking whether a declaration is there at all: |
143 * | 143 * |
144 * var isDeclared = const String.fromEnvironment("maybeDeclared") != null; | 144 * var isDeclared = const String.fromEnvironment("maybeDeclared") != null; |
145 */ | 145 */ |
146 external const factory String.fromEnvironment(String name, | 146 external const factory String.fromEnvironment(String name, |
147 {String defaultValue}); | 147 {String defaultValue}); |
148 | 148 |
149 /** | 149 /** |
150 * Gets the character (as a single-code-unit [String]) at the given [index]. | 150 * Gets the character (as a single-code-unit [String]) at the given [index]. |
151 * | 151 * |
152 * The returned string represents exactly one UTF-16 code unit, which may be | 152 * The returned string represents exactly one UTF-16 code unit, which may be |
153 * half of a surrogate pair. A single member of a surrogate pair is an | 153 * half of a surrogate pair. A single member of a surrogate pair is an |
154 * invalid UTF-16 string: | 154 * invalid UTF-16 string: |
155 * | 155 * |
156 * var clef = '\u{1D11E}'; | 156 * var clef = '\u{1D11E}'; |
157 * // These represent invalid UTF-16 strings. | 157 * // These represent invalid UTF-16 strings. |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 * is replaced by the result of calling [replace] with the match object. | 429 * is replaced by the result of calling [replace] with the match object. |
430 * | 430 * |
431 * The optional [startIndex] is by default set to 0. If provided, it must be | 431 * The optional [startIndex] is by default set to 0. If provided, it must be |
432 * an integer in the range `[0 .. len]`, where `len` is this string's length. | 432 * an integer in the range `[0 .. len]`, where `len` is this string's length. |
433 * | 433 * |
434 * If the value returned by calling `replace` is not a [String], it | 434 * If the value returned by calling `replace` is not a [String], it |
435 * is converted to a `String` using its `toString` method, which must | 435 * is converted to a `String` using its `toString` method, which must |
436 * then return a string. | 436 * then return a string. |
437 */ | 437 */ |
438 String replaceFirstMapped(Pattern from, String replace(Match match), | 438 String replaceFirstMapped(Pattern from, String replace(Match match), |
439 [int startIndex = 0]); | 439 [int startIndex = 0]); |
440 | 440 |
441 /** | 441 /** |
442 * Replaces all substrings that match [from] with [replace]. | 442 * Replaces all substrings that match [from] with [replace]. |
443 * | 443 * |
444 * Returns a new string in which the non-overlapping substrings matching | 444 * Returns a new string in which the non-overlapping substrings matching |
445 * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced | 445 * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced |
446 * by the literal string [replace]. | 446 * by the literal string [replace]. |
447 * | 447 * |
448 * 'resume'.replaceAll(new RegExp(r'e'), 'é'); // 'résumé' | 448 * 'resume'.replaceAll(new RegExp(r'e'), 'é'); // 'résumé' |
449 * | 449 * |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 * Each non-matched part is converted by a call to [onNonMatch]. If | 551 * Each non-matched part is converted by a call to [onNonMatch]. If |
552 * [onNonMatch] is omitted, the non-matching part is used. | 552 * [onNonMatch] is omitted, the non-matching part is used. |
553 * | 553 * |
554 * Then all the converted parts are combined into the resulting string. | 554 * Then all the converted parts are combined into the resulting string. |
555 * | 555 * |
556 * 'Eats shoots leaves'.splitMapJoin((new RegExp(r'shoots')), | 556 * 'Eats shoots leaves'.splitMapJoin((new RegExp(r'shoots')), |
557 * onMatch: (m) => '${m.group(0)}', | 557 * onMatch: (m) => '${m.group(0)}', |
558 * onNonMatch: (n) => '*'); // *shoots* | 558 * onNonMatch: (n) => '*'); // *shoots* |
559 */ | 559 */ |
560 String splitMapJoin(Pattern pattern, | 560 String splitMapJoin(Pattern pattern, |
561 {String onMatch(Match match), | 561 {String onMatch(Match match), String onNonMatch(String nonMatch)}); |
562 String onNonMatch(String nonMatch)}); | |
563 | 562 |
564 /** | 563 /** |
565 * Returns an unmodifiable list of the UTF-16 code units of this string. | 564 * Returns an unmodifiable list of the UTF-16 code units of this string. |
566 */ | 565 */ |
567 List<int> get codeUnits; | 566 List<int> get codeUnits; |
568 | 567 |
569 /** | 568 /** |
570 * Returns an [Iterable] of Unicode code-points of this string. | 569 * Returns an [Iterable] of Unicode code-points of this string. |
571 * | 570 * |
572 * If the string contains surrogate pairs, they are combined and returned | 571 * If the string contains surrogate pairs, they are combined and returned |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 int length = string.length; | 617 int length = string.length; |
619 int code = string.codeUnitAt(length - 1); | 618 int code = string.codeUnitAt(length - 1); |
620 if (_isTrailSurrogate(code) && string.length > 1) { | 619 if (_isTrailSurrogate(code) && string.length > 1) { |
621 int previousCode = string.codeUnitAt(length - 2); | 620 int previousCode = string.codeUnitAt(length - 2); |
622 if (_isLeadSurrogate(previousCode)) { | 621 if (_isLeadSurrogate(previousCode)) { |
623 return _combineSurrogatePair(previousCode, code); | 622 return _combineSurrogatePair(previousCode, code); |
624 } | 623 } |
625 } | 624 } |
626 return code; | 625 return code; |
627 } | 626 } |
628 | |
629 } | 627 } |
630 | 628 |
631 // Is then code (a 16-bit unsigned integer) a UTF-16 lead surrogate. | 629 // Is then code (a 16-bit unsigned integer) a UTF-16 lead surrogate. |
632 bool _isLeadSurrogate(int code) => (code & 0xFC00) == 0xD800; | 630 bool _isLeadSurrogate(int code) => (code & 0xFC00) == 0xD800; |
633 | 631 |
634 // Is then code (a 16-bit unsigned integer) a UTF-16 trail surrogate. | 632 // Is then code (a 16-bit unsigned integer) a UTF-16 trail surrogate. |
635 bool _isTrailSurrogate(int code) => (code & 0xFC00) == 0xDC00; | 633 bool _isTrailSurrogate(int code) => (code & 0xFC00) == 0xDC00; |
636 | 634 |
637 // Combine a lead and a trail surrogate value into a single code point. | 635 // Combine a lead and a trail surrogate value into a single code point. |
638 int _combineSurrogatePair(int start, int end) { | 636 int _combineSurrogatePair(int start, int end) { |
(...skipping 13 matching lines...) Expand all Loading... |
652 /** | 650 /** |
653 * Current code point. | 651 * Current code point. |
654 * | 652 * |
655 * If the iterator has hit either end, the [_currentCodePoint] is null | 653 * If the iterator has hit either end, the [_currentCodePoint] is null |
656 * and [: _position == _nextPosition :]. | 654 * and [: _position == _nextPosition :]. |
657 */ | 655 */ |
658 int _currentCodePoint; | 656 int _currentCodePoint; |
659 | 657 |
660 /** Create an iterator positioned at the beginning of the string. */ | 658 /** Create an iterator positioned at the beginning of the string. */ |
661 RuneIterator(String string) | 659 RuneIterator(String string) |
662 : this.string = string, _position = 0, _nextPosition = 0; | 660 : this.string = string, |
| 661 _position = 0, |
| 662 _nextPosition = 0; |
663 | 663 |
664 /** | 664 /** |
665 * Create an iterator positioned before the [index]th code unit of the string. | 665 * Create an iterator positioned before the [index]th code unit of the string. |
666 * | 666 * |
667 * When created, there is no [current] value. | 667 * When created, there is no [current] value. |
668 * A [moveNext] will use the rune starting at [index] the current value, | 668 * A [moveNext] will use the rune starting at [index] the current value, |
669 * and a [movePrevious] will use the rune ending just before [index] as the | 669 * and a [movePrevious] will use the rune ending just before [index] as the |
670 * the current value. | 670 * the current value. |
671 * | 671 * |
672 * The [index] position must not be in the middle of a surrogate pair. | 672 * The [index] position must not be in the middle of a surrogate pair. |
673 */ | 673 */ |
674 RuneIterator.at(String string, int index) | 674 RuneIterator.at(String string, int index) |
675 : string = string, _position = index, _nextPosition = index { | 675 : string = string, |
| 676 _position = index, |
| 677 _nextPosition = index { |
676 RangeError.checkValueInInterval(index, 0, string.length); | 678 RangeError.checkValueInInterval(index, 0, string.length); |
677 _checkSplitSurrogate(index); | 679 _checkSplitSurrogate(index); |
678 } | 680 } |
679 | 681 |
680 /** Throw an error if the index is in the middle of a surrogate pair. */ | 682 /** Throw an error if the index is in the middle of a surrogate pair. */ |
681 void _checkSplitSurrogate(int index) { | 683 void _checkSplitSurrogate(int index) { |
682 if (index > 0 && index < string.length && | 684 if (index > 0 && |
| 685 index < string.length && |
683 _isLeadSurrogate(string.codeUnitAt(index - 1)) && | 686 _isLeadSurrogate(string.codeUnitAt(index - 1)) && |
684 _isTrailSurrogate(string.codeUnitAt(index))) { | 687 _isTrailSurrogate(string.codeUnitAt(index))) { |
685 throw new ArgumentError('Index inside surrogate pair: $index'); | 688 throw new ArgumentError('Index inside surrogate pair: $index'); |
686 } | 689 } |
687 } | 690 } |
688 | 691 |
689 /** | 692 /** |
690 * Returns the starting position of the current rune in the string. | 693 * Returns the starting position of the current rune in the string. |
691 * | 694 * |
692 * Returns null if the [current] rune is null. | 695 * Returns null if the [current] rune is null. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 _position = position - 1; | 789 _position = position - 1; |
787 _currentCodePoint = _combineSurrogatePair(prevCodeUnit, codeUnit); | 790 _currentCodePoint = _combineSurrogatePair(prevCodeUnit, codeUnit); |
788 return true; | 791 return true; |
789 } | 792 } |
790 } | 793 } |
791 _position = position; | 794 _position = position; |
792 _currentCodePoint = codeUnit; | 795 _currentCodePoint = codeUnit; |
793 return true; | 796 return true; |
794 } | 797 } |
795 } | 798 } |
OLD | NEW |