2 // Getdown - application installer, patcher and launcher
3 // Copyright (C) 2004-2018 Getdown authors
4 // https://github.com/threerings/getdown/blob/master/LICENSE
6 package com.threerings.getdown.util;
8 import java.util.StringTokenizer;
10 public class StringUtil {
13 * @return true if the specified string could be a valid URL (contains no illegal characters)
15 public static boolean couldBeValidUrl (String url)
17 return url.matches("[A-Za-z0-9\\-\\._~:/\\?#\\[\\]@!$&'\\(\\)\\*\\+,;=%]+");
21 * @return true if the string is null or consists only of whitespace, false otherwise.
23 public static boolean isBlank (String value)
25 for (int ii = 0, ll = (value == null) ? 0 : value.length(); ii < ll; ii++) {
26 if (!Character.isWhitespace(value.charAt(ii))) {
34 * Parses an array of integers from it's string representation. The array should be represented
35 * as a bare list of numbers separated by commas, for example:
37 * <pre>25, 17, 21, 99</pre>
39 * Any inability to parse the int array will result in the function returning null.
41 public static int[] parseIntArray (String source)
43 StringTokenizer tok = new StringTokenizer(source, ",");
44 int[] vals = new int[tok.countTokens()];
45 for (int i = 0; tok.hasMoreTokens(); i++) {
47 // trim the whitespace from the token
48 vals[i] = Integer.parseInt(tok.nextToken().trim());
49 } catch (NumberFormatException nfe) {
57 * Parses an array of strings from a single string. The array should be represented as a bare
58 * list of strings separated by commas, for example:
60 * <pre>mary, had, a, little, lamb, and, an, escaped, comma,,</pre>
62 * If a comma is desired in one of the strings, it should be escaped by putting two commas in a
63 * row. Any inability to parse the string array will result in the function returning null.
65 public static String[] parseStringArray (String source)
67 return parseStringArray(source, false);
71 * Like {@link #parseStringArray(String)} but can be instructed to invoke {@link String#intern}
72 * on the strings being parsed into the array.
74 public static String[] parseStringArray (String source, boolean intern)
76 int tcount = 0, tpos = -1, tstart = 0;
78 // empty strings result in zero length arrays
79 if (source.length() == 0) {
83 // sort out escaped commas
84 source = source.replace(",,", "%COMMA%");
86 // count up the number of tokens
87 while ((tpos = source.indexOf(",", tpos+1)) != -1) {
91 String[] tokens = new String[tcount+1];
92 tpos = -1; tcount = 0;
95 while ((tpos = source.indexOf(",", tpos+1)) != -1) {
96 tokens[tcount] = source.substring(tstart, tpos);
97 tokens[tcount] = tokens[tcount].trim().replace("%COMMA%", ",");
99 tokens[tcount] = tokens[tcount].intern();
105 // grab the last token
106 tokens[tcount] = source.substring(tstart);
107 tokens[tcount] = tokens[tcount].trim().replace("%COMMA%", ",");
113 * @return the supplied string if it is non-null, "" if it is null.
115 public static String deNull (String value)
117 return (value == null) ? "" : value;
121 * Generates a string from the supplied bytes that is the HEX encoded representation of those
122 * bytes. Returns the empty string for a <code>null</code> or empty byte array.
124 * @param bytes the bytes for which we want a string representation.
125 * @param count the number of bytes to stop at (which will be coerced into being {@code <=} the
126 * length of the array).
128 public static String hexlate (byte[] bytes, int count)
134 count = Math.min(count, bytes.length);
135 char[] chars = new char[count*2];
137 for (int i = 0; i < count; i++) {
142 chars[2*i] = XLATE.charAt(val/16);
143 chars[2*i+1] = XLATE.charAt(val%16);
146 return new String(chars);
150 * Generates a string from the supplied bytes that is the HEX encoded representation of those
153 public static String hexlate (byte[] bytes)
155 return (bytes == null) ? "" : hexlate(bytes, bytes.length);
159 * Joins an array of strings (or objects which will be converted to strings) into a single
160 * string separated by commas.
162 public static String join (Object[] values)
164 return join(values, false);
168 * Joins an array of strings into a single string, separated by commas, and optionally escaping
169 * commas that occur in the individual string values such that a subsequent call to {@link
170 * #parseStringArray} would recreate the string array properly. Any elements in the values
171 * array that are null will be treated as an empty string.
173 public static String join (Object[] values, boolean escape)
175 return join(values, ", ", escape);
179 * Joins the supplied array of strings into a single string separated by the supplied
182 public static String join (Object[] values, String separator)
184 return join(values, separator, false);
188 * Helper function for the various <code>join</code> methods.
190 protected static String join (Object[] values, String separator, boolean escape)
192 StringBuilder buf = new StringBuilder();
193 int vlength = values.length;
194 for (int i = 0; i < vlength; i++) {
196 buf.append(separator);
198 String value = (values[i] == null) ? "" : values[i].toString();
199 buf.append((escape) ? value.replace(",", ",,") : value);
201 return buf.toString();
204 /** Used by {@link #hexlate} and {@link #unhexlate}. */
205 protected static final String XLATE = "0123456789abcdef";