package com.laytonsmith.PureUtilities.Common;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*/
public final class StringUtils {
private StringUtils() {
//
}
/**
* Joins a map together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object)
*
* @param map The map to concatenate
* @param entryGlue The glue to use between the key and value of each pair
* in the map
* @param elementGlue The glue to use between each key-value element pairs
* in the map
* @return The concatenated string
*/
public static String Join(Map map, String entryGlue, String elementGlue) {
return Join(map, entryGlue, elementGlue, null, null, null);
}
/**
* Joins a map together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object)
*
* @param map The map to concatenate
* @param entryGlue The glue to use between the key and value of each pair
* in the map
* @param elementGlue The glue to use between each key-value element pairs
* in the map
* @param lastElementGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the map, then this glue
* is used instead. If it is null, then lastElementGlue is used instead.
* @param empty If the map is completely empty, this string is simply
* returned. If null, an empty string is used.
* @return The concatenated string
*/
public static String Join(Map map, String entryGlue, String elementGlue, String lastElementGlue) {
return Join(map, entryGlue, elementGlue, lastElementGlue, null, null);
}
/**
* Joins a map together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object)
*
* @param map The map to concatenate
* @param entryGlue The glue to use between the key and value of each pair
* in the map
* @param elementGlue The glue to use between each key-value element pairs
* in the map
* @param lastElementGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the map, then this glue
* is used instead. If it is null, then lastElementGlue is used instead.
* @return The concatenated string
*/
public static String Join(Map map, String entryGlue, String elementGlue, String lastElementGlue, String elementGlueForTwoItems) {
return Join(map, entryGlue, elementGlue, lastElementGlue, elementGlueForTwoItems, null);
}
/**
* Joins a map together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object)
*
* @param map The map to concatenate
* @param entryGlue The glue to use between the key and value of each pair
* in the map
* @param elementGlue The glue to use between each key-value element pairs
* in the map
* @param lastElementGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the map, then this glue
* is used instead. If it is null, then lastElementGlue is used instead.
* @param empty If the map is completely empty, this string is simply
* returned. If null, an empty string is used.
* @return The concatenated string
*/
public static String Join(Map map, String entryGlue, String elementGlue, String lastElementGlue, String elementGlueForTwoItems, String empty) {
//Just create a list of glued together entries, then send it to the other Join method
List<String> list = new ArrayList<String>();
for (Object key : map.keySet()) {
StringBuilder b = new StringBuilder();
b.append(key).append(entryGlue).append(map.get(key));
list.add(b.toString());
}
return Join(list, elementGlue, lastElementGlue, elementGlueForTwoItems, empty);
}
/**
* Joins a set together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue.
* @param list The set to concatenate
* @param glue The glue to use
* @return The concatenated string
*/
public static String Join(Set set, String glue) {
return Join(set, glue, null, null, null);
}
/**
* Joins a set together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for sets that are being read by a human, to have a proper
* conjunction at the end.
* @param list The set to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @return The concatenated string
*/
public static String Join(Set set, String glue, String lastGlue) {
return Join(set, glue, lastGlue, null, null);
}
/**
* Joins a set together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for sets that are being read by a human, to have a proper
* conjunction at the end.
* @param list The set to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the set, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @return The concatenated string
*/
public static String Join(Set set, String glue, String lastGlue, String glueForTwoItems) {
return Join(set, glue, lastGlue, glueForTwoItems, null);
}
/**
* Joins a set together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for sets that are being read by a human, to have a proper
* conjunction at the end.
* @param list The set to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the set, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @param empty If the set is completely empty, this string is simply
* returned. If null, an empty string is used.
* @return The concatenated string
*/
public static String Join(Set set, String glue, String lastGlue, String glueForTwoItems, String empty) {
return Join(set, glue, lastGlue, glueForTwoItems, empty, null);
}
/**
* Joins a set together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for sets that are being read by a human, to have a proper
* conjunction at the end.
* @param list The set to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the set, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @param empty If the set is completely empty, this string is simply
* returned. If null, an empty string is used.
* @return The concatenated string
*/
public static <T> String Join(Set<T> set, String glue, String lastGlue, String glueForTwoItems, String empty, Renderer<T> renderer) {
final List<T> list = new ArrayList<T>(set);
return doJoin(new ItemGetter<T>() {
@Override
public T get(int index) {
return list.get(index);
}
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
}, glue, lastGlue, glueForTwoItems, empty, renderer);
}
/**
* Joins an array together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue.
* @param list The array to concatenate
* @param glue The glue to use
* @return The concatenated string
*/
public static String Join(Object[] list, String glue) {
return Join(list, glue, null, null, null);
}
/**
* Joins an array together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The array to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @return The concatenated string
*/
public static String Join(Object[] list, String glue, String lastGlue) {
return Join(list, glue, lastGlue, null, null);
}
/**
* Joins an array together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The array to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the array, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @return The concatenated string
*/
public static String Join(Object[] list, String glue, String lastGlue, String glueForTwoItems) {
return Join(list, glue, lastGlue, glueForTwoItems, null);
}
/**
* Joins an array together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The array to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the array, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @param empty If the array is completely empty, this string is simply
* returned. If null, an empty string is used.
* @return The concatenated string
*/
public static String Join(Object[] list, String glue, String lastGlue, String glueForTwoItems, String empty) {
return Join(list, glue, lastGlue, glueForTwoItems, empty, null);
}
/**
* Joins an array together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The array to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the array, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @param empty If the array is completely empty, this string is simply
* returned. If null, an empty string is used.
* @param renderer The item renderer. This renders each item in the list,
* one at a time. If null, toString will be used by default on each item.
* @return The concatenated string
*/
public static String Join(final Object[] list, String glue, String lastGlue, String glueForTwoItems, String empty, Renderer<Object> renderer) {
return doJoin(new ItemGetter<Object>() {
@Override
public Object get(int index) {
return list[index];
}
@Override
public int size() {
return list.length;
}
@Override
public boolean isEmpty() {
return list.length == 0;
}
}, glue, lastGlue, glueForTwoItems, empty, renderer);
}
/**
* Joins a list together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue.
* @param list The list to concatenate
* @param glue The glue to use
* @return The concatenated string
*/
public static String Join(List list, String glue) {
return Join(list, glue, null, null, null);
}
/**
* Joins a list together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The list to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @return The concatenated string
*/
public static String Join(List list, String glue, String lastGlue) {
return Join(list, glue, lastGlue, null, null);
}
/**
* Joins a list together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The list to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the list, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @return The concatenated string
*/
public static String Join(List list, String glue, String lastGlue, String glueForTwoItems) {
return Join(list, glue, lastGlue, glueForTwoItems, null);
}
/**
* Joins a list together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The list to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the list, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @param empty If the list is completely empty, this string is simply
* returned. If null, an empty string is used.
* @return The concatenated string
*/
public static String Join(final List list, String glue, String lastGlue, String glueForTwoItems, String empty) {
return Join(list, glue, lastGlue, glueForTwoItems, empty, null);
}
/**
* Joins a list together (using StringBuilder's {
*
* @see StringBuilder#append(Object)} method to "toString" the Object) using
* the specified string for glue. If lastGlue is null, it is the same as
* glue, but otherwise it is used to glue just the last two items together,
* which is useful for lists that are being read by a human, to have a
* proper conjunction at the end.
* @param list The list to concatenate
* @param glue The glue to use
* @param lastGlue The glue for the last two elements
* @param glueForTwoItems If only two items are in the list, then this glue
* is used instead. If it is null, then lastGlue is used instead.
* @param empty If the list is completely empty, this string is simply
* returned. If null, an empty string is used.
* @param renderer The item renderer. This renders each item in the list,
* one at a time. If null, toString will be used by default on each item.
* @return The concatenated string
*/
public static <T> String Join(final List<T> list, String glue, String lastGlue, String glueForTwoItems, String empty, Renderer<T> renderer) {
return doJoin(new ItemGetter<T>() {
@Override
public T get(int index) {
return list.get(index);
}
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
}, glue, lastGlue, glueForTwoItems, empty, renderer);
}
/**
* Abstracted version of the join algorithm.
*
* @param <T>
* @param items
* @param glue
* @param lastGlue
* @param glueForTwoItems
* @param empty
* @param renderer
* @return
*/
private static <T> String doJoin(ItemGetter<T> items, String glue, String lastGlue, String glueForTwoItems, String empty, Renderer<T> renderer) {
if (renderer == null) {
renderer = new Renderer<T>() {
@Override
public String toString(T item) {
if (item == null) {
return "null";
} else {
return item.toString();
}
}
};
}
if (lastGlue == null) {
lastGlue = glue;
}
if (glueForTwoItems == null) {
glueForTwoItems = lastGlue;
}
if (items.isEmpty()) {
return empty == null ? "" : empty;
} else if (items.size() == 2) {
StringBuilder b = new StringBuilder();
return b.append(renderer.toString(items.get(0)))
.append(glueForTwoItems)
.append(renderer.toString(items.get(1))).toString();
} else {
StringBuilder b = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
T o = items.get(i);
if (i != 0) {
if (i == items.size() - 1) {
b.append(lastGlue);
} else {
b.append(glue);
}
}
b.append(renderer.toString(o));
}
return b.toString();
}
}
private static interface ItemGetter<T> {
T get(int index);
int size();
boolean isEmpty();
}
/**
* Used to provide a renderer for each item when glueing the items together.
*
* @param <T> The type of each item
*/
public static interface Renderer<T> {
/**
*
* @param item
* @return
*/
String toString(T item);
}
private static int minimum(int a, int b, int c) {
return Math.min(Math.min(a, b), c);
}
/**
* Returns the levenshtein distance of two character sequences. For
* instance, "123" and "133" would have a string distance of 1, while "123"
* and "123" would be 0, since they are the same string.
*
* @param str1
* @param str2
* @return
*/
public static int LevenshteinDistance(CharSequence str1,
CharSequence str2) {
int[][] distance = new int[str1.length() + 1][str2.length() + 1];
for (int i = 0; i <= str1.length(); i++) {
distance[i][0] = i;
}
for (int j = 0; j <= str2.length(); j++) {
distance[0][j] = j;
}
for (int i = 1; i <= str1.length(); i++) {
for (int j = 1; j <= str2.length(); j++) {
distance[i][j] = minimum(
distance[i - 1][j] + 1,
distance[i][j - 1] + 1,
distance[i - 1][j - 1]
+ ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0
: 1));
}
}
return distance[str1.length()][str2.length()];
}
/**
* Splits an argument string into arguments. It is expected that the string:
*
* <code>this is "a 'quoted'" '\'string\''</code>
*
* would parse into 4 arguments, individually, "this", "is", "a 'quoted'",
* "'string'". It essentially handles the very basic case of command line
* argument parsing.
*
* @param args
* @return
*/
public static List<String> ArgParser(String args) {
List<String> arguments = new ArrayList<String>();
StringBuilder buf = new StringBuilder();
char escape = 0;
char quote = 0;
boolean was_quote = false;
for (int i = 0; i < args.length(); i++) {
char ch = args.charAt(i);
if (quote != 0) { // we're in a quote
if (escape != 0) { // we're in an escape too
if (ch == quote) { // escaping the same quote gives just that quote
buf.append(ch);
} else { // escaping anything else gives the escape and char as written
buf.append(escape);
buf.append(quote);
}
// in either case, this terminates the escape.
escape = 0;
continue;
} else if (ch == quote) { // Specifying the same quote again terminates the quote.
quote = 0;
was_quote = true;
continue;
}
} else {
if (escape != 0) {
// all escapes outside quotes which are supported simply output the
// second character, as we aren't handling special ones like \t or \n
buf.append(ch);
escape = 0;
continue;
} else { // outside of quotes and escapes
switch (ch) {
case ' ': // we can tokenize
if (was_quote || buf.length() != 0) {
arguments.add(buf.toString());
buf = new StringBuilder();
was_quote = false;
}
continue;
case '"': // we can start quotes
case '\'':
quote = ch;
continue;
}
}
}
// escape handling and default handling can fall through from either branch to here
switch (ch) {
case '\\':
escape = ch;
break;
default:
buf.append(ch);
}
}
if (escape != 0) { // makes trailing escapes be appended (erroneous string, though, IMO)
buf.append(escape);
}
if (was_quote || buf.length() != 0) { // add the final string
arguments.add(buf.toString());
}
return arguments;
}
public static String trimLeft(String str) {
//If the argument is null then return empty string
if (str == null) {
return "";
}
/* The charAt method returns the character at a particular position in a String.
* We check to see if the character at position 0 (the leading character) is a space.
* If it is, use substring to make a new String that starts after the space.
*/
int len = 0;
while (str.charAt(len) == ' ') {
len++;
}
return str.substring(len);
}
public static String trimRight(String str) {
//If the argument is null then return empty string
if (str == null) {
return "";
}
/* The logic for Rtrim is, While the last character in the String is a space, remove it.
* In the code, take the length of the string and use it to determine if the last character is a space.
*/
int len = str.length();
while (len > 0 && str.charAt(len - 1) == ' ') {
len--;
}
str = str.substring(0, len);
return str;
}
/**
* Works like String.split(), but trims each of the entries also.
*
* @param string
* @param regex
* @return
*/
public static String[] trimSplit(String string, String regex) {
String[] split = string.split(regex);
for (int i = 0; i < split.length; i++) {
split[i] = split[i].trim();
}
return split;
}
/**
* Works like String.replaceFirst, but replaces the last instance instead.
*
* @param string
* @param regex
* @param replacement
* @return
*/
public static String replaceLast(String string, String regex, String replacement) {
if (regex == null) {
return string;
}
if (string == null) {
return null;
}
if (regex.length() > string.length()) {
//It can't be contained in here
return string;
}
Matcher m = Pattern.compile(regex).matcher(string);
int start = -1;
int end = -1;
while (m.find()) {
start = m.start();
end = m.end();
}
if (start == -1 || end == -1) {
//Didn't find it, return the whole string
return string;
} else {
return string.substring(0, start) + replacement + string.substring(end, string.length());
}
}
/**
* Convenience method for HumanReadableByteCount(bytes, true).
*
* @param bytes
* @return
*/
public static String HumanReadableByteCount(long bytes) {
return HumanReadableByteCount(bytes, true);
}
/**
* Returns a human readable byte count, given a byte count.
*
* @param bytes
* @param si
* @return
*/
public static String HumanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit) {
return bytes + " B";
}
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
/**
* Returns a properly agreeing subject verb clause given a count, and
* singular subject. This version assumes that the plural subject can be
* made simply by appending <code>s</code> to the singular subject, which is
* not always true. This is useful in cases where forming a sentence
* requires different wording depending on the count. Usually, you might use
* a fairly complex tertiary statement, for instance: <code>String message = "There " + (count==1?"is":"are") +
* " " + count + " test failure" + (count==1?"":"s");</code> This is time
* consuming, and easy to mess up or accidentally reverse. Instead, you can
* use this function. Note that this will add <code>is</code> or
* </code>are</code> for you. You need only to provide the count, singular
* subject, and plural subject. If the subject cannot be made plural with
* just an <code>s</code>, use
* {@link #PluralHelper(int, java.lang.String, java.lang.String)} instead.
* Usage example:
*
* <pre>
* String message = "There " + PluralHelper(count, "test failure");
* //If count is 1: There is 1 test failure
* //If count is not 1: There are 2 test failures
* </pre>
*
* @param count The count of items
* @param singular The subject of the sentence, as a singular
* @return The properly formatted clause.
*/
public static String PluralHelper(int count, String singular) {
return PluralHelper(count, singular, singular + "s");
}
/**
* Returns a properly agreeing subject verb clause given a count, singular
* subject, and plural subject. This is useful in cases where forming a
* sentence requires different wording depending on the count. Usually, you
* might use a fairly complex tertiary statement, for instance: <code>String message = "There " + (count==1?"is":"are") +
* " " + count + " test failure" + (count==1?"":"s");</code> This is time
* consuming, and easy to mess up or accidentally reverse. Instead, you can
* use this function. Note that this will add <code>is</code> or
* </code>are</code> for you. You need only to provide the count, singular
* subject, and plural subject. If the subject can be made plural with just
* an <code>s</code>, use {@link #PluralHelper(int, java.lang.String)}
* instead. Usage example:
*
* <pre>
* String message = "There " + PluralHelper(count, "fish", "fish");
* //If count is 1: There is 1 fish
* //If count is not 1: There are 2 fish
* </pre>
*
* @param count The count of items
* @param singular The subject of the sentence, as a singular
* @param plural The subject of the sentence, as a plural
* @return The properly formatted clause.
*/
public static String PluralHelper(int count, String singular, String plural) {
return (count == 1 ? "is" : "are") + " " + count + " " + (count == 1 ? singular : plural);
}
/**
* For even more complex sentences, it may just be easiest to provide a
* template, which will be replaced, if the count is singular or plural.
* Both singularTemplate and pluralTemplate are expected to be String.format
* templates with a %d in them, which will be replaced with the actual count
* number. If the count == 1, then the singularTemplate will be used, else
* the pluralTemplate will be used. Usage example:
*
* <pre>
* String message = PluralTemplateHelper(count, "I will buy %d car if it has a good price",
* "I will buy %d cars if they have a good price");
* </pre>
*
* @param count The count of items
* @param singularTemplate The singular template
* @param pluralTemplate The plural template
* @return
*/
public static String PluralTemplateHelper(int count, String singularTemplate, String pluralTemplate) {
if (count == 1) {
return String.format(singularTemplate, count);
} else {
return String.format(pluralTemplate, count);
}
}
/**
* This is the system newline string. For instance, on windows, this would
* likely be \r\n, and unix systems would likely be \n.
*/
public static final String nl = System.getProperty("line.separator");
/**
* This returns the system newline string. For instance, on windows, this
* would likely return \r\n, and unix systems would likely return \n.
*
* @return The system newline string.
*/
public static String nl() {
return nl;
}
/**
* Multiplies a string. For instance, stringMultiply(3, "abc") would return
* "abcabcabc". If count is 0, an empty string is returned, and if count is
* 1, the character sequence itself is returned.
*
* @param count The repeat count
* @param s The sequence to repeat
* @return The multiplied string
* @throws IllegalArgumentException If count is less than 0.
*/
public static String stringMultiply(int count, CharSequence s) {
if (count < 0) {
throw new IllegalArgumentException("Count must be greater than or equal to 0");
}
if (count == 0) {
return "";
}
if (count == 1) {
return s.toString();
}
//Ok, actually have to do the multiply now.
StringBuilder b = new StringBuilder(s.length() * count);
for (int i = 0; i < count; i++) {
b.append(s);
}
return b.toString();
}
/**
* Given a string, returns a string that could be printed out in Java source
* code. That is, all escapable characters are reversed. The returned string
* will already be surrounded by quotes.
*
* @param s
* @return
*/
public static String toCodeString(String s) {
return "\"" + s.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\t", "\\t") + "\"";
}
/**
* Takes a byte array, and returns a string hex representation.
*
* @param bytes
* @return
*/
public static String toHex(byte[] bytes) {
BigInteger bi = new BigInteger(1, bytes);
return String.format("%0" + (bytes.length << 1) + "X", bi);
}
/**
* Splits a string on word boundries.
* @param text
* @param len
* @return
*/
public static List<String> lineSplit(String text, int len) {
// return empty array for null text
if (text == null) {
return new ArrayList<>();
}
// return text if len is zero or less
// or text is less than length
if (len <= 0 || text.length() <= len) {
return new ArrayList<>(Arrays.asList(new String[]{text}));
}
char[] chars = text.toCharArray();
List<String> lines = new ArrayList<>();
StringBuilder line = new StringBuilder();
StringBuilder word = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
word.append(chars[i]);
if (chars[i] == ' ') {
if ((line.length() + word.length()) > len) {
lines.add(line.toString());
line.delete(0, line.length());
}
line.append(word);
word.delete(0, word.length());
}
}
// handle any extra chars in current word
if (word.length() > 0) {
if ((line.length() + word.length()) > len) {
lines.add(line.toString());
line.delete(0, line.length());
}
line.append(word);
}
// handle extra line
if (line.length() > 0) {
lines.add(line.toString());
}
return lines;
}
}