package php.runtime.common; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Pattern; final public class StringUtils { public static final int INDEX_NOT_FOUND = -1; private final static String[] EMPTY_STRING_ARRAY = new String[]{}; public static String repeat(char ch, int repeat) { char[] buf = new char[repeat]; for (int i = repeat - 1; i >= 0; i--) { buf[i] = ch; } return new String(buf); } public static String join(Iterator<?> iterator, char separator) { // handle null, zero and one elements before building a buffer if (iterator == null) { return null; } if (!iterator.hasNext()) { return ""; } Object first = iterator.next(); if (!iterator.hasNext()) { return first == null ? "" : first.toString(); } // two or more elements StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small if (first != null) { buf.append(first); } while (iterator.hasNext()) { buf.append(separator); Object obj = iterator.next(); if (obj != null) { buf.append(obj); } } return buf.toString(); } public static String join(Iterator<?> iterator, String separator) { // handle null, zero and one elements before building a buffer if (iterator == null) { return null; } if (!iterator.hasNext()) { return ""; } Object first = iterator.next(); if (!iterator.hasNext()) { return first == null ? "" : first.toString(); } // two or more elements StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small if (first != null) { buf.append(first); } while (iterator.hasNext()) { if (separator != null) { buf.append(separator); } Object obj = iterator.next(); if (obj != null) { buf.append(obj); } } return buf.toString(); } public static String join(Iterable<?> iterable, char separator) { if (iterable == null) { return null; } return join(iterable.iterator(), separator); } public static String join(Iterable<?> iterable, String separator) { if (iterable == null) { return null; } return join(iterable.iterator(), separator); } public static String join(Object[] array, String separator, int startIndex, int endIndex) { if (array == null) { return null; } if (separator == null) { separator = ""; } // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator)) // (Assuming that all Strings are roughly equally long) int noOfItems = endIndex - startIndex; if (noOfItems <= 0) { return ""; } StringBuilder buf = new StringBuilder(noOfItems * 16); for (int i = startIndex; i < endIndex; i++) { if (i > startIndex) { buf.append(separator); } if (array[i] != null) { buf.append(array[i]); } } return buf.toString(); } public static String join(Object[] array, String separator) { if (array == null) { return null; } return join(array, separator, 0, array.length); } public static String join(Object[] array, char separator, int startIndex, int endIndex) { if (array == null) { return null; } int noOfItems = endIndex - startIndex; if (noOfItems <= 0) { return ""; } StringBuilder buf = new StringBuilder(noOfItems * 16); for (int i = startIndex; i < endIndex; i++) { if (i > startIndex) { buf.append(separator); } if (array[i] != null) { buf.append(array[i]); } } return buf.toString(); } 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 EMPTY_STRING_ARRAY; } List<String> list = new ArrayList<String>(); 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 list.toArray(new String[list.size()]); } 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 EMPTY_STRING_ARRAY; } List<String> list = new ArrayList<String>(); 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 list.toArray(new String[list.size()]); } public static String[] split(String str, char separatorChar) { return splitWorker(str, separatorChar, false); } public static String[] split(String str, String separatorChars, int max) { return str.split(Pattern.quote(separatorChars), max); } public static String[] split(String toSplit, String delimiter) { return toSplit.split(Pattern.quote(delimiter)); } public static String reverse(String str) { if (str == null) { return null; } return new StringBuilder(str).reverse().toString(); } static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart, CharSequence substring, int start, int length) { if (cs instanceof String && substring instanceof String) { return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); } else { // TODO: Implement rather than convert to String return cs.toString().regionMatches(ignoreCase, thisStart, substring.toString(), start, length); } } public static int indexOfIgnoreCase(CharSequence str, CharSequence searchStr, int startPos) { if (str == null || searchStr == null) { return INDEX_NOT_FOUND; } if (startPos < 0) { startPos = 0; } int endLimit = str.length() - searchStr.length() + 1; if (startPos > endLimit) { return INDEX_NOT_FOUND; } if (searchStr.length() == 0) { return startPos; } for (int i = startPos; i < endLimit; i++) { if (regionMatches(str, true, i, searchStr, 0, searchStr.length())) { return i; } } return INDEX_NOT_FOUND; } public static int lastIndexOfIgnoreCase(CharSequence str, CharSequence searchStr, int startPos) { if (str == null || searchStr == null) { return INDEX_NOT_FOUND; } if (startPos > str.length() - searchStr.length()) { startPos = str.length() - searchStr.length(); } if (startPos < 0) { return INDEX_NOT_FOUND; } if (searchStr.length() == 0) { return startPos; } for (int i = startPos; i >= 0; i--) { if (regionMatches(str, true, i, searchStr, 0, searchStr.length())) { return i; } } return INDEX_NOT_FOUND; } public static boolean isValidClassName(String name){ int length = name.length(); if (length == 0) return false; for(int i = 0; i < length; i++){ char ch = name.charAt(i); if (Character.isLetter(ch) || (i != 0 && Character.isDigit(ch)) || ch == '\\' || ch == '_') continue; return false; } return true; } public static boolean hasLength(CharSequence str) { return (str != null && str.length() > 0); } public static String replace(String inString, String oldPattern, String newPattern) { return replace(inString, oldPattern, newPattern, false, null); } public static String replaceIgnoreCase(String inString, String oldPattern, String newPattern) { return replace(inString, oldPattern, newPattern, true, null); } public static String replace(String inString, String oldPattern, String newPattern, boolean ignoreCase, AtomicLong count) { if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) { return inString; } if (count != null) count.set(0); StringBuilder sb = new StringBuilder(); int pos = 0; // our position in the old string int index = ignoreCase ? inString.toLowerCase().indexOf(oldPattern.toLowerCase()) : inString.indexOf(oldPattern); // the index of an occurrence we've found, or -1 int patLen = oldPattern.length(); while (index >= 0) { sb.append(inString.substring(pos, index)); sb.append(newPattern); pos = index + patLen; index = ignoreCase ? inString.toLowerCase().indexOf(oldPattern.toLowerCase(), pos) : inString.indexOf(oldPattern, pos); if (count != null) count.incrementAndGet(); } sb.append(inString.substring(pos)); // remember to append any characters to the right of a match return sb.toString(); } public static boolean isEmpty(String str) { return str == null || str.isEmpty(); } public static boolean isNotEmpty(String str) { return !isEmpty(str); } public static boolean isBlank(String str) { return str == null || str.isEmpty() || str.trim().isEmpty(); } public static boolean isNotBlank(String str) { return !isBlank(str); } }