diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java index 509068ac4..b1813a141 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java @@ -53,8 +53,6 @@ public final class KeySpecParser { private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Constants for parsing. - private static int COMMA = ','; - private static final char ESCAPE_CHAR = '\\'; private static final char LABEL_END = '|'; private static final String PREFIX_TEXT = "!text/"; static final String PREFIX_ICON = "!icon/"; @@ -80,14 +78,14 @@ public final class KeySpecParser { } private static String parseEscape(final String text) { - if (text.indexOf(ESCAPE_CHAR) < 0) { + if (text.indexOf(Constants.CSV_ESCAPE) < 0) { return text; } final int length = text.length(); final StringBuilder sb = new StringBuilder(); for (int pos = 0; pos < length; pos++) { final char c = text.charAt(pos); - if (c == ESCAPE_CHAR && pos + 1 < length) { + if (c == Constants.CSV_ESCAPE && pos + 1 < length) { // Skip escape char pos++; sb.append(text.charAt(pos)); @@ -99,7 +97,7 @@ public final class KeySpecParser { } private static int indexOfLabelEnd(final String moreKeySpec, final int start) { - if (moreKeySpec.indexOf(ESCAPE_CHAR, start) < 0) { + if (moreKeySpec.indexOf(Constants.CSV_ESCAPE, start) < 0) { final int end = moreKeySpec.indexOf(LABEL_END, start); if (end == 0) { throw new KeySpecParserError(LABEL_END + " at " + start + ": " + moreKeySpec); @@ -109,7 +107,7 @@ public final class KeySpecParser { final int length = moreKeySpec.length(); for (int pos = start; pos < length; pos++) { final char c = moreKeySpec.charAt(pos); - if (c == ESCAPE_CHAR && pos + 1 < length) { + if (c == Constants.CSV_ESCAPE && pos + 1 < length) { // Skip escape char pos++; } else if (c == LABEL_END) { @@ -353,7 +351,7 @@ public final class KeySpecParser { final String name = text.substring(pos + prefixLen, end); sb.append(textsSet.getText(name)); pos = end - 1; - } else if (c == ESCAPE_CHAR) { + } else if (c == Constants.CSV_ESCAPE) { if (sb != null) { // Append both escape character and escaped character. sb.append(text.substring(pos, Math.min(pos + 2, size))); @@ -385,45 +383,6 @@ public final class KeySpecParser { return size; } - public static String[] parseCsvString(final String rawText, final KeyboardTextsSet textsSet) { - final String text = resolveTextReference(rawText, textsSet); - final int size = text.length(); - if (size == 0) { - return null; - } - if (StringUtils.codePointCount(text) == 1) { - return text.codePointAt(0) == COMMA ? null : new String[] { text }; - } - - ArrayList list = null; - int start = 0; - for (int pos = 0; pos < size; pos++) { - final char c = text.charAt(pos); - if (c == COMMA) { - // Skip empty entry. - if (pos - start > 0) { - if (list == null) { - list = CollectionUtils.newArrayList(); - } - list.add(text.substring(start, pos)); - } - // Skip comma - start = pos + 1; - } else if (c == ESCAPE_CHAR) { - // Skip escape character and escaped character. - pos++; - } - } - final String remain = (size - start > 0) ? text.substring(start) : null; - if (list == null) { - return remain != null ? new String[] { remain } : null; - } - if (remain != null) { - list.add(remain); - } - return list.toArray(new String[list.size()]); - } - public static int getIntValue(final String[] moreKeys, final String key, final int defaultValue) { if (moreKeys == null) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java index fe75e20ae..5db3ebbd1 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java @@ -18,6 +18,8 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; +import com.android.inputmethod.latin.StringUtils; + public abstract class KeyStyle { private final KeyboardTextsSet mTextsSet; @@ -39,7 +41,8 @@ public abstract class KeyStyle { protected String[] parseStringArray(final TypedArray a, final int index) { if (a.hasValue(index)) { - return KeySpecParser.parseCsvString(a.getString(index), mTextsSet); + final String text = KeySpecParser.resolveTextReference(a.getString(index), mTextsSet); + return StringUtils.parseCsvString(text); } return null; } diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java index 85cc55232..422448edf 100644 --- a/java/src/com/android/inputmethod/latin/Constants.java +++ b/java/src/com/android/inputmethod/latin/Constants.java @@ -215,6 +215,10 @@ public final class Constants { } } + // Constants for CSV parsing. + public static final char CSV_SEPARATOR = ','; + public static final char CSV_ESCAPE = '\\'; + private Constants() { // This utility class is not publicly instantiable. } diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 728f6b281..d05868029 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -89,8 +89,8 @@ public final class SettingsValues { mWordConnectors = StringUtils.toCodePointArray(res.getString(R.string.symbols_word_connectors)); Arrays.sort(mWordConnectors); - final String[] suggestPuncsSpec = KeySpecParser.parseCsvString( - res.getString(R.string.suggested_punctuations), null); + final String[] suggestPuncsSpec = StringUtils.parseCsvString(res.getString( + R.string.suggested_punctuations)); mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec); mWordSeparators = res.getString(R.string.symbols_word_separators); mHintToSaveText = res.getText(R.string.hint_add_to_dictionary); @@ -211,6 +211,7 @@ public final class SettingsValues { final ArrayList puncList = CollectionUtils.newArrayList(); if (puncs != null) { for (final String puncSpec : puncs) { + // TODO: Stop using KeySpceParser.getLabel(). puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec), SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED, Dictionary.TYPE_HARDCODED)); diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java index d00edbe92..6fac0d2d3 100644 --- a/java/src/com/android/inputmethod/latin/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -372,4 +372,42 @@ public final class StringUtils { // Here we arrived at the start of the line. This should behave exactly like whitespace. return (START == state || LETTER == state) ? noCaps : caps; } + + public static String[] parseCsvString(final String text) { + final int size = text.length(); + if (size == 0) { + return null; + } + if (codePointCount(text) == 1) { + return text.codePointAt(0) == Constants.CSV_SEPARATOR ? null : new String[] { text }; + } + + ArrayList list = null; + int start = 0; + for (int pos = 0; pos < size; pos++) { + final char c = text.charAt(pos); + if (c == Constants.CSV_SEPARATOR) { + // Skip empty entry. + if (pos - start > 0) { + if (list == null) { + list = CollectionUtils.newArrayList(); + } + list.add(text.substring(start, pos)); + } + // Skip comma + start = pos + 1; + } else if (c == Constants.CSV_ESCAPE) { + // Skip escape character and escaped character. + pos++; + } + } + final String remain = (size - start > 0) ? text.substring(start) : null; + if (list == null) { + return remain != null ? new String[] { remain } : null; + } + if (remain != null) { + list.add(remain); + } + return list.toArray(new String[list.size()]); + } } diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java index cee62ca38..d58e1627f 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java @@ -21,6 +21,7 @@ import android.test.InstrumentationTestCase; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.latin.CollectionUtils; +import com.android.inputmethod.latin.StringUtils; import java.lang.reflect.Field; import java.util.ArrayList; @@ -74,7 +75,8 @@ public class KeySpecParserCsvTests extends InstrumentationTestCase { } private void assertTextArray(String message, String value, String ... expectedArray) { - final String[] actual = KeySpecParser.parseCsvString(value, mTextsSet); + final String resolvedActual = KeySpecParser.resolveTextReference(value, mTextsSet); + final String[] actual = StringUtils.parseCsvString(resolvedActual); final String[] expected = (expectedArray.length == 0) ? null : expectedArray; assertArrayEquals(message, expected, actual); }