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

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

Issue 10868105: Fix string unifizationf for dartc. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Move string.dart to string_base.dart. Created 8 years, 3 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 | « runtime/lib/lib_impl_sources.gypi ('k') | runtime/lib/string_base.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * [StringBase] contains common methods used by concrete String implementations,
7 * e.g., OneByteString.
8 */
9 class StringBase {
10
11 factory StringBase._uninstantiable() {
12 throw const UnsupportedOperationException(
13 "StringBase can't be instaniated");
14 }
15
16 int hashCode() native "String_hashCode";
17
18 /**
19 * Create the most efficient string representation for specified
20 * [codePoints].
21 */
22 static String createFromCharCodes(List<int> charCodes) {
23 ObjectArray objectArray;
24 if (charCodes is ObjectArray) {
25 objectArray = charCodes;
26 } else {
27 int len = charCodes.length;
28 objectArray = new ObjectArray(len);
29 for (int i = 0; i < len; i++) {
30 objectArray[i] = charCodes[i];
31 }
32 }
33 return _createFromCodePoints(objectArray);
34 }
35
36 static String _createFromCodePoints(ObjectArray<int> codePoints)
37 native "StringBase_createFromCodePoints";
38
39 String operator [](int index) native "String_charAt";
40
41 int charCodeAt(int index) native "String_charCodeAt";
42
43 int get length() native "String_getLength";
44
45 bool isEmpty() {
46 return this.length === 0;
47 }
48
49 String concat(String other) native "String_concat";
50
51 String toString() {
52 return this;
53 }
54
55 bool operator ==(Object other) {
56 if (this === other) {
57 return true;
58 }
59 if ((other is !String) ||
60 (this.length != other.length)) {
61 // TODO(5413632): Compare hash codes when both are present.
62 return false;
63 }
64 return this.compareTo(other) === 0;
65 }
66
67 int compareTo(String other) {
68 int thisLength = this.length;
69 int otherLength = other.length;
70 int len = (thisLength < otherLength) ? thisLength : otherLength;
71 for (int i = 0; i < len; i++) {
72 int thisCodePoint = this.charCodeAt(i);
73 int otherCodePoint = other.charCodeAt(i);
74 if (thisCodePoint < otherCodePoint) {
75 return -1;
76 }
77 if (thisCodePoint > otherCodePoint) {
78 return 1;
79 }
80 }
81 if (thisLength < otherLength) return -1;
82 if (thisLength > otherLength) return 1;
83 return 0;
84 }
85
86 bool substringMatches(int start, String other) {
87 if (other.isEmpty()) return true;
88 if ((start < 0) || (start >= this.length)) {
89 return false;
90 }
91 final int len = other.length;
92 if ((start + len) > this.length) {
93 return false;
94 }
95 for (int i = 0; i < len; i++) {
96 if (this.charCodeAt(i + start) != other.charCodeAt(i)) {
97 return false;
98 }
99 }
100 return true;
101 }
102
103 bool endsWith(String other) {
104 return this.substringMatches(this.length - other.length, other);
105 }
106
107 bool startsWith(String other) {
108 return this.substringMatches(0, other);
109 }
110
111 int indexOf(String other, [int start = 0]) {
112 if (other.isEmpty()) {
113 return start < this.length ? start : this.length;
114 }
115 if ((start < 0) || (start >= this.length)) {
116 return -1;
117 }
118 int len = this.length - other.length + 1;
119 for (int index = start; index < len; index++) {
120 if (this.substringMatches(index, other)) {
121 return index;
122 }
123 }
124 return -1;
125 }
126
127 int lastIndexOf(String other, [int start = null]) {
128 if (start == null) start = length - 1;
129 if (other.isEmpty()) {
130 return min(this.length, start);
131 }
132 if (start >= this.length) {
133 start = this.length - 1;
134 }
135 for (int index = start; index >= 0; index--) {
136 if (this.substringMatches(index, other)) {
137 return index;
138 }
139 }
140 return -1;
141 }
142
143 String substring(int startIndex, [int endIndex]) {
144 if (endIndex === null) endIndex = this.length;
145
146 if ((startIndex < 0) || (startIndex > this.length)) {
147 throw new IndexOutOfRangeException(startIndex);
148 }
149 if ((endIndex < 0) || (endIndex > this.length)) {
150 throw new IndexOutOfRangeException(endIndex);
151 }
152 if (startIndex > endIndex) {
153 throw new IndexOutOfRangeException(startIndex);
154 }
155 return _substringUnchecked(startIndex, endIndex);
156 }
157
158 String _substringUnchecked(int startIndex, int endIndex)
159 native "StringBase_substringUnchecked";
160
161 String trim() {
162 final int len = this.length;
163 int first = 0;
164 for (; first < len; first++) {
165 if (!_isWhitespace(this.charCodeAt(first))) {
166 break;
167 }
168 }
169 if (len == first) {
170 // String contains only whitespaces.
171 return "";
172 }
173 int last = len - 1;
174 for (; last >= first; last--) {
175 if (!_isWhitespace(this.charCodeAt(last))) {
176 break;
177 }
178 }
179 if ((first == 0) && (last == (len - 1))) {
180 // Returns this string if it does not have leading or trailing
181 // whitespaces.
182 return this;
183 } else {
184 return _substringUnchecked(first, last + 1);
185 }
186 }
187
188 bool contains(Pattern pattern, [int startIndex = 0]) {
189 if (pattern is String) {
190 return indexOf(pattern, startIndex) >= 0;
191 }
192 return pattern.allMatches(this.substring(startIndex)).iterator().hasNext();
193 }
194
195 String replaceFirst(Pattern pattern, String replacement) {
196 if (pattern is! Pattern) {
197 throw new IllegalArgumentException("${pattern} is not a Pattern");
198 }
199 if (replacement is! String) {
200 throw new IllegalArgumentException("${replacement} is not a String");
201 }
202 StringBuffer buffer = new StringBuffer();
203 int startIndex = 0;
204 Iterator iterator = pattern.allMatches(this).iterator();
205 if (iterator.hasNext()) {
206 Match match = iterator.next();
207 buffer.add(this.substring(startIndex, match.start())).add(replacement);
208 startIndex = match.end();
209 }
210 return buffer.add(this.substring(startIndex)).toString();
211 }
212
213 String replaceAll(Pattern pattern, String replacement) {
214 if (pattern is! Pattern) {
215 throw new IllegalArgumentException("${pattern} is not a Pattern");
216 }
217 if (replacement is! String) {
218 throw new IllegalArgumentException("${replacement} is not a String");
219 }
220 StringBuffer buffer = new StringBuffer();
221 int startIndex = 0;
222 for (Match match in pattern.allMatches(this)) {
223 buffer.add(this.substring(startIndex, match.start())).add(replacement);
224 startIndex = match.end();
225 }
226 return buffer.add(this.substring(startIndex)).toString();
227 }
228
229 /**
230 * Convert all objects in [values] to strings and concat them
231 * into a result string.
232 */
233 static String _interpolate(List values) {
234 int numValues = values.length;
235 var stringList = new ObjectArray(numValues);
236 for (int i = 0; i < numValues; i++) {
237 stringList[i] = values[i].toString();
238 }
239 return _concatAll(stringList);
240 }
241
242 Iterable<Match> allMatches(String str) {
243 List<Match> result = new List<Match>();
244 int length = str.length;
245 int patternLength = this.length;
246 int startIndex = 0;
247 while (true) {
248 int position = str.indexOf(this, startIndex);
249 if (position == -1) {
250 break;
251 }
252 result.add(new _StringMatch(position, str, this));
253 int endIndex = position + patternLength;
254 if (endIndex == length) {
255 break;
256 } else if (position == endIndex) {
257 ++startIndex; // empty match, advance and restart
258 } else {
259 startIndex = endIndex;
260 }
261 }
262 return result;
263 }
264
265 List<String> split(Pattern pattern) {
266 int length = this.length;
267 Iterator iterator = pattern.allMatches(this).iterator();
268 if (length == 0 && iterator.hasNext()) {
269 // A matched empty string input returns the empty list.
270 return <String>[];
271 }
272 List<String> result = new List<String>();
273 int startIndex = 0;
274 int previousIndex = 0;
275 while (true) {
276 if (startIndex == length || !iterator.hasNext()) {
277 result.add(this.substring(previousIndex, length));
278 break;
279 }
280 Match match = iterator.next();
281 if (match.start() == length) {
282 result.add(this.substring(previousIndex, length));
283 break;
284 }
285 int endIndex = match.end();
286 if (startIndex == endIndex && endIndex == previousIndex) {
287 ++startIndex; // empty match, advance and restart
288 continue;
289 }
290 result.add(this.substring(previousIndex, match.start()));
291 startIndex = previousIndex = endIndex;
292 }
293 return result;
294 }
295
296 List<String> splitChars() {
297 int len = this.length;
298 final result = new List<String>(len);
299 for (int i = 0; i < len; i++) {
300 result[i] = this[i];
301 }
302 return result;
303 }
304
305 List<int> charCodes() {
306 int len = this.length;
307 final result = new List<int>(len);
308 for (int i = 0; i < len; i++) {
309 result[i] = this.charCodeAt(i);
310 }
311 return result;
312 }
313
314 String toUpperCase() native "String_toUpperCase";
315
316 String toLowerCase() native "String_toLowerCase";
317
318 // Implementations of Strings methods follow below.
319 static String join(List<String> strings, String separator) {
320 final int length = strings.length;
321 if (length === 0) {
322 return "";
323 }
324
325 List stringsList = strings;
326 if (separator.length != 0) {
327 stringsList = new List(2 * length - 1);
328 stringsList[0] = strings[0];
329 int j = 1;
330 for (int i = 1; i < length; i++) {
331 stringsList[j++] = separator;
332 stringsList[j++] = strings[i];
333 }
334 }
335 return concatAll(stringsList);
336 }
337
338 static String concatAll(List<String> strings) {
339 ObjectArray stringsArray;
340 if (strings is ObjectArray) {
341 stringsArray = strings;
342 } else {
343 int len = strings.length;
344 stringsArray = new ObjectArray(len);
345 for (int i = 0; i < len; i++) {
346 stringsArray[i] = strings[i];
347 }
348 }
349 return _concatAll(stringsArray);
350 }
351
352 static String _concatAll(ObjectArray<String> strings)
353 native "Strings_concatAll";
354 }
355
356
357 class OneByteString extends StringBase implements String {
358 factory OneByteString._uninstantiable() {
359 throw const UnsupportedOperationException(
360 "OneByteString can only be allocated by the VM");
361 }
362
363 // Checks for one-byte whitespaces only.
364 // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid
365 // whitespaces for one byte strings.
366 bool _isWhitespace(int codePoint) {
367 return
368 (codePoint === 32) || // Space.
369 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
370 }
371
372 }
373
374
375 class TwoByteString extends StringBase implements String {
376 factory TwoByteString._uninstantiable() {
377 throw const UnsupportedOperationException(
378 "TwoByteString can only be allocated by the VM");
379 }
380
381 // Checks for one-byte whitespaces only.
382 // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid
383 // whitespaces. Add checking for multi-byte whitespace codepoints.
384 bool _isWhitespace(int codePoint) {
385 return
386 (codePoint === 32) || // Space.
387 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
388 }
389 }
390
391
392 class FourByteString extends StringBase implements String {
393 factory FourByteString._uninstantiable() {
394 throw const UnsupportedOperationException(
395 "FourByteString can only be allocated by the VM");
396 }
397
398 // Checks for one-byte whitespaces only.
399 // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid
400 // whitespaces. Add checking for multi-byte whitespace codepoints.
401 bool _isWhitespace(int codePoint) {
402 return
403 (codePoint === 32) || // Space.
404 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
405 }
406 }
407
408
409 class ExternalOneByteString extends StringBase implements String {
410 factory ExternalOneByteString._uninstantiable() {
411 throw const UnsupportedOperationException(
412 "ExternalOneByteString can only be allocated by the VM");
413 }
414
415 // Checks for one-byte whitespaces only.
416 // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid
417 // whitespaces for one byte strings.
418 bool _isWhitespace(int codePoint) {
419 return
420 (codePoint === 32) || // Space.
421 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
422 }
423 }
424
425
426 class ExternalTwoByteString extends StringBase implements String {
427 factory ExternalTwoByteString._uninstantiable() {
428 throw const UnsupportedOperationException(
429 "ExternalTwoByteString can only be allocated by the VM");
430 }
431
432 // Checks for one-byte whitespaces only.
433 // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid
434 // whitespaces. Add checking for multi-byte whitespace codepoints.
435 bool _isWhitespace(int codePoint) {
436 return
437 (codePoint === 32) || // Space.
438 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
439 }
440 }
441
442
443 class ExternalFourByteString extends StringBase implements String {
444 factory ExternalFourByteString._uninstantiable() {
445 throw const UnsupportedOperationException(
446 "ExternalFourByteString can only be allocated by the VM");
447 }
448
449 // Checks for one-byte whitespaces only.
450 // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid
451 // whitespaces. Add checking for multi-byte whitespace codepoints.
452 bool _isWhitespace(int codePoint) {
453 return
454 (codePoint === 32) || // Space.
455 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
456 }
457 }
458
459
460 class _StringMatch implements Match {
461 const _StringMatch(int this._start,
462 String this.str,
463 String this.pattern);
464
465 int start() => _start;
466 int end() => _start + pattern.length;
467 String operator[](int g) => group(g);
468 int groupCount() => 0;
469
470 String group(int group) {
471 if (group != 0) {
472 throw new IndexOutOfRangeException(group);
473 }
474 return pattern;
475 }
476
477 List<String> groups(List<int> groups) {
478 List<String> result = new List<String>();
479 for (int g in groups) {
480 result.add(group(g));
481 }
482 return result;
483 }
484
485 final int _start;
486 final String str;
487 final String pattern;
488 }
OLDNEW
« no previous file with comments | « runtime/lib/lib_impl_sources.gypi ('k') | runtime/lib/string_base.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698