Mercurial > hg > truffle
comparison graal/com.oracle.max.base/src/com/sun/max/lang/Strings.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | bc8527f3071c |
comparison
equal
deleted
inserted
replaced
3732:3e2e8b8abdaf | 3733:e233f5660da4 |
---|---|
1 /* | |
2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.sun.max.lang; | |
24 | |
25 import java.io.*; | |
26 import java.util.*; | |
27 | |
28 /** | |
29 * Additional String-related operations. | |
30 */ | |
31 public final class Strings { | |
32 | |
33 private Strings() { | |
34 } | |
35 | |
36 /** | |
37 * @param stream | |
38 * the input stream to be read in its entirety and then closed | |
39 * @return the contents of the input stream as a String, with line breaks | |
40 * @throws IOException | |
41 * as usual | |
42 */ | |
43 public static String fromInputStream(InputStream stream) throws IOException { | |
44 final BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); | |
45 final StringBuffer result = new StringBuffer(); | |
46 final String lineSeparator = System.getProperty("line.separator"); | |
47 while (true) { | |
48 final String line = reader.readLine(); | |
49 if (line == null) { | |
50 stream.close(); | |
51 return result.toString(); | |
52 } | |
53 result.append(line); | |
54 result.append(lineSeparator); | |
55 } | |
56 } | |
57 | |
58 public static String firstCharToLowerCase(String s) { | |
59 if (s == null || s.length() == 0) { | |
60 return s; | |
61 } | |
62 return s.substring(0, 1).toLowerCase() + s.substring(1); | |
63 } | |
64 | |
65 public static String firstCharToUpperCase(String s) { | |
66 if (s == null || s.length() == 0) { | |
67 return s; | |
68 } | |
69 return s.substring(0, 1).toUpperCase() + s.substring(1); | |
70 } | |
71 | |
72 public static String times(char ch, int nTimes) { | |
73 if (nTimes <= 0) { | |
74 return ""; | |
75 } | |
76 final char[] chars = new char[nTimes]; | |
77 for (int i = 0; i < nTimes; i++) { | |
78 chars[i] = ch; | |
79 } | |
80 return new String(chars); | |
81 } | |
82 | |
83 private static final char[] SPACES; | |
84 static { | |
85 SPACES = new char[200]; | |
86 java.util.Arrays.fill(SPACES, ' '); | |
87 } | |
88 | |
89 public static String spaces(int nSpaces) { | |
90 if (nSpaces <= 0) { | |
91 return ""; | |
92 } | |
93 if (nSpaces <= SPACES.length) { | |
94 return new String(SPACES, 0, nSpaces); | |
95 } | |
96 return times(' ', nSpaces); | |
97 } | |
98 | |
99 /** | |
100 * @return The String {@code s} padded out to {@code length}, if needed, by appending space characters | |
101 */ | |
102 public static String padLengthWithSpaces(String s, int length) { | |
103 if (s.length() >= length) { | |
104 return s; | |
105 } | |
106 return s + spaces(length - s.length()); | |
107 } | |
108 | |
109 /** | |
110 * @return The string {@code s} padded out to {@code length}, if needed, by prepending space characters | |
111 */ | |
112 public static String padLengthWithSpaces(int length, String s) { | |
113 if (s.length() >= length) { | |
114 return s; | |
115 } | |
116 return spaces(length - s.length()) + s; | |
117 } | |
118 | |
119 private static final char[] ZEROES; | |
120 static { | |
121 ZEROES = new char[200]; | |
122 java.util.Arrays.fill(ZEROES, '0'); | |
123 } | |
124 | |
125 public static String zeroes(int nZeroes) { | |
126 if (nZeroes <= 0) { | |
127 return ""; | |
128 } | |
129 if (nZeroes <= ZEROES.length) { | |
130 return new String(ZEROES, 0, nZeroes); | |
131 } | |
132 return times(' ', nZeroes); | |
133 } | |
134 | |
135 /** | |
136 * @return The String {@code s} padded out to {@code length}, if needed, by appending zero characters | |
137 */ | |
138 public static String padLengthWithZeroes(String s, int length) { | |
139 if (s.length() >= length) { | |
140 return s; | |
141 } | |
142 return s + zeroes(length - s.length()); | |
143 } | |
144 | |
145 /** | |
146 * @return The string {@code s} padded out to {@code length}, if needed, by prepending zero characters | |
147 */ | |
148 public static String padLengthWithZeroes(int length, String s) { | |
149 if (s.length() >= length) { | |
150 return s; | |
151 } | |
152 return zeroes(length - s.length()) + s; | |
153 } | |
154 | |
155 /** | |
156 * Finds the index of the first non-escaped instance of {@code c} in {@code s} starting at {@code fromIndex}. | |
157 * The search takes into account that the escape char (i.e. {@code '\'}) may itself be escaped. | |
158 * | |
159 * @return -1 if the char could not be found | |
160 */ | |
161 public static int indexOfNonEscapedChar(char c, String s, int fromIndex) { | |
162 int index = s.indexOf(c, fromIndex); | |
163 while (index != -1) { | |
164 if (index > 0 && (s.charAt(index - 1) != '\\') || (index > 1 && s.charAt(index - 2) == '\\')) { | |
165 return index; | |
166 } | |
167 index = s.indexOf(c, index + 1); | |
168 } | |
169 return -1; | |
170 } | |
171 | |
172 /** | |
173 * Parses a command line into a string array appropriate for calling {@link Runtime#exec(String[])}. | |
174 * The given command line is tokenized around {@link Character#isWhitespace(char) whitespaces} | |
175 * except for sequences of characters enclosed in non-escaped double quotes (after the double | |
176 * quotes are removed). | |
177 */ | |
178 public static String[] splitCommand(String command) { | |
179 final List<String> parts = new ArrayList<String>(); | |
180 | |
181 boolean escapedChar = false; | |
182 boolean insideQuotes = false; | |
183 | |
184 final char[] buffer = new char[command.length()]; | |
185 int pos = 0; | |
186 | |
187 for (int index = 0; index < command.length(); ++index) { | |
188 final char ch = command.charAt(index); | |
189 if (escapedChar) { | |
190 escapedChar = false; | |
191 } else { | |
192 if (ch == '\\') { | |
193 escapedChar = true; | |
194 } else { | |
195 if (insideQuotes) { | |
196 if (ch == '"') { | |
197 insideQuotes = false; | |
198 continue; | |
199 } | |
200 } else { | |
201 if (ch == '"') { | |
202 insideQuotes = true; | |
203 continue; | |
204 } else if (Character.isWhitespace(ch)) { | |
205 if (pos != 0) { | |
206 parts.add(new String(buffer, 0, pos)); | |
207 pos = 0; | |
208 } | |
209 continue; | |
210 | |
211 } | |
212 } | |
213 } | |
214 } | |
215 buffer[pos++] = ch; | |
216 } | |
217 | |
218 if (insideQuotes) { | |
219 throw new IllegalArgumentException("unclosed quotes"); | |
220 } | |
221 if (escapedChar) { | |
222 throw new IllegalArgumentException("command line cannot end with escape char '\\'"); | |
223 } | |
224 if (pos != 0) { | |
225 parts.add(new String(buffer, 0, pos)); | |
226 } | |
227 return parts.toArray(new String[parts.size()]); | |
228 } | |
229 | |
230 public static String truncate(String s, int maxLength) { | |
231 if (maxLength < 0) { | |
232 throw new IllegalArgumentException(); | |
233 } | |
234 if (s.length() <= maxLength) { | |
235 return s; | |
236 } | |
237 return s.substring(0, maxLength) + "..."; | |
238 } | |
239 | |
240 /** | |
241 * Capitalizes the first character in a given string. | |
242 * | |
243 * @param string the string to process | |
244 * @param lowercaseTail if true, the remaining characters in {@code string} are converted to lower case | |
245 */ | |
246 public static String capitalizeFirst(String string, boolean lowercaseTail) { | |
247 final String tail = string.substring(1); | |
248 return Character.toUpperCase(string.charAt(0)) + (lowercaseTail ? tail.toLowerCase() : tail); | |
249 } | |
250 | |
251 /** | |
252 * Chops the last {@code count} from a given string. | |
253 * | |
254 * @param s the string to chop | |
255 * @param count the number of characters to chop from the end of {@code s} | |
256 * @return the chopped string | |
257 * @throws IndexOutOfBoundsException if {@code count < 0} or {@code count > s.length()} | |
258 */ | |
259 public static String chopSuffix(String s, int count) { | |
260 return s.substring(0, s.length() - count); | |
261 } | |
262 | |
263 /** | |
264 * Chops the last {@code suffix.length()} from a given string. Calling this method is | |
265 * equivalent to {@link #chopSuffix(String, int) chop(s, suffix.length())}. | |
266 */ | |
267 public static String chopSuffix(String s, String suffix) { | |
268 return chopSuffix(s, suffix.length()); | |
269 } | |
270 | |
271 /** | |
272 * Prepends {@code n} space characters to every line in String {@code lines}, | |
273 * including a possibly non-empty line following the final newline. | |
274 * Returns {@code lines} if {@code spaces <= 0} | |
275 */ | |
276 public static String indent(String lines, int spaces) { | |
277 return indent(lines, spaces(spaces)); | |
278 } | |
279 | |
280 /** | |
281 * Prepends the String {@code indentation} to every line in String {@code lines}, | |
282 * including a possibly non-empty line following the final newline. | |
283 */ | |
284 public static String indent(String lines, String indentation) { | |
285 if (lines.length() == 0) { | |
286 return lines; | |
287 } | |
288 final String newLine = "\n"; | |
289 if (lines.endsWith(newLine)) { | |
290 return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine; | |
291 } | |
292 return indentation + lines.replace(newLine, newLine + indentation); | |
293 } | |
294 | |
295 public static String formatParagraphs(String s, int leftJust, int pindent, int width) { | |
296 final int len = s.length(); | |
297 int indent = pindent; | |
298 indent += leftJust; | |
299 int consumed = indent + leftJust; | |
300 final String indstr = space(indent); | |
301 final String ljstr = space(leftJust); | |
302 final StringBuffer buf = new StringBuffer(s.length() + 50); | |
303 buf.append(indstr); | |
304 int lastSp = -1; | |
305 for (int cntr = 0; cntr < len; cntr++) { | |
306 final char c = s.charAt(cntr); | |
307 if (c == '\n') { | |
308 buf.append('\n'); | |
309 consumed = indent; | |
310 buf.append(indstr); | |
311 continue; | |
312 } else if (Character.isWhitespace(c)) { | |
313 lastSp = buf.length(); | |
314 } | |
315 buf.append(c); | |
316 consumed++; | |
317 | |
318 if (consumed > width) { | |
319 if (lastSp >= 0) { | |
320 buf.setCharAt(lastSp, '\n'); | |
321 buf.insert(lastSp + 1, ljstr); | |
322 consumed = buf.length() - lastSp + leftJust - 1; | |
323 } | |
324 } | |
325 } | |
326 return buf.toString(); | |
327 } | |
328 | |
329 protected static final String[] spacers = { | |
330 "", // 0 | |
331 " ", // 1 | |
332 " ", // 2 | |
333 " ", // 3 | |
334 " ", // 4 | |
335 " ", // 5 | |
336 " ", // 6 | |
337 " ", // 7 | |
338 " ", // 8 | |
339 " ", // 9 | |
340 " ", // 10 | |
341 }; | |
342 | |
343 public static void appendFract(StringBuffer buf, double val, int digits) { | |
344 int cntr = 0; | |
345 for (int radix = 10; cntr < digits; radix = radix * 10, cntr++) { | |
346 if (cntr == 0) { | |
347 buf.append('.'); | |
348 } | |
349 final int digit = (int) (val * radix) % 10; | |
350 buf.append((char) (digit + '0')); | |
351 } | |
352 } | |
353 | |
354 public static String fixedDouble(double fval, int places) { | |
355 if (Double.isInfinite(fval)) { | |
356 return "(inf)"; | |
357 } | |
358 if (Double.isNaN(fval)) { | |
359 return "(NaN)"; | |
360 } | |
361 | |
362 final StringBuffer buf = new StringBuffer(places + 5); | |
363 // append the whole part | |
364 final long val = (long) fval; | |
365 buf.append(val); | |
366 // append the fractional part | |
367 final double fract = fval >= 0 ? fval - val : val - fval; | |
368 appendFract(buf, fract, places); | |
369 | |
370 return buf.toString(); | |
371 } | |
372 | |
373 public static String space(int len) { | |
374 if (len <= 0) { | |
375 return ""; | |
376 } | |
377 if (len < spacers.length) { | |
378 return spacers[len]; | |
379 } | |
380 return times(' ', len); | |
381 } | |
382 | |
383 public static void space(StringBuffer buf, int len) { | |
384 int i = 0; | |
385 while (i++ < len) { | |
386 buf.append(' '); | |
387 } | |
388 } | |
389 | |
390 public static String concat(String first, String second, String separator) { | |
391 if (!first.isEmpty()) { | |
392 return first + separator + second; | |
393 } | |
394 return second; | |
395 } | |
396 | |
397 } |