| 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 patch class String { | 5 patch class String { |
| 6 /* patch */ factory String.fromCharCodes(Iterable<int> charCodes) { | 6 /* patch */ factory String.fromCharCodes(Iterable<int> charCodes) { |
| 7 return _StringBase.createFromCharCodes(charCodes); | 7 return _StringBase.createFromCharCodes(charCodes); |
| 8 } | 8 } |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 return true; | 131 return true; |
| 132 } | 132 } |
| 133 | 133 |
| 134 bool endsWith(String other) { | 134 bool endsWith(String other) { |
| 135 return _substringMatches(this.length - other.length, other); | 135 return _substringMatches(this.length - other.length, other); |
| 136 } | 136 } |
| 137 | 137 |
| 138 bool startsWith(Pattern pattern, [int index = 0]) { | 138 bool startsWith(Pattern pattern, [int index = 0]) { |
| 139 if (index < 0 || index > this.length) { | 139 if ((index < 0) || (index > this.length)) { |
| 140 throw new RangeError.range(index, 0, this.length); | 140 throw new RangeError.range(index, 0, this.length); |
| 141 } | 141 } |
| 142 if (pattern is String) { | 142 if (pattern is String) { |
| 143 return _substringMatches(index, pattern); | 143 return _substringMatches(index, pattern); |
| 144 } | 144 } |
| 145 return pattern.matchAsPrefix(this, index) != null; | 145 return pattern.matchAsPrefix(this, index) != null; |
| 146 } | 146 } |
| 147 | 147 |
| 148 int indexOf(Pattern pattern, [int start = 0]) { | 148 int indexOf(Pattern pattern, [int start = 0]) { |
| 149 if (start < 0 || start > this.length) { | 149 if ((start < 0) || (start > this.length)) { |
| 150 throw new RangeError.range(start, 0, this.length); | 150 throw new RangeError.range(start, 0, this.length); |
| 151 } | 151 } |
| 152 if (pattern is String) { | 152 if (pattern is String) { |
| 153 String other = pattern; | 153 String other = pattern; |
| 154 int maxIndex = this.length - other.length; | 154 int maxIndex = this.length - other.length; |
| 155 // TODO: Use an efficient string search (e.g. BMH). | 155 // TODO: Use an efficient string search (e.g. BMH). |
| 156 for (int index = start; index <= maxIndex; index++) { | 156 for (int index = start; index <= maxIndex; index++) { |
| 157 if (_substringMatches(index, other)) { | 157 if (_substringMatches(index, other)) { |
| 158 return index; | 158 return index; |
| 159 } | 159 } |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 _OneByteString e = strings[i]; | 569 _OneByteString e = strings[i]; |
| 570 final eLength = e.length; | 570 final eLength = e.length; |
| 571 for (int s = 0; s < eLength; s++) { | 571 for (int s = 0; s < eLength; s++) { |
| 572 res._setAt(rIx++, e.codeUnitAt(s)); | 572 res._setAt(rIx++, e.codeUnitAt(s)); |
| 573 } | 573 } |
| 574 } | 574 } |
| 575 return res; | 575 return res; |
| 576 } | 576 } |
| 577 | 577 |
| 578 int indexOf(Pattern pattern, [int start = 0]) { | 578 int indexOf(Pattern pattern, [int start = 0]) { |
| 579 final len = this.length; | |
| 580 // Specialize for single character pattern. | 579 // Specialize for single character pattern. |
| 581 // TODO(srdjan): Implement for other string classes. | 580 final pCid = pattern._cid; |
| 582 if ((pattern._cid == _OneByteString._classId) && | 581 if ((pCid == _OneByteString._classId) || |
| 583 (pattern.length == 1) && | 582 (pCid == _TwoByteString._classId) || |
| 584 (start >= 0) && (start < len)) { | 583 (pCid == _ExternalOneByteString._classId)) { |
| 585 final patternCu0 = pattern.codeUnitAt(0); | 584 final len = this.length; |
| 586 for (int i = start; i < len; i++) { | 585 if ((pattern.length == 1) && (start >= 0) && (start < len)) { |
| 587 if (this.codeUnitAt(i) == patternCu0) { | 586 final patternCu0 = pattern.codeUnitAt(0); |
| 588 return i; | 587 if (patternCu0 > 0xFF) { |
| 588 return -1; |
| 589 } | 589 } |
| 590 for (int i = start; i < len; i++) { |
| 591 if (this.codeUnitAt(i) == patternCu0) { |
| 592 return i; |
| 593 } |
| 594 } |
| 595 return -1; |
| 590 } | 596 } |
| 591 return -1; | |
| 592 } | 597 } |
| 593 return super.indexOf(pattern, start); | 598 return super.indexOf(pattern, start); |
| 594 } | 599 } |
| 595 | 600 |
| 596 // Allocates a string of given length, expecting its content to be | 601 // Allocates a string of given length, expecting its content to be |
| 597 // set using _setAt. | 602 // set using _setAt. |
| 598 static _OneByteString _allocate(int length) native "OneByteString_allocate"; | 603 static _OneByteString _allocate(int length) native "OneByteString_allocate"; |
| 599 | 604 |
| 600 // This is internal helper method. Code point value must be a valid | 605 // This is internal helper method. Code point value must be a valid |
| 601 // Latin1 value (0..0xFF), index must be valid. | 606 // Latin1 value (0..0xFF), index must be valid. |
| 602 void _setAt(int index, int codePoint) native "OneByteString_setAt"; | 607 void _setAt(int index, int codePoint) native "OneByteString_setAt"; |
| 603 } | 608 } |
| 604 | 609 |
| 605 | 610 |
| 606 class _TwoByteString extends _StringBase implements String { | 611 class _TwoByteString extends _StringBase implements String { |
| 612 static final int _classId = "\u{FFFF}"._cid; |
| 613 |
| 607 factory _TwoByteString._uninstantiable() { | 614 factory _TwoByteString._uninstantiable() { |
| 608 throw new UnsupportedError( | 615 throw new UnsupportedError( |
| 609 "_TwoByteString can only be allocated by the VM"); | 616 "_TwoByteString can only be allocated by the VM"); |
| 610 } | 617 } |
| 611 | 618 |
| 612 bool _isWhitespace(int codePoint) { | 619 bool _isWhitespace(int codePoint) { |
| 613 return _StringBase._isTwoByteWhitespace(codePoint); | 620 return _StringBase._isTwoByteWhitespace(codePoint); |
| 614 } | 621 } |
| 615 | 622 |
| 616 bool operator ==(Object other) { | 623 bool operator ==(Object other) { |
| 617 return super == other; | 624 return super == other; |
| 618 } | 625 } |
| 619 } | 626 } |
| 620 | 627 |
| 621 | 628 |
| 622 class _ExternalOneByteString extends _StringBase implements String { | 629 class _ExternalOneByteString extends _StringBase implements String { |
| 630 static final int _classId = _getCid(); |
| 631 |
| 623 factory _ExternalOneByteString._uninstantiable() { | 632 factory _ExternalOneByteString._uninstantiable() { |
| 624 throw new UnsupportedError( | 633 throw new UnsupportedError( |
| 625 "_ExternalOneByteString can only be allocated by the VM"); | 634 "_ExternalOneByteString can only be allocated by the VM"); |
| 626 } | 635 } |
| 627 | 636 |
| 628 bool _isWhitespace(int codePoint) { | 637 bool _isWhitespace(int codePoint) { |
| 629 return _StringBase._isOneByteWhitespace(codePoint); | 638 return _StringBase._isOneByteWhitespace(codePoint); |
| 630 } | 639 } |
| 631 | 640 |
| 632 bool operator ==(Object other) { | 641 bool operator ==(Object other) { |
| 633 return super == other; | 642 return super == other; |
| 634 } | 643 } |
| 644 |
| 645 static int _getCid() native "ExternalOneByteString_getCid"; |
| 635 } | 646 } |
| 636 | 647 |
| 637 | 648 |
| 638 class _ExternalTwoByteString extends _StringBase implements String { | 649 class _ExternalTwoByteString extends _StringBase implements String { |
| 639 factory _ExternalTwoByteString._uninstantiable() { | 650 factory _ExternalTwoByteString._uninstantiable() { |
| 640 throw new UnsupportedError( | 651 throw new UnsupportedError( |
| 641 "_ExternalTwoByteString can only be allocated by the VM"); | 652 "_ExternalTwoByteString can only be allocated by the VM"); |
| 642 } | 653 } |
| 643 | 654 |
| 644 bool _isWhitespace(int codePoint) { | 655 bool _isWhitespace(int codePoint) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 class _CodeUnits extends Object with ListMixin<int>, | 697 class _CodeUnits extends Object with ListMixin<int>, |
| 687 UnmodifiableListMixin<int> { | 698 UnmodifiableListMixin<int> { |
| 688 /** The string that this is the code units of. */ | 699 /** The string that this is the code units of. */ |
| 689 String _string; | 700 String _string; |
| 690 | 701 |
| 691 _CodeUnits(this._string); | 702 _CodeUnits(this._string); |
| 692 | 703 |
| 693 int get length => _string.length; | 704 int get length => _string.length; |
| 694 int operator[](int i) => _string.codeUnitAt(i); | 705 int operator[](int i) => _string.codeUnitAt(i); |
| 695 } | 706 } |
| OLD | NEW |