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

Side by Side Diff: packages/quiver/lib/strings.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 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
« no previous file with comments | « packages/quiver/lib/streams.dart ('k') | packages/quiver/lib/testing/async.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 2013 Google Inc. All Rights Reserved. 1 // Copyright 2013 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 library quiver.strings; 15 library quiver.strings;
16 16
17 /** 17 /// Returns [true] if [s] is either null, empty or is solely made of whitespace
18 * Returns [true] if [s] is either null, empty or is solely made of whitespace 18 /// characters (as defined by [String.trim]).
19 * characters (as defined by [String.trim]).
20 */
21 bool isBlank(String s) => s == null || s.trim().isEmpty; 19 bool isBlank(String s) => s == null || s.trim().isEmpty;
22 20
23 /** 21 /// Returns [true] if [s] is either null or empty.
24 * Returns [true] if [s] is either null or empty.
25 */
26 bool isEmpty(String s) => s == null || s.isEmpty; 22 bool isEmpty(String s) => s == null || s.isEmpty;
27 23
28 /** 24 /// Returns [true] if [s] is a not empty string.
29 * Returns a string with characters from the given [s] in reverse order. 25 bool isNotEmpty(String s) => s != null && s.isNotEmpty;
30 */ 26
31 String flip(String s) { 27 /// Returns a string with characters from the given [s] in reverse order.
28 String reverse(String s) {
32 if (s == null || s == '') return s; 29 if (s == null || s == '') return s;
33 StringBuffer sb = new StringBuffer(); 30 StringBuffer sb = new StringBuffer();
34 var runes = s.runes; 31 var runes = s.runes;
35 for (int i = runes.length - 1; i >= 0; i--) { 32 for (int i = runes.length - 1; i >= 0; i--) {
36 sb.writeCharCode(runes.elementAt(i)); 33 sb.writeCharCode(runes.elementAt(i));
37 } 34 }
38 return sb.toString(); 35 return sb.toString();
39 } 36 }
40 37
41 /** 38 /// Returns a string with characters from the given [s] in reverse order.
42 * If [s] is [null] returns empty string, otherwise returns [s] as is. 39 ///
43 */ 40 /// DEPRECATED: use [reverse] instead.
44 String nullToEmpty(String s) => s == null ? '' : s; 41 @deprecated
42 String flip(String s) => reverse(s);
45 43
46 /** 44 /// Concatenates [s] to itself a given number of [times]. Empty and null
47 * If [s] is an empty string returns [null], otherwise returns [s] as is. 45 /// strings will always result in empty and null strings respectively no matter
48 */ 46 /// how many [times] they are [repeat]ed.
49 String emptyToNull(String s) => s == '' ? null : s; 47 ///
50 48 /// If [times] is negative, returns the reversed string repeated given number
51 /** 49 /// of [times].
52 * Concatenates [s] to itself a given number of [times]. Empty and null 50 ///
53 * strings will always result in empty and null strings respectively no matter 51 /// DEPRECATED: use the `*` operator on [String].
54 * how many [times] they are [repeat]ed. 52 @deprecated
55 *
56 * If [times] is negative, returns the [flip]ped string repeated given number
57 * of [times].
58 */
59 String repeat(String s, int times) { 53 String repeat(String s, int times) {
60 if (s == null || s == '') return s; 54 if (s == null || s == '') return s;
61 if (times < 0) { 55 if (times < 0) {
62 return repeat(flip(s), -times); 56 return repeat(reverse(s), -times);
63 } 57 }
64 StringBuffer sink = new StringBuffer(); 58 StringBuffer sink = new StringBuffer();
65 _repeat(sink, s, times); 59 _repeat(sink, s, times);
66 return sink.toString(); 60 return sink.toString();
67 } 61 }
68 62
69 /** 63 /// Loops over [s] and returns traversed characters. Takes arbitrary [from] and
70 * Loops over [s] and returns traversed characters. Takes arbitrary [from] and 64 /// [to] indices. Works as a substitute for [String.substring], except it never
71 * [to] indices. Works as a substitute for [String.substring], except it never 65 /// throws [RangeError]. Supports negative indices. Think of an index as a
72 * throws [RangeError]. Supports negative indices. Think of an index as a 66 /// coordinate in an infinite in both directions vector filled with repeating
73 * coordinate in an infinite in both directions vector filled with repeating 67 /// string [s], whose 0-th coordinate coincides with the 0-th character in [s].
74 * string [s], whose 0-th coordinate coincides with the 0-th character in [s]. 68 /// Then [loop] returns the sub-vector defined by the interval ([from], [to]).
75 * Then [loop] returns the sub-vector defined by the interval ([from], [to]). 69 /// [from] is inclusive. [to] is exclusive.
76 * [from] is inclusive. [to] is exclusive. 70 ///
77 * 71 /// This method throws exceptions on [null] and empty strings.
78 * This method throws exceptions on [null] and empty strings. 72 ///
79 * 73 /// If [to] is omitted or is [null] the traversing ends at the end of the loop.
80 * If [to] is omitted or is [null] the traversing ends at the end of the loop. 74 ///
81 * 75 /// If [to] < [from], traverses [s] in the opposite direction.
82 * If [to] < [from], traverses [s] in the opposite direction. 76 ///
83 * 77 /// For example:
84 * For example: 78 ///
85 * 79 /// loop('Hello, World!', 7) == 'World!'
86 * loop('Hello, World!', 7) == 'World!' 80 /// loop('ab', 0, 6) == 'ababab'
87 * loop('ab', 0, 6) == 'ababab' 81 /// loop('test.txt', -3) == 'txt'
88 * loop('test.txt', -3) == 'txt' 82 /// loop('ldwor', -3, 2) == 'world'
89 * loop('ldwor', -3, 2) == 'world'
90 */
91 String loop(String s, int from, [int to]) { 83 String loop(String s, int from, [int to]) {
92 if (s == null || s == '') { 84 if (s == null || s == '') {
93 throw new ArgumentError('Input string cannot be null or empty'); 85 throw new ArgumentError('Input string cannot be null or empty');
94 } 86 }
95 if (to != null && to < from) { 87 if (to != null && to < from) {
96 return loop(flip(s), -from, -to); 88 return loop(reverse(s), -from, -to);
97 } 89 }
98 int len = s.length; 90 int len = s.length;
99 int leftFrag = from >= 0 ? from ~/ len : ((from - len) ~/ len); 91 int leftFrag = from >= 0 ? from ~/ len : ((from - len) ~/ len);
100 if (to == null) { 92 if (to == null) {
101 to = (leftFrag + 1) * len; 93 to = (leftFrag + 1) * len;
102 } 94 }
103 int rightFrag = to - 1 >= 0 ? to ~/ len : ((to - len) ~/ len); 95 int rightFrag = to - 1 >= 0 ? to ~/ len : ((to - len) ~/ len);
104 int fragOffset = rightFrag - leftFrag - 1; 96 int fragOffset = rightFrag - leftFrag - 1;
105 if (fragOffset == -1) { 97 if (fragOffset == -1) {
106 return s.substring(from - leftFrag * len, to - rightFrag * len); 98 return s.substring(from - leftFrag * len, to - rightFrag * len);
107 } 99 }
108 StringBuffer sink = new StringBuffer(s.substring(from - leftFrag * len)); 100 StringBuffer sink = new StringBuffer(s.substring(from - leftFrag * len));
109 _repeat(sink, s, fragOffset); 101 _repeat(sink, s, fragOffset);
110 sink.write(s.substring(0, to - rightFrag * len)); 102 sink.write(s.substring(0, to - rightFrag * len));
111 return sink.toString(); 103 return sink.toString();
112 } 104 }
113 105
114 void _repeat(StringBuffer sink, String s, int times) { 106 void _repeat(StringBuffer sink, String s, int times) {
115 for (int i = 0; i < times; i++) { 107 for (int i = 0; i < times; i++) {
116 sink.write(s); 108 sink.write(s);
117 } 109 }
118 } 110 }
119 111
120 /** 112 /// Returns `true` if [rune] represents a digit.
121 * Returns a [String] of length [width] padded on the left with characters from 113 ///
122 * [fill] if `input.length` is less than [width]. [fill] is repeated if 114 /// The definition of digit matches the Unicode `0x3?` range of Western
123 * neccessary to pad. 115 /// European digits.
124 * 116 bool isDigit(int rune) => rune ^ 0x30 <= 9;
125 * Returns [input] if `input.length` is equal to or greater than width. [input]
126 * can be `null` and is treated as an empty string.
127 */
128 @Deprecated('Will be removed in 0.22.0')
129 String padLeft(String input, int width, String fill) {
130 if (fill == null || fill.length == 0) {
131 throw new ArgumentError('fill cannot be null or empty');
132 }
133 if (input == null || input.length == 0) return loop(fill, 0, width);
134 if (input.length >= width) return input;
135 return loop(fill, 0, width - input.length) + input;
136 }
137 117
138 /** 118 /// Returns `true` if [rune] represents a whitespace character.
139 * Returns a [String] of length [width] padded on the right with characters from 119 ///
140 * [fill] if `input.length` is less than [width]. Characters are selected from 120 /// The definition of whitespace matches that used in [String.trim] which is
141 * [fill] starting at the end, so that the last character in [fill] is the last 121 /// based on Unicode 6.2. This maybe be a different set of characters than the
142 * character in the result. [fill] is repeated if neccessary to pad. 122 /// environment's [RegExp] definition for whitespace, which is given by the
143 * 123 /// ECMAScript standard: http://ecma-international.org/ecma-262/5.1/#sec-15.10
144 * Returns [input] if `input.length` is equal to or greater than width. [input]
145 * can be `null` and is treated as an empty string.
146 */
147 @Deprecated('Will be removed in 0.22.0')
148 String padRight(String input, int width, String fill) {
149 if (fill == null || fill.length == 0) {
150 throw new ArgumentError('fill cannot be null or empty');
151 }
152 if (input == null || input.length == 0) {
153 return loop(fill, -width, 0);
154 }
155 if (input.length >= width) return input;
156 return input + loop(fill, input.length - width, 0);
157 }
158
159 /**
160 * Removes leading whitespace from a string.
161 *
162 * Whitespace is defined to be the same as [String.trim].
163 */
164 @Deprecated('Will be removed in 0.22.0')
165 String trimLeft(String input) {
166 int i = 0;
167 for (var rune in input.runes) {
168 if (isWhitespace(rune)) {
169 i++;
170 } else {
171 break;
172 }
173 }
174 return input.substring(i);
175 }
176
177 /**
178 * Removes trailing whitespace from a string.
179 *
180 * Whitespace is defined to be the same as [String.trim].
181 */
182 @Deprecated('Will be removed in 0.22.0')
183 String trimRight(String input) {
184 int i = 0;
185 int lastNonWhitespace = -1;
186 for (var rune in input.runes) {
187 i++;
188 if (!isWhitespace(rune)) {
189 lastNonWhitespace = i;
190 }
191 }
192 if (lastNonWhitespace == -1) return '';
193 return input.substring(0, lastNonWhitespace);
194 }
195
196 /**
197 * Returns `true` if [rune] represents a whitespace character.
198 *
199 * The definition of whitespace matches that used in [String.trim] which is
200 * based on Unicode 6.2. This maybe be a different set of characters than the
201 * environment's [RegExp] definition for whitespace, which is given by the
202 * ECMAScript standard: http://ecma-international.org/ecma-262/5.1/#sec-15.10
203 */
204 bool isWhitespace(int rune) => ((rune >= 0x0009 && rune <= 0x000D) || 124 bool isWhitespace(int rune) => ((rune >= 0x0009 && rune <= 0x000D) ||
205 rune == 0x0020 || 125 rune == 0x0020 ||
206 rune == 0x0085 || 126 rune == 0x0085 ||
207 rune == 0x00A0 || 127 rune == 0x00A0 ||
208 rune == 0x1680 || 128 rune == 0x1680 ||
209 rune == 0x180E || 129 rune == 0x180E ||
210 (rune >= 0x2000 && rune <= 0x200A) || 130 (rune >= 0x2000 && rune <= 0x200A) ||
211 rune == 0x2028 || 131 rune == 0x2028 ||
212 rune == 0x2029 || 132 rune == 0x2029 ||
213 rune == 0x202F || 133 rune == 0x202F ||
214 rune == 0x205F || 134 rune == 0x205F ||
215 rune == 0x3000 || 135 rune == 0x3000 ||
216 rune == 0xFEFF); 136 rune == 0xFEFF);
217 137
218 /** 138 /// Returns a [String] of length [width] padded with the same number of
219 * Returns a [String] of length [width] padded with the same number of 139 /// characters on the left and right from [fill]. On the right, characters are
220 * characters on the left and right from [fill]. On the right, characters are 140 /// selected from [fill] starting at the end so that the last character in
221 * selected from [fill] starting at the end so that the last character in [fill] 141 /// [fill] is the last character in the result. [fill] is repeated if
222 * is the last character in the result. [fill] is repeated if neccessary to pad. 142 /// neccessary to pad.
223 * 143 ///
224 * Returns [input] if `input.length` is equal to or greater than width. [input] 144 /// Returns [input] if `input.length` is equal to or greater than width.
225 * can be `null` and is treated as an empty string. 145 /// [input] can be `null` and is treated as an empty string.
226 * 146 ///
227 * If there are an odd number of characters to pad, then the right will be 147 /// If there are an odd number of characters to pad, then the right will be
228 * padded with one more than the left. 148 /// padded with one more than the left.
229 */
230 String center(String input, int width, String fill) { 149 String center(String input, int width, String fill) {
231 if (fill == null || fill.length == 0) { 150 if (fill == null || fill.length == 0) {
232 throw new ArgumentError('fill cannot be null or empty'); 151 throw new ArgumentError('fill cannot be null or empty');
233 } 152 }
234 if (input == null) input = ''; 153 if (input == null) input = '';
235 var leftWidth = input.length + (width - input.length) ~/ 2; 154 if (input.length >= width) return input;
236 return padRight(padLeft(input, leftWidth, fill), width, fill); 155
156 var padding = width - input.length;
157 if (padding ~/ 2 > 0) {
158 input = loop(fill, 0, padding ~/ 2) + input;
159 }
160 return input + loop(fill, input.length - width, 0);
237 } 161 }
238 162
239 /** 163 /// Returns `true` if [a] and [b] are equal after being converted to lower
240 * Returns `true` if [a] and [b] are equal after being converted to lower case, 164 /// case, or are both null.
241 * or are both null. 165 bool equalsIgnoreCase(String a, String b) =>
242 */ 166 (a == null && b == null) ||
243 bool equalsIgnoreCase(String a, String b) => (a == null && b == null) ||
244 (a != null && b != null && a.toLowerCase() == b.toLowerCase()); 167 (a != null && b != null && a.toLowerCase() == b.toLowerCase());
245 168
246 /** 169 /// Compares [a] and [b] after converting to lower case.
247 * Compares [a] and [b] after converting to lower case. 170 ///
248 * 171 /// Both [a] and [b] must not be null.
249 * Both [a] and [b] must not be null.
250 */
251 int compareIgnoreCase(String a, String b) => 172 int compareIgnoreCase(String a, String b) =>
252 a.toLowerCase().compareTo(b.toLowerCase()); 173 a.toLowerCase().compareTo(b.toLowerCase());
OLDNEW
« no previous file with comments | « packages/quiver/lib/streams.dart ('k') | packages/quiver/lib/testing/async.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698