From dd56a2d551da7fc9befda2508f6ff4f027fa2625 Mon Sep 17 00:00:00 2001 From: plata <5999812-plata-gl@users.noreply.gitlab.com> Date: Fri, 24 May 2024 20:58:16 +0000 Subject: [PATCH] android/text/TextUtils: add indexOf() + lastIndexOf() --- src/api-impl/android/text/TextUtils.java | 195 +++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/src/api-impl/android/text/TextUtils.java b/src/api-impl/android/text/TextUtils.java index 78e9fb70..9b27a867 100644 --- a/src/api-impl/android/text/TextUtils.java +++ b/src/api-impl/android/text/TextUtils.java @@ -59,6 +59,197 @@ public class TextUtils { } return sb.toString(); } + + public static int indexOf(CharSequence s, char ch) { + return indexOf(s, ch, 0); + } + + public static int indexOf(CharSequence s, char ch, int start) { + Class c = s.getClass(); + + if (c == String.class) + return ((String)s).indexOf(ch, start); + + return indexOf(s, ch, start, s.length()); + } + + public static int indexOf(CharSequence s, char ch, int start, int end) { + Class c = s.getClass(); + + if (s instanceof GetChars || c == StringBuffer.class || + c == StringBuilder.class || c == String.class) { + final int INDEX_INCREMENT = 500; + char[] temp = obtain(INDEX_INCREMENT); + + while (start < end) { + int segend = start + INDEX_INCREMENT; + if (segend > end) + segend = end; + + getChars(s, start, segend, temp, 0); + + int count = segend - start; + for (int i = 0; i < count; i++) { + if (temp[i] == ch) { + recycle(temp); + return i + start; + } + } + + start = segend; + } + + recycle(temp); + return -1; + } + + for (int i = start; i < end; i++) + if (s.charAt(i) == ch) + return i; + + return -1; + } + + public static int lastIndexOf(CharSequence s, char ch) { + return lastIndexOf(s, ch, s.length() - 1); + } + + public static int lastIndexOf(CharSequence s, char ch, int last) { + Class c = s.getClass(); + + if (c == String.class) + return ((String)s).lastIndexOf(ch, last); + + return lastIndexOf(s, ch, 0, last); + } + + public static int lastIndexOf(CharSequence s, char ch, + int start, int last) { + if (last < 0) + return -1; + if (last >= s.length()) + last = s.length() - 1; + + int end = last + 1; + + Class c = s.getClass(); + + if (s instanceof GetChars || c == StringBuffer.class || + c == StringBuilder.class || c == String.class) { + final int INDEX_INCREMENT = 500; + char[] temp = obtain(INDEX_INCREMENT); + + while (start < end) { + int segstart = end - INDEX_INCREMENT; + if (segstart < start) + segstart = start; + + getChars(s, segstart, end, temp, 0); + + int count = end - segstart; + for (int i = count - 1; i >= 0; i--) { + if (temp[i] == ch) { + recycle(temp); + return i + segstart; + } + } + + end = segstart; + } + + recycle(temp); + return -1; + } + + for (int i = end - 1; i >= start; i--) + if (s.charAt(i) == ch) + return i; + + return -1; + } + + public static int indexOf(CharSequence s, CharSequence needle) { + return indexOf(s, needle, 0, s.length()); + } + + public static int indexOf(CharSequence s, CharSequence needle, int start) { + return indexOf(s, needle, start, s.length()); + } + + public static int indexOf(CharSequence s, CharSequence needle, + int start, int end) { + int nlen = needle.length(); + if (nlen == 0) + return start; + + char c = needle.charAt(0); + + for (;;) { + start = indexOf(s, c, start); + if (start > end - nlen) { + break; + } + + if (start < 0) { + return -1; + } + + if (regionMatches(s, start, needle, 0, nlen)) { + return start; + } + + start++; + } + return -1; + } + + public static boolean regionMatches(CharSequence one, int toffset, + CharSequence two, int ooffset, + int len) { + int tempLen = 2 * len; + if (tempLen < len) { + // Integer overflow; len is unreasonably large + throw new IndexOutOfBoundsException(); + } + char[] temp = obtain(tempLen); + + getChars(one, toffset, toffset + len, temp, 0); + getChars(two, ooffset, ooffset + len, temp, len); + + boolean match = true; + for (int i = 0; i < len; i++) { + if (temp[i] != temp[i + len]) { + match = false; + break; + } + } + + recycle(temp); + return match; + } + + /* package */ static char[] obtain(int len) { + char[] buf; + + synchronized (sLock) { + buf = sTemp; + sTemp = null; + } + + // if (buf == null || buf.length < len) + // buf = ArrayUtils.newUnpaddedCharArray(len); + + return buf; + } + + /* package */ static void recycle(char[] temp) { + if (temp.length > 1000) + return; + + synchronized (sLock) { + sTemp = temp; + } + } // end of unchanged from android source public static CharSequence join(Iterable list) { @@ -133,4 +324,8 @@ public class TextUtils { public static int getCapsMode(CharSequence cs, int off, int reqModes) { return 0; } + + private static Object sLock = new Object(); + + private static char[] sTemp = null; }