Loading java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +0 −65 Original line number Diff line number Diff line Loading @@ -48,13 +48,10 @@ import java.util.Arrays; public final class KeySpecParser { private static final boolean DEBUG = LatinImeLogger.sDBG; private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Constants for parsing. private static final char COMMA = ','; private static final char BACKSLASH = '\\'; private static final char VERTICAL_BAR = '|'; private static final String PREFIX_TEXT = "!text/"; static final String PREFIX_ICON = "!icon/"; private static final String PREFIX_CODE = "!code/"; private static final String PREFIX_HEX = "0x"; Loading Loading @@ -361,68 +358,6 @@ public final class KeySpecParser { } } public static String resolveTextReference(final String rawText, final KeyboardTextsSet textsSet) { if (TextUtils.isEmpty(rawText)) { return null; } int level = 0; String text = rawText; StringBuilder sb; do { level++; if (level >= MAX_STRING_REFERENCE_INDIRECTION) { throw new RuntimeException("too many @string/resource indirection: " + text); } final int prefixLen = PREFIX_TEXT.length(); final int size = text.length(); if (size < prefixLen) { return TextUtils.isEmpty(text) ? null : text; } sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); if (text.startsWith(PREFIX_TEXT, pos) && textsSet != null) { if (sb == null) { sb = new StringBuilder(text.substring(0, pos)); } final int end = searchTextNameEnd(text, pos + prefixLen); final String name = text.substring(pos + prefixLen, end); sb.append(textsSet.getText(name)); pos = end - 1; } else if (c == BACKSLASH) { if (sb != null) { // Append both escape character and escaped character. sb.append(text.substring(pos, Math.min(pos + 2, size))); } pos++; } else if (sb != null) { sb.append(c); } } if (sb != null) { text = sb.toString(); } } while (sb != null); return TextUtils.isEmpty(text) ? null : text; } private static int searchTextNameEnd(final String text, final int start) { final int size = text.length(); for (int pos = start; pos < size; pos++) { final char c = text.charAt(pos); // Label name should be consisted of [a-zA-Z_0-9]. if ((c >= 'a' && c <= 'z') || c == '_' || (c >= '0' && c <= '9')) { continue; } return pos; } return size; } public static int getIntValue(final String[] moreKeys, final String key, final int defaultValue) { if (moreKeys == null) { Loading java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java +2 −2 Original line number Diff line number Diff line Loading @@ -32,14 +32,14 @@ public abstract class KeyStyle { protected String parseString(final TypedArray a, final int index) { if (a.hasValue(index)) { return KeySpecParser.resolveTextReference(a.getString(index), mTextsSet); return mTextsSet.resolveTextReference(a.getString(index)); } return null; } protected String[] parseStringArray(final TypedArray a, final int index) { if (a.hasValue(index)) { final String text = KeySpecParser.resolveTextReference(a.getString(index), mTextsSet); final String text = mTextsSet.resolveTextReference(a.getString(index)); return KeySpecParser.splitKeySpecs(text); } return null; Loading java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +66 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard.internal; import android.content.Context; import android.content.res.Resources; import android.text.TextUtils; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.utils.CollectionUtils; Loading Loading @@ -45,6 +46,10 @@ import java.util.HashMap; * KeyboardTextsSet.java */ public final class KeyboardTextsSet { private static final String PREFIX_TEXT = "!text/"; private static final char BACKSLASH = '\\'; private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Language to texts map. private static final HashMap<String, String[]> sLocaleToTextsMap = CollectionUtils.newHashMap(); private static final HashMap<String, Integer> sNameToIdsMap = CollectionUtils.newHashMap(); Loading Loading @@ -87,6 +92,67 @@ public final class KeyboardTextsSet { return (text == null) ? LANGUAGE_DEFAULT[id] : text; } private static int searchTextNameEnd(final String text, final int start) { final int size = text.length(); for (int pos = start; pos < size; pos++) { final char c = text.charAt(pos); // Label name should be consisted of [a-zA-Z_0-9]. if ((c >= 'a' && c <= 'z') || c == '_' || (c >= '0' && c <= '9')) { continue; } return pos; } return size; } public String resolveTextReference(final String rawText) { if (TextUtils.isEmpty(rawText)) { return null; } int level = 0; String text = rawText; StringBuilder sb; do { level++; if (level >= MAX_STRING_REFERENCE_INDIRECTION) { throw new RuntimeException("too many @string/resource indirection: " + text); } final int prefixLen = PREFIX_TEXT.length(); final int size = text.length(); if (size < prefixLen) { return TextUtils.isEmpty(text) ? null : text; } sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); if (text.startsWith(PREFIX_TEXT, pos)) { if (sb == null) { sb = new StringBuilder(text.substring(0, pos)); } final int end = searchTextNameEnd(text, pos + prefixLen); final String name = text.substring(pos + prefixLen, end); sb.append(getText(name)); pos = end - 1; } else if (c == BACKSLASH) { if (sb != null) { // Append both escape character and escaped character. sb.append(text.substring(pos, Math.min(pos + 2, size))); } pos++; } else if (sb != null) { sb.append(c); } } if (sb != null) { text = sb.toString(); } } while (sb != null); return TextUtils.isEmpty(text) ? null : text; } // These texts' name should be aligned with the @string/<name> in // values*/strings-action-keys.xml. private static final String[] RESOURCE_NAMES = { Loading tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java +3 −5 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase { private void assertTextArray(final String message, final String value, final String ... expectedArray) { final String resolvedActual = KeySpecParser.resolveTextReference(value, mTextsSet); final String resolvedActual = mTextsSet.resolveTextReference(value); final String[] actual = KeySpecParser.splitKeySpecs(resolvedActual); final String[] expected = (expectedArray.length == 0) ? null : expectedArray; assertArrayEquals(message, expected, actual); Loading @@ -117,13 +117,11 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase { private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3; public void testResolveNullText() { assertNull("resolve null", KeySpecParser.resolveTextReference( null, mTextsSet)); assertNull("resolve null", mTextsSet.resolveTextReference(null)); } public void testResolveEmptyText() { assertNull("resolve empty text", KeySpecParser.resolveTextReference( "!text/empty_string", mTextsSet)); assertNull("resolve empty text", mTextsSet.resolveTextReference("!text/empty_string")); } public void testSplitZero() { Loading tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ public class KeySpecParserTests extends AndroidTestCase { private void assertParser(String message, String moreKeySpec, String expectedLabel, String expectedOutputText, int expectedIcon, int expectedCode) { final String labelResolved = KeySpecParser.resolveTextReference(moreKeySpec, mTextsSet); final String labelResolved = mTextsSet.resolveTextReference(moreKeySpec); final MoreKeySpec spec = new MoreKeySpec(labelResolved, false /* needsToUpperCase */, Locale.US, mCodesSet); assertEquals(message + " [label]", expectedLabel, spec.mLabel); Loading Loading
java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +0 −65 Original line number Diff line number Diff line Loading @@ -48,13 +48,10 @@ import java.util.Arrays; public final class KeySpecParser { private static final boolean DEBUG = LatinImeLogger.sDBG; private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Constants for parsing. private static final char COMMA = ','; private static final char BACKSLASH = '\\'; private static final char VERTICAL_BAR = '|'; private static final String PREFIX_TEXT = "!text/"; static final String PREFIX_ICON = "!icon/"; private static final String PREFIX_CODE = "!code/"; private static final String PREFIX_HEX = "0x"; Loading Loading @@ -361,68 +358,6 @@ public final class KeySpecParser { } } public static String resolveTextReference(final String rawText, final KeyboardTextsSet textsSet) { if (TextUtils.isEmpty(rawText)) { return null; } int level = 0; String text = rawText; StringBuilder sb; do { level++; if (level >= MAX_STRING_REFERENCE_INDIRECTION) { throw new RuntimeException("too many @string/resource indirection: " + text); } final int prefixLen = PREFIX_TEXT.length(); final int size = text.length(); if (size < prefixLen) { return TextUtils.isEmpty(text) ? null : text; } sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); if (text.startsWith(PREFIX_TEXT, pos) && textsSet != null) { if (sb == null) { sb = new StringBuilder(text.substring(0, pos)); } final int end = searchTextNameEnd(text, pos + prefixLen); final String name = text.substring(pos + prefixLen, end); sb.append(textsSet.getText(name)); pos = end - 1; } else if (c == BACKSLASH) { if (sb != null) { // Append both escape character and escaped character. sb.append(text.substring(pos, Math.min(pos + 2, size))); } pos++; } else if (sb != null) { sb.append(c); } } if (sb != null) { text = sb.toString(); } } while (sb != null); return TextUtils.isEmpty(text) ? null : text; } private static int searchTextNameEnd(final String text, final int start) { final int size = text.length(); for (int pos = start; pos < size; pos++) { final char c = text.charAt(pos); // Label name should be consisted of [a-zA-Z_0-9]. if ((c >= 'a' && c <= 'z') || c == '_' || (c >= '0' && c <= '9')) { continue; } return pos; } return size; } public static int getIntValue(final String[] moreKeys, final String key, final int defaultValue) { if (moreKeys == null) { Loading
java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java +2 −2 Original line number Diff line number Diff line Loading @@ -32,14 +32,14 @@ public abstract class KeyStyle { protected String parseString(final TypedArray a, final int index) { if (a.hasValue(index)) { return KeySpecParser.resolveTextReference(a.getString(index), mTextsSet); return mTextsSet.resolveTextReference(a.getString(index)); } return null; } protected String[] parseStringArray(final TypedArray a, final int index) { if (a.hasValue(index)) { final String text = KeySpecParser.resolveTextReference(a.getString(index), mTextsSet); final String text = mTextsSet.resolveTextReference(a.getString(index)); return KeySpecParser.splitKeySpecs(text); } return null; Loading
java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +66 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard.internal; import android.content.Context; import android.content.res.Resources; import android.text.TextUtils; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.utils.CollectionUtils; Loading Loading @@ -45,6 +46,10 @@ import java.util.HashMap; * KeyboardTextsSet.java */ public final class KeyboardTextsSet { private static final String PREFIX_TEXT = "!text/"; private static final char BACKSLASH = '\\'; private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Language to texts map. private static final HashMap<String, String[]> sLocaleToTextsMap = CollectionUtils.newHashMap(); private static final HashMap<String, Integer> sNameToIdsMap = CollectionUtils.newHashMap(); Loading Loading @@ -87,6 +92,67 @@ public final class KeyboardTextsSet { return (text == null) ? LANGUAGE_DEFAULT[id] : text; } private static int searchTextNameEnd(final String text, final int start) { final int size = text.length(); for (int pos = start; pos < size; pos++) { final char c = text.charAt(pos); // Label name should be consisted of [a-zA-Z_0-9]. if ((c >= 'a' && c <= 'z') || c == '_' || (c >= '0' && c <= '9')) { continue; } return pos; } return size; } public String resolveTextReference(final String rawText) { if (TextUtils.isEmpty(rawText)) { return null; } int level = 0; String text = rawText; StringBuilder sb; do { level++; if (level >= MAX_STRING_REFERENCE_INDIRECTION) { throw new RuntimeException("too many @string/resource indirection: " + text); } final int prefixLen = PREFIX_TEXT.length(); final int size = text.length(); if (size < prefixLen) { return TextUtils.isEmpty(text) ? null : text; } sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); if (text.startsWith(PREFIX_TEXT, pos)) { if (sb == null) { sb = new StringBuilder(text.substring(0, pos)); } final int end = searchTextNameEnd(text, pos + prefixLen); final String name = text.substring(pos + prefixLen, end); sb.append(getText(name)); pos = end - 1; } else if (c == BACKSLASH) { if (sb != null) { // Append both escape character and escaped character. sb.append(text.substring(pos, Math.min(pos + 2, size))); } pos++; } else if (sb != null) { sb.append(c); } } if (sb != null) { text = sb.toString(); } } while (sb != null); return TextUtils.isEmpty(text) ? null : text; } // These texts' name should be aligned with the @string/<name> in // values*/strings-action-keys.xml. private static final String[] RESOURCE_NAMES = { Loading
tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java +3 −5 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase { private void assertTextArray(final String message, final String value, final String ... expectedArray) { final String resolvedActual = KeySpecParser.resolveTextReference(value, mTextsSet); final String resolvedActual = mTextsSet.resolveTextReference(value); final String[] actual = KeySpecParser.splitKeySpecs(resolvedActual); final String[] expected = (expectedArray.length == 0) ? null : expectedArray; assertArrayEquals(message, expected, actual); Loading @@ -117,13 +117,11 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase { private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3; public void testResolveNullText() { assertNull("resolve null", KeySpecParser.resolveTextReference( null, mTextsSet)); assertNull("resolve null", mTextsSet.resolveTextReference(null)); } public void testResolveEmptyText() { assertNull("resolve empty text", KeySpecParser.resolveTextReference( "!text/empty_string", mTextsSet)); assertNull("resolve empty text", mTextsSet.resolveTextReference("!text/empty_string")); } public void testSplitZero() { Loading
tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ public class KeySpecParserTests extends AndroidTestCase { private void assertParser(String message, String moreKeySpec, String expectedLabel, String expectedOutputText, int expectedIcon, int expectedCode) { final String labelResolved = KeySpecParser.resolveTextReference(moreKeySpec, mTextsSet); final String labelResolved = mTextsSet.resolveTextReference(moreKeySpec); final MoreKeySpec spec = new MoreKeySpec(labelResolved, false /* needsToUpperCase */, Locale.US, mCodesSet); assertEquals(message + " [label]", expectedLabel, spec.mLabel); Loading