OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, 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 class StringImplementation implements String native "String" { | |
6 factory StringImplementation.fromValues(List<int> values) { | |
7 return _newFromValues(values); | |
8 } | |
9 | |
10 String operator[](int index) { | |
11 if (0 <= index && index < length) { | |
12 return _indexOperator(index); | |
13 } | |
14 throw new IndexOutOfRangeException(index); | |
15 } | |
16 | |
17 int charCodeAt(int index) { | |
18 if (0 <= index && index < length) { | |
19 return _charCodeAt(index); | |
20 } | |
21 throw new IndexOutOfRangeException(index); | |
22 } | |
23 | |
24 int get length() native; | |
25 | |
26 bool operator ==(var other) native; | |
27 | |
28 bool substringMatches(int start, String other) { | |
29 int len = length; | |
30 int otherLen = other.length; | |
31 if (otherLen == 0) return true; | |
32 if ((start < 0) || (start >= len)) return false; | |
33 if (start + otherLen > len) return false; | |
34 StringImplementation otherImpl = other; | |
35 for (int i = 0; i < otherLen; i++) { | |
36 // We can use the unsafe _charCodeAt. | |
37 if (_charCodeAt(start + i) != otherImpl._charCodeAt(i)) return false; | |
38 } | |
39 return true; | |
40 } | |
41 | |
42 bool endsWith(String other) { | |
43 return substringMatches(length - other.length, other); | |
44 } | |
45 | |
46 bool startsWith(String other) { | |
47 return substringMatches(0, other); | |
48 } | |
49 | |
50 int indexOf(String other, [int start = 0]) { | |
51 return _nativeIndexOf(other, start); | |
52 } | |
53 | |
54 int lastIndexOf(String other, [int start = null]) { | |
55 if (start === null) start = length - 1; | |
56 return _nativeLastIndexOf(other, start); | |
57 } | |
58 | |
59 int _nativeIndexOf(String other, int start) native; | |
60 int _nativeLastIndexOf(String other, int start) native; | |
61 | |
62 bool isEmpty() { | |
63 return length == 0; | |
64 } | |
65 | |
66 String concat(String other) native; | |
67 | |
68 String operator +(Object obj) { | |
69 return this.concat(obj.toString()); | |
70 } | |
71 | |
72 String substring(int startIndex, [int endIndex = null]) { | |
73 if (endIndex == null) endIndex = this.length; | |
74 | |
75 if ((startIndex < 0) || (startIndex > this.length)) { | |
76 throw new IndexOutOfRangeException(startIndex); | |
77 } | |
78 if ((endIndex < 0) || (endIndex > this.length)) { | |
79 throw new IndexOutOfRangeException(endIndex); | |
80 } | |
81 if (startIndex > endIndex) { | |
82 throw new IndexOutOfRangeException(startIndex); | |
83 } | |
84 return _substringUnchecked(startIndex, endIndex); | |
85 } | |
86 | |
87 String trim() native; | |
88 | |
89 bool contains(Pattern pattern, [int startIndex = 0]) { | |
90 if (startIndex < 0 || startIndex > length) { | |
91 throw new IndexOutOfRangeException(startIndex); | |
92 } | |
93 if (pattern is String) { | |
94 return this.indexOf(pattern, startIndex) != -1; | |
95 } else if (pattern is JSSyntaxRegExp) { | |
96 JSSyntaxRegExp regExp = pattern; | |
97 return regExp.hasMatch(_substringUnchecked(startIndex, length)); | |
98 } else { | |
99 String substr = _substringUnchecked(startIndex, length); | |
100 return !pattern.allMatches(substr).iterator().hasNext(); | |
101 } | |
102 } | |
103 | |
104 String replaceFirst(Pattern from, String to) { | |
105 if (from is String || from is JSSyntaxRegExp) { | |
106 return _replace(from, to); | |
107 } else { | |
108 // TODO(floitsch): implement generic String.replace (with patterns). | |
109 throw "StringImplementation.replace(Pattern) UNIMPLEMENTED"; | |
110 } | |
111 } | |
112 | |
113 String replaceAll(Pattern from, String to) { | |
114 if (from is String) { | |
115 if (from == "") { | |
116 if (this == "") { | |
117 return to; | |
118 } else { | |
119 StringBuffer result = new StringBuffer(); | |
120 int len = length; | |
121 result.add(to); | |
122 for (int i = 0; i < len; i++) { | |
123 result.add(this[i]); | |
124 result.add(to); | |
125 } | |
126 return result.toString(); | |
127 } | |
128 } else { | |
129 return _replaceAll(from, to); | |
130 } | |
131 } else if (from is JSSyntaxRegExp) { | |
132 return _replaceAll(from, to); | |
133 } else { | |
134 // TODO(floitsch): implement generic String.replace (with patterns). | |
135 throw "StringImplementation.replaceAll(Pattern) UNIMPLEMENTED"; | |
136 } | |
137 } | |
138 | |
139 List<String> split(Pattern pattern) { | |
140 if (pattern is String || pattern is JSSyntaxRegExp) { | |
141 return _split(pattern); | |
142 } else { | |
143 throw "StringImplementation.split(Pattern) UNIMPLEMENTED"; | |
144 } | |
145 } | |
146 | |
147 Iterable<Match> allMatches(String str) { | |
148 List<Match> result = []; | |
149 if (this.isEmpty()) return result; | |
150 int length = this.length; | |
151 | |
152 int ix = 0; | |
153 while (ix < str.length) { | |
154 int foundIx = str.indexOf(this, ix); | |
155 if (foundIx < 0) break; | |
156 // Call "toString" to coerce the "this" back to a primitive string. | |
157 result.add(new _StringMatch(foundIx, str, this.toString())); | |
158 ix = foundIx + length; | |
159 } | |
160 return result; | |
161 } | |
162 | |
163 List<String> splitChars() { | |
164 return _split(""); | |
165 } | |
166 | |
167 List<int> charCodes() { | |
168 int len = length; | |
169 List<int> result = new List<int>(len); | |
170 for (int i = 0; i < len; i++) { | |
171 // It is safe to call the private function (which doesn't do | |
172 // range-checks). | |
173 result[i] = _charCodeAt(i); | |
174 } | |
175 return result; | |
176 } | |
177 | |
178 String toLowerCase() native; | |
179 String toUpperCase() native; | |
180 | |
181 int hashCode() native; | |
182 | |
183 // Note: we can't just return 'this', because we want the primitive string | |
184 // and not the wrapped String object. | |
185 String toString() native; | |
186 | |
187 int compareTo(String other) native; | |
188 | |
189 static String _newFromValues(List<int> values) native; | |
190 String _indexOperator(int index) native; | |
191 int _charCodeAt(int index) native; | |
192 String _substringUnchecked(int startIndex, int endIndex) native; | |
193 String _replace(Pattern from, String to) native; | |
194 String _replaceAll(Pattern from, String to) native; | |
195 List<String> _split(Pattern pattern) native; | |
196 | |
197 get dynamic() { return toString(); } | |
198 } | |
199 | |
200 class _StringJsUtil { | |
201 static String toDartString(o) native { | |
202 if (o === null) return "null"; | |
203 return o.toString(); | |
204 } | |
205 } | |
206 | |
207 class _StringMatch implements Match { | |
208 const _StringMatch(int this._start, | |
209 String this.str, | |
210 String this.pattern); | |
211 | |
212 int start() => _start; | |
213 int end() => _start + pattern.length; | |
214 String operator[](int g) => group(g); | |
215 int groupCount() => 0; | |
216 | |
217 String group(int group_) { | |
218 if (group_ != 0) { | |
219 throw new IndexOutOfRangeException(group_); | |
220 } | |
221 return pattern; | |
222 } | |
223 | |
224 List<String> groups(List<int> groups_) { | |
225 List<String> result = new List<String>(); | |
226 for (int g in groups_) { | |
227 result.add(group(g)); | |
228 } | |
229 return result; | |
230 } | |
231 | |
232 final int _start; | |
233 final String str; | |
234 final String pattern; | |
235 } | |
OLD | NEW |