/*
* Copyright (C) 2006 The Android Open Source Project
*
* 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 android.text;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.intel.mpt.annotation.MayloonStubAnnotation;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.style.ReplacementSpan;
import android.util.Printer;
import java.util.regex.Pattern;
import java.util.Iterator;
public class TextUtils {
private TextUtils() { /* cannot be instantiated */
}
private static String[] EMPTY_STRING_ARRAY = new String[] {};
public enum TruncateAt {
START,
MIDDLE,
END,
MARQUEE,
}
/** @hide */
public static final int ALIGNMENT_SPAN = 1;
/** @hide */
public static final int FOREGROUND_COLOR_SPAN = 2;
/** @hide */
public static final int RELATIVE_SIZE_SPAN = 3;
/** @hide */
public static final int SCALE_X_SPAN = 4;
/** @hide */
public static final int STRIKETHROUGH_SPAN = 5;
/** @hide */
public static final int UNDERLINE_SPAN = 6;
/** @hide */
public static final int STYLE_SPAN = 7;
/** @hide */
public static final int BULLET_SPAN = 8;
/** @hide */
public static final int QUOTE_SPAN = 9;
/** @hide */
public static final int LEADING_MARGIN_SPAN = 10;
/** @hide */
public static final int URL_SPAN = 11;
/** @hide */
public static final int BACKGROUND_COLOR_SPAN = 12;
/** @hide */
public static final int TYPEFACE_SPAN = 13;
/** @hide */
public static final int SUPERSCRIPT_SPAN = 14;
/** @hide */
public static final int SUBSCRIPT_SPAN = 15;
/** @hide */
public static final int ABSOLUTE_SIZE_SPAN = 16;
/** @hide */
public static final int TEXT_APPEARANCE_SPAN = 17;
/** @hide */
public static final int ANNOTATION = 18;
public static void getChars(CharSequence s, int start, int end,
char[] dest, int destoff) {
Class c = s.getClass();
if (c == String.class)
((String) s).getChars(start, end, dest, destoff);
else if (c == StringBuilder.class)
((StringBuilder) s).getChars(start, end, dest, destoff);
else {
if (0 <= start && start <= end) {
for (int i = start; i < end; i++)
dest[destoff++] = s.charAt(i);
}
else
{
throw new StringIndexOutOfBoundsException();
}
}
}
public static int indexOf(CharSequence s, String ch) {
return indexOf(s, ch, 0);
}
public static int indexOf(CharSequence s, String 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, String ch, int start, int end) {
for (int i = start; i < end; i++)
if (s.charAt(i) == ch.charAt(0))
return i;
return -1;
}
public static int lastIndexOf(CharSequence s, char ch) {
return 0;
}
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;
}
private static Object sLock = new Object();
private static char[] sTemp = null;
public static void writeToParcel(CharSequence val, Parcel parcel, int i) {
// TODO Auto-generated method stub
}
public static boolean isEmpty(CharSequence str) {
if(str==null){
return true;
}
if (getLength(str)== 0)
return true;
else
return false;
}
public static int getLength(CharSequence str){
if(str==null){
return 0;
}
/**
* @j2sNative
* return String(str).length;
*/{}
return 0;
}
/**
* Returns a string containing the tokens joined by delimiters.
* @param tokens an array objects to be joined. Strings will be formed from
* the objects by calling object.toString().
*/
public static String join(CharSequence delimiter, Object[] tokens) {
StringBuilder sb = new StringBuilder();
boolean firstTime = true;
for (Object token: tokens) {
if (firstTime) {
firstTime = false;
} else {
sb.append(delimiter);
}
sb.append(token);
}
return sb.toString();
}
/**
* Returns a string containing the tokens joined by delimiters.
* @param tokens an array objects to be joined. Strings will be formed from
* the objects by calling object.toString().
*/
public static String join(CharSequence delimiter, Iterable tokens) {
StringBuilder sb = new StringBuilder();
boolean firstTime = true;
for (Object token: tokens) {
if (firstTime) {
firstTime = false;
} else {
sb.append(delimiter);
}
sb.append(token);
}
return sb.toString();
}
/**
* String.split() returns [''] when the string to be split is empty. This returns []. This does
* not remove any empty strings from the result. For example split("a,", "," ) returns {"a", ""}.
*
* @param text the string to split
* @param expression the regular expression to match
* @return an array of strings. The array will be empty if text is empty
*
* @throws NullPointerException if expression or text is null
*/
public static String[] split(String text, String expression) {
if (text.length() == 0) {
return EMPTY_STRING_ARRAY;
} else {
return text.split(expression, -1);
}
}
/**
* Splits a string on a pattern. String.split() returns [''] when the string to be
* split is empty. This returns []. This does not remove any empty strings from the result.
* @param text the string to split
* @param pattern the regular expression to match
* @return an array of strings. The array will be empty if text is empty
*
* @throws NullPointerException if expression or text is null
*/
public static String[] split(String text, Pattern pattern) {
if (text.length() == 0) {
return EMPTY_STRING_ARRAY;
} else {
return pattern.split(text, -1);
}
}
public static boolean equals(CharSequence a, CharSequence b) {
if (a == b) return true;
int length;
if (a != null && b != null && (length = a.length()) == b.length()) {
if (a instanceof String && b instanceof String) {
return a.equals(b);
} else {
for (int i = 0; i < length; i++) {
if (a.charAt(i) != b.charAt(i)) return false;
}
return true;
}
}
return false;
}
public static int getOffsetBefore(CharSequence text, int offset) {
if (offset == 0)
return 0;
if (offset == 1)
return 0;
char c = text.charAt(offset - 1);
if (c >= '\uDC00' && c <= '\uDFFF') {
char c1 = text.charAt(offset - 2);
if (c1 >= '\uD800' && c1 <= '\uDBFF')
offset -= 2;
else
offset -= 1;
} else {
offset -= 1;
}
/*if (text instanceof Spanned) {
ReplacementSpan[] spans = ((Spanned) text).getSpans(offset, offset,
ReplacementSpan.class);
for (int i = 0; i < spans.length; i++) {
int start = ((Spanned) text).getSpanStart(spans[i]);
int end = ((Spanned) text).getSpanEnd(spans[i]);
if (start < offset && end > offset)
offset = start;
}
}*/
return offset;
}
/**
* Copies the spans from the region <code>start...end</code> in
* <code>source</code> to the region
* <code>destoff...destoff+end-start</code> in <code>dest</code>.
* Spans in <code>source</code> that begin before <code>start</code>
* or end after <code>end</code> but overlap this range are trimmed
* as if they began at <code>start</code> or ended at <code>end</code>.
*
* @throws IndexOutOfBoundsException if any of the copied spans
* are out of range in <code>dest</code>.
*/
public static void copySpansFrom(Spanned source, int start, int end,
Class kind,
Spannable dest, int destoff) {
if (kind == null) {
kind = Object.class;
}
Object[] spans = source.getSpans(start, end, kind);
for (int i = 0; i < spans.length; i++) {
int st = source.getSpanStart(spans[i]);
int en = source.getSpanEnd(spans[i]);
int fl = source.getSpanFlags(spans[i]);
if (st < start)
st = start;
if (en > end)
en = end;
dest.setSpan(spans[i], st - start + destoff, en - start + destoff,
fl);
}
}
/* package */ static char[] obtain(int len) {
char[] buf;
synchronized (sLock) {
buf = sTemp;
sTemp = null;
}
if (buf == null || buf.length < len)
buf = new char[ArrayUtils.idealCharArraySize(len)];
return buf;
}
/* package */ static void recycle(char[] temp) {
if (temp.length > 1000)
return;
synchronized (sLock) {
sTemp = temp;
}
}
public static int getOffsetAfter(CharSequence text, int offset) {
int len = text.length();
if (offset == len)
return len;
if (offset == len - 1)
return len;
char c = text.charAt(offset);
if (c >= '\uD800' && c <= '\uDBFF') {
char c1 = text.charAt(offset + 1);
if (c1 >= '\uDC00' && c1 <= '\uDFFF')
offset += 2;
else
offset += 1;
} else {
offset += 1;
}
if (text instanceof Spanned) {
ReplacementSpan[] spans = ((Spanned) text).getSpans(offset, offset,
ReplacementSpan.class);
for (int i = 0; i < spans.length; i++) {
int start = ((Spanned) text).getSpanStart(spans[i]);
int end = ((Spanned) text).getSpanEnd(spans[i]);
if (start < offset && end > offset)
offset = end;
}
}
return offset;
}
// XXX currently this only reverses chars, not spans
public static CharSequence getReverse(CharSequence source,
int start, int end) {
return new Reverser(source, start, end);
}
private static class Reverser
implements CharSequence, GetChars
{
public Reverser(CharSequence source, int start, int end) {
mSource = source;
mStart = start;
mEnd = end;
}
public int length() {
return mEnd - mStart;
}
public CharSequence subSequence(int start, int end) {
char[] buf = new char[end - start];
getChars(start, end, buf, 0);
return new String(buf);
}
public String toString() {
return subSequence(0, length()).toString();
}
public char charAt(int off) {
return AndroidCharacter.getMirror(mSource.charAt(mEnd - 1 - off));
}
public void getChars(int start, int end, char[] dest, int destoff) {
TextUtils.getChars(mSource, start + mStart, end + mStart,
dest, destoff);
AndroidCharacter.mirror(dest, 0, end - start);
int len = end - start;
int n = (end - start) / 2;
for (int i = 0; i < n; i++) {
char tmp = dest[destoff + i];
dest[destoff + i] = dest[destoff + len - i - 1];
dest[destoff + len - i - 1] = tmp;
}
}
private CharSequence mSource;
private int mStart;
private int mEnd;
}
/**
* @j2sNative
* console.log("Missing method: getTrimmedLength");
*/
@MayloonStubAnnotation()
public static int getTrimmedLength(CharSequence s) {
System.out.println("Stub" + " Function : getTrimmedLength");
return 0;
}
/**
* @j2sNative
* console.log("Missing method: htmlEncode");
*/
@MayloonStubAnnotation()
public static String htmlEncode(String s) {
System.out.println("Stub" + " Function : htmlEncode");
return null;
}
/**
* @j2sNative
* console.log("Missing method: isGraphic");
*/
@MayloonStubAnnotation()
public static boolean isGraphic(char c) {
System.out.println("Stub" + " Function : isGraphic");
return true;
}
/**
* @j2sNative
* console.log("Missing method: isDigitsOnly");
*/
@MayloonStubAnnotation()
public static boolean isDigitsOnly(CharSequence str) {
System.out.println("Stub" + " Function : isDigitsOnly");
return true;
}
public static CharSequence stringOrSpannedString(CharSequence source) {
if (source == null)
return null;
if (source instanceof SpannedString)
return source;
if (source instanceof Spanned)
return new SpannedString(source);
return source.toString();
}
/**
* @j2sNative
* console.log("Missing method: isGraphic");
*/
@MayloonStubAnnotation()
public static boolean isGraphic(CharSequence str) {
System.out.println("Stub" + " Function : isGraphic");
return true;
}
/**
* @j2sNative
* console.log("Missing method: concat");
*/
@MayloonStubAnnotation()
public static CharSequence concat(CharSequence text) {
System.out.println("Stub" + " Function : concat");
return null;
}
}