com.baidu.jprotobuf.pbrpc.utils.StringUtils Maven / Gradle / Ivy
Show all versions of jprotobuf-rpc-core Show documentation
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baidu.jprotobuf.pbrpc.utils;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
/**
* Utility class for String.
*
* @author xiemalin
* @since 1.0
*/
public class StringUtils {
/** The Constant EMPTY_STRING. */
public static final String EMPTY_STRING = "";
/**
*
* Checks if a String is empty ("") or null.
*
*
*
* StringUtils.isEmpty(null) = true
* StringUtils.isEmpty("") = true
* StringUtils.isEmpty(" ") = false
* StringUtils.isEmpty("bob") = false
* StringUtils.isEmpty(" bob ") = false
*
*
*
* NOTE: This method changed in Lang version 2.0. It no longer trims the String. That functionality is available in
* isBlank().
*
*
* @param str the String to check, may be null
* @return true
if the String is empty or null
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
*
* Checks if a String is whitespace, empty ("") or null.
*
*
*
* StringUtils.isBlank(null) = true
* StringUtils.isBlank("") = true
* StringUtils.isBlank(" ") = true
* StringUtils.isBlank("bob") = false
* StringUtils.isBlank(" bob ") = false
*
*
* @param str the String to check, may be null
* @return true
if the String is null, empty or whitespace
* @since 2.0
*/
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
/**
*
* Convert a String
to an int
, returning zero
if the conversion fails.
*
*
*
* If the string is null
, zero
is returned.
*
*
*
* NumberUtils.toInt(null) = 0
* NumberUtils.toInt("") = 0
* NumberUtils.toInt("1") = 1
*
*
* @param str the string to convert, may be null
* @return the int represented by the string, or zero
if conversion fails
* @since 2.1
*/
public static int toInt(String str) {
return toInt(str, 0);
}
/**
*
* Convert a String
to an int
, returning a default value if the conversion fails.
*
*
*
* If the string is null
, the default value is returned.
*
*
*
* NumberUtils.stringToInt(null, 1) = 1
* NumberUtils.stringToInt("", 1) = 1
* NumberUtils.stringToInt("1", 0) = 1
*
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the int represented by the string, or the default if conversion fails
* @deprecated Use {@link #toInt(String, int)} This method will be removed in Commons Lang 3.0
*/
public static int stringToInt(String str, int defaultValue) {
return toInt(str, defaultValue);
}
/**
*
* Convert a String
to an int
, returning a default value if the conversion fails.
*
*
*
* If the string is null
, the default value is returned.
*
*
*
* NumberUtils.toInt(null, 1) = 1
* NumberUtils.toInt("", 1) = 1
* NumberUtils.toInt("1", 0) = 1
*
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the int represented by the string, or the default if conversion fails
* @since 2.1
*/
public static int toInt(String str, int defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
/**
*
* Convert a String
to an long
, returning a default value if the conversion fails.
*
*
*
* If the string is null
, the default value is returned.
*
*
*
* NumberUtils.toLong(null) = 0
* NumberUtils.toLong("") = 0
* NumberUtils.toLong("1") = 1
*
*
* @param str the string to convert, may be null
* @return the long represented by the string, or the default if conversion fails
* @since 2.1
*/
public static long toLong(String str) {
return toLong(str, 0);
}
/**
*
* Convert a String
to an long
, returning a default value if the conversion fails.
*
*
*
* If the string is null
, the default value is returned.
*
*
*
* NumberUtils.toLong(null, 1) = 1
* NumberUtils.toLong("", 1) = 1
* NumberUtils.toLong("1", 0) = 1
*
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the long represented by the string, or the default if conversion fails
* @since 2.1
*/
public static long toLong(String str, long defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Long.parseLong(str);
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
/**
*
* Escapes the characters in a String
using Java String rules.
*
*
*
* Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)
*
*
*
* So a tab becomes the characters '\\'
and 't'
.
*
*
*
* The only difference between Java strings and JavaScript strings is that in JavaScript, a single quote must be
* escaped.
*
*
*
* Example:
*
*
* input string: He didn't say, "Stop!"
* output string: He didn't say, \"Stop!\"
*
*
*
*
* @param str String to escape values in, may be null
* @return String with escaped values, null
if null string input
*/
public static String escapeJava(String str) {
return escapeJavaStyleString(str, false);
}
/**
*
* Escapes the characters in a String
using Java String rules to a Writer
.
*
*
*
* A null
string input has no effect.
*
*
* @param out Writer to write escaped string into
* @param str String to escape values in, may be null
* @throws IOException if error occurs on underlying Writer
* @throws IllegalArgumentException if the Writer is null
* @see #escapeJava(java.lang.String)
*/
public static void escapeJava(Writer out, String str) throws IOException {
escapeJavaStyleString(out, str, false);
}
/**
*
* Worker method for the {@link #escapeJavaScript(String)} method.
*
*
* @param str String to escape values in, may be null
* @param escapeSingleQuotes escapes single quotes if true
* @return the escaped string
*/
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes) {
if (str == null) {
return null;
}
try {
StringWriter writer = new StringWriter(str.length() * 2);
escapeJavaStyleString(writer, str, escapeSingleQuotes);
return writer.toString();
} catch (IOException ioe) {
// this should never ever happen while writing to a StringWriter
ioe.printStackTrace();
return null;
}
}
/**
*
* Worker method for the {@link #escapeJavaScript(String)} method.
*
*
* @param out write to receieve the escaped string
* @param str String to escape values in, may be null
* @param escapeSingleQuote escapes single quotes if true
* @throws IOException if an IOException occurs
*/
private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote) throws IOException {
if (out == null) {
throw new IllegalArgumentException("The Writer must not be null");
}
if (str == null) {
return;
}
int sz;
sz = str.length();
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
// handle unicode
if (ch > 0xfff) {
out.write("\\u" + hex(ch));
} else if (ch > 0xff) {
out.write("\\u0" + hex(ch));
} else if (ch > 0x7f) {
out.write("\\u00" + hex(ch));
} else if (ch < 32) {
switch (ch) {
case '\b':
out.write('\\');
out.write('b');
break;
case '\n':
out.write('\\');
out.write('n');
break;
case '\t':
out.write('\\');
out.write('t');
break;
case '\f':
out.write('\\');
out.write('f');
break;
case '\r':
out.write('\\');
out.write('r');
break;
default:
if (ch > 0xf) {
out.write("\\u00" + hex(ch));
} else {
out.write("\\u000" + hex(ch));
}
break;
}
} else {
switch (ch) {
case '\'':
if (escapeSingleQuote) {
out.write('\\');
}
out.write('\'');
break;
case '"':
out.write('\\');
out.write('"');
break;
case '\\':
out.write('\\');
out.write('\\');
break;
case '/':
out.write('\\');
out.write('/');
break;
default:
out.write(ch);
break;
}
}
}
}
/**
*
* Unescapes any Java literals found in the String
. For example, it will turn a sequence of
* '\'
and 'n'
into a newline character, unless the '\'
is preceded by
* another '\'
.
*
*
* @param str the String
to unescape, may be null
* @return a new unescaped String
, null
if null string input
*/
public static String unescapeJava(String str) {
if (str == null) {
return null;
}
try {
StringWriter writer = new StringWriter(str.length());
unescapeJava(writer, str);
return writer.toString();
} catch (IOException ioe) {
// this should never ever happen while writing to a StringWriter
ioe.printStackTrace();
return null;
}
}
/**
*
* Unescapes any Java literals found in the String
to a Writer
.
*
*
*
* For example, it will turn a sequence of '\'
and 'n'
into a newline character, unless
* the '\'
is preceded by another '\'
.
*
*
*
* A null
string input has no effect.
*
*
* @param out the Writer
used to output unescaped characters
* @param str the String
to unescape, may be null
* @throws IOException if error occurs on underlying Writer
* @throws IllegalArgumentException if the Writer is null
*/
public static void unescapeJava(Writer out, String str) throws IOException {
if (out == null) {
throw new IllegalArgumentException("The Writer must not be null");
}
if (str == null) {
return;
}
int sz = str.length();
StringBuffer unicode = new StringBuffer(4);
boolean hadSlash = false;
boolean inUnicode = false;
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
if (inUnicode) {
// if in unicode, then we're reading unicode
// values in somehow
unicode.append(ch);
if (unicode.length() == 4) {
// unicode now contains the four hex digits
// which represents our unicode character
try {
int value = Integer.parseInt(unicode.toString(), 16);
out.write((char) value);
unicode.setLength(0);
inUnicode = false;
hadSlash = false;
} catch (NumberFormatException nfe) {
throw new RuntimeException("Unable to parse unicode value: " + unicode, nfe);
}
}
continue;
}
if (hadSlash) {
// handle an escaped value
hadSlash = false;
switch (ch) {
case '\\':
out.write('\\');
break;
case '\'':
out.write('\'');
break;
case '\"':
out.write('"');
break;
case 'r':
out.write('\r');
break;
case 'f':
out.write('\f');
break;
case 't':
out.write('\t');
break;
case 'n':
out.write('\n');
break;
case 'b':
out.write('\b');
break;
case 'u': {
// uh-oh, we're in unicode country....
inUnicode = true;
break;
}
default:
out.write(ch);
break;
}
continue;
} else if (ch == '\\') {
hadSlash = true;
continue;
}
out.write(ch);
}
if (hadSlash) {
// then we're in the weird case of a \ at the end of the
// string, let's output it anyway.
out.write('\\');
}
}
/**
*
* Returns an upper case hexadecimal String
for the given character.
*
*
* @param ch The character to convert.
* @return An upper case hexadecimal String
*/
private static String hex(char ch) {
return Integer.toHexString(ch).toUpperCase();
}
/**
*
* Splits the provided text into an array, using whitespace as the separator. Whitespace is defined by
* {@link Character#isWhitespace(char)}.
*
*
*
* The separator is not included in the returned String array. Adjacent separators are treated as one separator. For
* more control over the split use the StrTokenizer class.
*
*
*
* A null
input String returns null
.
*
*
*
* StringUtils.split(null) = null
* StringUtils.split("") = []
* StringUtils.split("abc def") = ["abc", "def"]
* StringUtils.split("abc def") = ["abc", "def"]
* StringUtils.split(" abc ") = ["abc"]
*
*
* @param str the String to parse, may be null
* @return an array of parsed Strings, null
if null String input
*/
public static String[] split(String str) {
return split(str, null, -1);
}
/**
*
* Splits the provided text into an array, separator specified. This is an alternative to using StringTokenizer.
*
*
*
* The separator is not included in the returned String array. Adjacent separators are treated as one separator. For
* more control over the split use the StrTokenizer class.
*
*
*
* A null
input String returns null
.
*
*
*
* StringUtils.split(null, *) = null
* StringUtils.split("", *) = []
* StringUtils.split("a.b.c", '.') = ["a", "b", "c"]
* StringUtils.split("a..b.c", '.') = ["a", "b", "c"]
* StringUtils.split("a:b:c", '.') = ["a:b:c"]
* StringUtils.split("a b c", ' ') = ["a", "b", "c"]
*
*
* @param str the String to parse, may be null
* @param separatorChar the character used as the delimiter
* @return an array of parsed Strings, null
if null String input
* @since 2.0
*/
public static String[] split(String str, char separatorChar) {
return splitWorker(str, separatorChar, false);
}
/**
*
* Splits the provided text into an array, separators specified. This is an alternative to using StringTokenizer.
*
*
*
* The separator is not included in the returned String array. Adjacent separators are treated as one separator. For
* more control over the split use the StrTokenizer class.
*
*
*
* A null
input String returns null
. A null
separatorChars splits on
* whitespace.
*
*
*
* StringUtils.split(null, *) = null
* StringUtils.split("", *) = []
* StringUtils.split("abc def", null) = ["abc", "def"]
* StringUtils.split("abc def", " ") = ["abc", "def"]
* StringUtils.split("abc def", " ") = ["abc", "def"]
* StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
*
*
* @param str the String to parse, may be null
* @param separatorChars the characters used as the delimiters, null
splits on whitespace
* @return an array of parsed Strings, null
if null String input
*/
public static String[] split(String str, String separatorChars) {
return splitWorker(str, separatorChars, -1, false);
}
/**
*
* Splits the provided text into an array with a maximum length, separators specified.
*
*
*
* The separator is not included in the returned String array. Adjacent separators are treated as one separator.
*
*
*
* A null
input String returns null
. A null
separatorChars splits on
* whitespace.
*
*
*
* If more than max
delimited substrings are found, the last returned string includes all characters
* after the first max - 1
returned strings (including separator characters).
*
*
*
* StringUtils.split(null, *, *) = null
* StringUtils.split("", *, *) = []
* StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"]
* StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"]
* StringUtils.split("ab:cd:ef", ":", 0) = ["ab", "cd", "ef"]
* StringUtils.split("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
*
*
* @param str the String to parse, may be null
* @param separatorChars the characters used as the delimiters, null
splits on whitespace
* @param max the maximum number of elements to include in the array. A zero or negative value implies no limit
* @return an array of parsed Strings, null
if null String input
*/
public static String[] split(String str, String separatorChars, int max) {
return splitWorker(str, separatorChars, max, false);
}
/**
*
* Splits the provided text into an array, separator string specified.
*
*
*
* The separator(s) will not be included in the returned String array. Adjacent separators are treated as one
* separator.
*
*
*
* A null
input String returns null
. A null
separator splits on whitespace.
*
*
*
* StringUtils.splitByWholeSeparator(null, *) = null
* StringUtils.splitByWholeSeparator("", *) = []
* StringUtils.splitByWholeSeparator("ab de fg", null) = ["ab", "de", "fg"]
* StringUtils.splitByWholeSeparator("ab de fg", null) = ["ab", "de", "fg"]
* StringUtils.splitByWholeSeparator("ab:cd:ef", ":") = ["ab", "cd", "ef"]
* StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
*
*
* @param str the String to parse, may be null
* @param separator String containing the String to be used as a delimiter, null
splits on whitespace
* @return an array of parsed Strings, null
if null String was input
*/
public static String[] splitByWholeSeparator(String str, String separator) {
return splitByWholeSeparatorWorker(str, separator, -1, false);
}
/**
*
* Splits the provided text into an array, separator string specified. Returns a maximum of max
* substrings.
*
*
*
* The separator(s) will not be included in the returned String array. Adjacent separators are treated as one
* separator.
*
*
*
* A null
input String returns null
. A null
separator splits on whitespace.
*
*
*
* StringUtils.splitByWholeSeparator(null, *, *) = null
* StringUtils.splitByWholeSeparator("", *, *) = []
* StringUtils.splitByWholeSeparator("ab de fg", null, 0) = ["ab", "de", "fg"]
* StringUtils.splitByWholeSeparator("ab de fg", null, 0) = ["ab", "de", "fg"]
* StringUtils.splitByWholeSeparator("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
* StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
* StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
*
*
* @param str the String to parse, may be null
* @param separator String containing the String to be used as a delimiter, null
splits on whitespace
* @param max the maximum number of elements to include in the returned array. A zero or negative value implies no
* limit.
* @return an array of parsed Strings, null
if null String was input
*/
public static String[] splitByWholeSeparator(String str, String separator, int max) {
return splitByWholeSeparatorWorker(str, separator, max, false);
}
/**
*
* Splits the provided text into an array, separator string specified.
*
*
*
* The separator is not included in the returned String array. Adjacent separators are treated as separators for
* empty tokens. For more control over the split use the StrTokenizer class.
*
*
*
* A null
input String returns null
. A null
separator splits on whitespace.
*
*
*
* StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *) = null
* StringUtils.splitByWholeSeparatorPreserveAllTokens("", *) = []
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null) = ["ab", "de", "fg"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null) = ["ab", "", "", "de", "fg"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":") = ["ab", "cd", "ef"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
*
*
* @param str the String to parse, may be null
* @param separator String containing the String to be used as a delimiter, null
splits on whitespace
* @return an array of parsed Strings, null
if null String was input
* @since 2.4
*/
public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator) {
return splitByWholeSeparatorWorker(str, separator, -1, true);
}
/**
*
* Splits the provided text into an array, separator string specified. Returns a maximum of max
* substrings.
*
*
*
* The separator is not included in the returned String array. Adjacent separators are treated as separators for
* empty tokens. For more control over the split use the StrTokenizer class.
*
*
*
* A null
input String returns null
. A null
separator splits on whitespace.
*
*
*
* StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *, *) = null
* StringUtils.splitByWholeSeparatorPreserveAllTokens("", *, *) = []
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0) = ["ab", "de", "fg"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0) = ["ab", "", "", "de", "fg"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
* StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
*
*
* @param str the String to parse, may be null
* @param separator String containing the String to be used as a delimiter, null
splits on whitespace
* @param max the maximum number of elements to include in the returned array. A zero or negative value implies no
* limit.
* @return an array of parsed Strings, null
if null String was input
* @since 2.4
*/
public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator, int max) {
return splitByWholeSeparatorWorker(str, separator, max, true);
}
/**
* Performs the logic for the splitByWholeSeparatorPreserveAllTokens
methods.
*
* @param str the String to parse, may be null
* @param separator String containing the String to be used as a delimiter, null
splits on whitespace
* @param max the maximum number of elements to include in the returned array. A zero or negative value implies no
* limit.
* @param preserveAllTokens if true
, adjacent separators are treated as empty token separators; if
* false
, adjacent separators are treated as one separator.
* @return an array of parsed Strings, null
if null String input
* @since 2.4
*/
private static String[]
splitByWholeSeparatorWorker(String str, String separator, int max, boolean preserveAllTokens) {
if (str == null) {
return null;
}
int len = str.length();
if (len == 0) {
return new String[0];
}
if ((separator == null) || (EMPTY_STRING.equals(separator))) {
// Split on whitespace.
return splitWorker(str, null, max, preserveAllTokens);
}
int separatorLength = separator.length();
ArrayList substrings = new ArrayList();
int numberOfSubstrings = 0;
int beg = 0;
int end = 0;
while (end < len) {
end = str.indexOf(separator, beg);
if (end > -1) {
if (end > beg) {
numberOfSubstrings += 1;
if (numberOfSubstrings == max) {
end = len;
substrings.add(str.substring(beg));
} else {
// The following is OK, because String.substring( beg, end ) excludes
// the character at the position 'end'.
substrings.add(str.substring(beg, end));
// Set the starting point for the next search.
// The following is equivalent to beg = end + (separatorLength - 1) + 1,
// which is the right calculation:
beg = end + separatorLength;
}
} else {
// We found a consecutive occurrence of the separator, so skip it.
if (preserveAllTokens) {
numberOfSubstrings += 1;
if (numberOfSubstrings == max) {
end = len;
substrings.add(str.substring(beg));
} else {
substrings.add(EMPTY_STRING);
}
}
beg = end + separatorLength;
}
} else {
// String.substring( beg ) goes from 'beg' to the end of the String.
substrings.add(str.substring(beg));
end = len;
}
}
return (String[]) substrings.toArray(new String[substrings.size()]);
}
/**
* Performs the logic for the split
and splitPreserveAllTokens
methods that do not return
* a maximum array length.
*
* @param str the String to parse, may be null
* @param separatorChar the separate character
* @param preserveAllTokens if true
, adjacent separators are treated as empty token separators; if
* false
, adjacent separators are treated as one separator.
* @return an array of parsed Strings, null
if null String input
*/
private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
// Performance tuned for 2.0 (JDK1.4)
if (str == null) {
return null;
}
int len = str.length();
if (len == 0) {
return new String[0];
}
List list = new ArrayList();
int i = 0, start = 0;
boolean match = false;
boolean lastMatch = false;
while (i < len) {
if (str.charAt(i) == separatorChar) {
if (match || preserveAllTokens) {
list.add(str.substring(start, i));
match = false;
lastMatch = true;
}
start = ++i;
continue;
}
lastMatch = false;
match = true;
i++;
}
if (match || (preserveAllTokens && lastMatch)) {
list.add(str.substring(start, i));
}
return (String[]) list.toArray(new String[list.size()]);
}
/**
* Performs the logic for the split
and splitPreserveAllTokens
methods that return a
* maximum array length.
*
* @param str the String to parse, may be null
* @param separatorChars the separate character
* @param max the maximum number of elements to include in the array. A zero or negative value implies no limit.
* @param preserveAllTokens if true
, adjacent separators are treated as empty token separators; if
* false
, adjacent separators are treated as one separator.
* @return an array of parsed Strings, null
if null String input
*/
private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
// Performance tuned for 2.0 (JDK1.4)
// Direct code is quicker than StringTokenizer.
// Also, StringTokenizer uses isSpace() not isWhitespace()
if (str == null) {
return null;
}
int len = str.length();
if (len == 0) {
return new String[0];
}
List list = new ArrayList();
int sizePlus1 = 1;
int i = 0, start = 0;
boolean match = false;
boolean lastMatch = false;
if (separatorChars == null) {
// Null separator means use whitespace
while (i < len) {
if (Character.isWhitespace(str.charAt(i))) {
if (match || preserveAllTokens) {
lastMatch = true;
if (sizePlus1++ == max) {
i = len;
lastMatch = false;
}
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
lastMatch = false;
match = true;
i++;
}
} else if (separatorChars.length() == 1) {
// Optimise 1 character case
char sep = separatorChars.charAt(0);
while (i < len) {
if (str.charAt(i) == sep) {
if (match || preserveAllTokens) {
lastMatch = true;
if (sizePlus1++ == max) {
i = len;
lastMatch = false;
}
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
lastMatch = false;
match = true;
i++;
}
} else {
// standard case
while (i < len) {
if (separatorChars.indexOf(str.charAt(i)) >= 0) {
if (match || preserveAllTokens) {
lastMatch = true;
if (sizePlus1++ == max) {
i = len;
lastMatch = false;
}
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
lastMatch = false;
match = true;
i++;
}
}
if (match || (preserveAllTokens && lastMatch)) {
list.add(str.substring(start, i));
}
return (String[]) list.toArray(new String[list.size()]);
}
}