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

Side by Side Diff: runtime/lib/string_patch.dart

Issue 949753005: Add String.replaceRange and use it in replaceFirst{,Mapped}. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 5 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 | « no previous file | sdk/lib/_internal/compiler/js_lib/interceptors.dart » ('j') | 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 const int _maxAscii = 0x7f; 5 const int _maxAscii = 0x7f;
6 const int _maxLatin1 = 0xff; 6 const int _maxLatin1 = 0xff;
7 const int _maxUtf16 = 0xffff; 7 const int _maxUtf16 = 0xffff;
8 const int _maxUnicode = 0x10ffff; 8 const int _maxUnicode = 0x10ffff;
9 9
10 patch class String { 10 patch class String {
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 565 }
566 if (startIndex is! int) { 566 if (startIndex is! int) {
567 throw new ArgumentError("${startIndex} is not an int"); 567 throw new ArgumentError("${startIndex} is not an int");
568 } 568 }
569 RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); 569 RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
570 Iterator iterator = 570 Iterator iterator =
571 startIndex == 0 ? pattern.allMatches(this).iterator 571 startIndex == 0 ? pattern.allMatches(this).iterator
572 : pattern.allMatches(this, startIndex).iterator; 572 : pattern.allMatches(this, startIndex).iterator;
573 if (!iterator.moveNext()) return this; 573 if (!iterator.moveNext()) return this;
574 Match match = iterator.current; 574 Match match = iterator.current;
575 return "${this.substring(0, match.start)}" 575 return replaceRange(match.start, match.end, replacement);
576 "$replacement"
577 "${this.substring(match.end)}";
578 } 576 }
579 577
578 String replaceRange(int start, int end, String replacement) {
579 int length = this.length;
580 end = RangeError.checkValidRange(start, end, length);
581 bool replacementIsOneByte = replacement._isOneByte;
582 int replacementLength = replacement.length;
583 int totalLength = start + (length - end) + replacementLength;
584 if (replacementIsOneByte && this._isOneByte) {
585 var result = _OneByteString._allocate(totalLength);
586 int index = 0;
587 index = result._setRange(index, this, 0, start);
588 index = result._setRange(start, replacement, 0, replacementLength);
589 result._setRange(index, this, end, length);
590 return result;
591 }
592 List slices = [];
593 _addReplaceSlice(slices, 0, start);
594 if (replacement.length > 0) slices.add(replacement);
595 _addReplaceSlice(slices, end, length);
596 return _joinReplaceAllResult(this, slices, totalLength,
597 replacementIsOneByte);
598 }
580 599
581 static int _addReplaceSlice(List matches, int start, int end) { 600 static int _addReplaceSlice(List matches, int start, int end) {
582 int length = end - start; 601 int length = end - start;
583 if (length > 0) { 602 if (length > 0) {
584 if (length <= _maxLengthValue && start <= _maxStartValue) { 603 if (length <= _maxLengthValue && start <= _maxStartValue) {
585 matches.add(-((start << _lengthBits) | length)); 604 matches.add(-((start << _lengthBits) | length));
586 } else { 605 } else {
587 matches.add(start); 606 matches.add(start);
588 matches.add(end); 607 matches.add(end);
589 } 608 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 [int startIndex = 0]) { 731 [int startIndex = 0]) {
713 if (pattern == null) throw new ArgumentError.notNull("pattern"); 732 if (pattern == null) throw new ArgumentError.notNull("pattern");
714 if (replace == null) throw new ArgumentError.notNull("replace"); 733 if (replace == null) throw new ArgumentError.notNull("replace");
715 if (startIndex == null) throw new ArgumentError.notNull("startIndex"); 734 if (startIndex == null) throw new ArgumentError.notNull("startIndex");
716 RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); 735 RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
717 736
718 var matches = pattern.allMatches(this, startIndex).iterator; 737 var matches = pattern.allMatches(this, startIndex).iterator;
719 if (!matches.moveNext()) return this; 738 if (!matches.moveNext()) return this;
720 var match = matches.current; 739 var match = matches.current;
721 var replacement = "${replace(match)}"; 740 var replacement = "${replace(match)}";
722 var slices = []; 741 return replaceRange(match.start, match.end, replacement);
723 int length = 0;
724 if (match.start > 0) {
725 length += _addReplaceSlice(slices, 0, match.start);
726 }
727 slices.add(replacement);
728 length += replacement.length;
729 if (match.end < this.length) {
730 length += _addReplaceSlice(slices, match.end, this.length);
731 }
732 bool replacementIsOneByte = replacement._isOneByte;
733 if (replacementIsOneByte &&
734 length < _maxJoinReplaceOneByteStringLength &&
735 this._isOneByte) {
736 return _joinReplaceAllOneByteResult(this, slices, length);
737 }
738 return _joinReplaceAllResult(this, slices, length, replacementIsOneByte);
739 } 742 }
740 743
741 static String _matchString(Match match) => match[0]; 744 static String _matchString(Match match) => match[0];
742 static String _stringIdentity(String string) => string; 745 static String _stringIdentity(String string) => string;
743 746
744 String _splitMapJoinEmptyString(String onMatch(Match match), 747 String _splitMapJoinEmptyString(String onMatch(Match match),
745 String onNonMatch(String nonMatch)) { 748 String onNonMatch(String nonMatch)) {
746 // Pattern is the empty string. 749 // Pattern is the empty string.
747 StringBuffer buffer = new StringBuffer(); 750 StringBuffer buffer = new StringBuffer();
748 int length = this.length; 751 int length = this.length;
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 static _OneByteString _allocate(int length) native "OneByteString_allocate"; 1212 static _OneByteString _allocate(int length) native "OneByteString_allocate";
1210 1213
1211 1214
1212 static _OneByteString _allocateFromOneByteList(List<int> list, 1215 static _OneByteString _allocateFromOneByteList(List<int> list,
1213 int start, int end) 1216 int start, int end)
1214 native "OneByteString_allocateFromOneByteList"; 1217 native "OneByteString_allocateFromOneByteList";
1215 1218
1216 // This is internal helper method. Code point value must be a valid 1219 // This is internal helper method. Code point value must be a valid
1217 // Latin1 value (0..0xFF), index must be valid. 1220 // Latin1 value (0..0xFF), index must be valid.
1218 void _setAt(int index, int codePoint) native "OneByteString_setAt"; 1221 void _setAt(int index, int codePoint) native "OneByteString_setAt";
1222
1223 // Should be optimizable to a memory move.
1224 // Accepts both _OneByteString and _ExternalOneByteString as argument.
1225 // Returns index after last character written.
1226 int _setRange(int index, String oneByteString, int start, int end) {
1227 assert(oneByteString._isOneByte);
1228 assert(0 <= start);
1229 assert(start <= end);
1230 assert(end <= oneByteString.length);
1231 assert(0 <= index);
1232 assert(index + (end - start) <= length);
1233 for (int i = start; i < end; i++) {
1234 _setAt(index, oneByteString.codeUnitAt(i));
1235 index += 1;
1236 }
1237 return index;
1238 }
1219 } 1239 }
1220 1240
1221 1241
1222 class _TwoByteString extends _StringBase implements String { 1242 class _TwoByteString extends _StringBase implements String {
1223 factory _TwoByteString._uninstantiable() { 1243 factory _TwoByteString._uninstantiable() {
1224 throw new UnsupportedError( 1244 throw new UnsupportedError(
1225 "_TwoByteString can only be allocated by the VM"); 1245 "_TwoByteString can only be allocated by the VM");
1226 } 1246 }
1227 1247
1228 static String _allocateFromTwoByteList(List list, int start, int end) 1248 static String _allocateFromTwoByteList(List list, int start, int end)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 for (int g in groups) { 1313 for (int g in groups) {
1294 result.add(group(g)); 1314 result.add(group(g));
1295 } 1315 }
1296 return result; 1316 return result;
1297 } 1317 }
1298 1318
1299 final int start; 1319 final int start;
1300 final String input; 1320 final String input;
1301 final String pattern; 1321 final String pattern;
1302 } 1322 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/js_lib/interceptors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698