diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/BinaryDictionary.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionary.java | 120 |
1 files changed, 80 insertions, 40 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 08ddd25fa..fa90fce67 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -26,14 +26,18 @@ import android.util.Log; import java.io.File; import java.util.Arrays; +import java.util.Locale; /** * Implements a static, compacted, binary dictionary of standard words. */ public class BinaryDictionary extends Dictionary { + public static final String DICTIONARY_PACK_AUTHORITY = + "com.android.inputmethod.latin.dictionarypack"; + /** - * There is difference between what java and native code can handle. + * There is a difference between what java and native code can handle. * This value should only be used in BinaryDictionary.java * It is necessary to keep it at this value because some languages e.g. German have * really long words. @@ -54,38 +58,42 @@ public class BinaryDictionary extends Dictionary { private final int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_PROXIMITY_CHARS_SIZE]; private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; - private final int[] mFrequencies = new int[MAX_WORDS]; - private final int[] mFrequencies_bigrams = new int[MAX_BIGRAMS]; + private final int[] mScores = new int[MAX_WORDS]; + private final int[] mBigramScores = new int[MAX_BIGRAMS]; private final KeyboardSwitcher mKeyboardSwitcher = KeyboardSwitcher.getInstance(); - private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance(); - - private static class Flags { - private static class FlagEntry { - public final String mName; - public final int mValue; - public FlagEntry(String name, int value) { - mName = name; - mValue = value; - } + + public static class Flag { + public final String mName; + public final int mValue; + + public Flag(String name, int value) { + mName = name; + mValue = value; } - public static final FlagEntry[] ALL_FLAGS = { - // Here should reside all flags that trigger some special processing - // These *must* match the definition in UnigramDictionary enum in - // unigram_dictionary.h so please update both at the same time. - new FlagEntry("requiresGermanUmlautProcessing", 0x1) - }; } + + public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING = + new Flag("requiresGermanUmlautProcessing", 0x1); + + private static final Flag[] ALL_FLAGS = { + // Here should reside all flags that trigger some special processing + // These *must* match the definition in UnigramDictionary enum in + // unigram_dictionary.h so please update both at the same time. + FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING, + }; + private int mFlags = 0; private BinaryDictionary() { } /** - * Initialize a dictionary from a raw resource file + * Initializes a dictionary from a raw resource file * @param context application context for reading resources * @param resId the resource containing the raw binary dictionary - * @return initialized instance of BinaryDictionary + * @param dicTypeId the type of the dictionary being created, out of the list in Suggest.DIC_* + * @return an initialized instance of BinaryDictionary */ public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) { synchronized (sInstance) { @@ -110,12 +118,12 @@ public class BinaryDictionary extends Dictionary { return null; } } - sInstance.initFlags(); + sInstance.mFlags = initFlags(ALL_FLAGS, SubtypeSwitcher.getInstance()); return sInstance; } /* package for test */ static BinaryDictionary initDictionary(File dictionary, long startOffset, - long length, int dicTypeId) { + long length, int dicTypeId, Flag[] flagArray) { synchronized (sInstance) { sInstance.closeInternal(); if (dictionary.isFile()) { @@ -126,22 +134,54 @@ public class BinaryDictionary extends Dictionary { return null; } } + sInstance.mFlags = initFlags(flagArray, null); return sInstance; } - private void initFlags() { + private static int initFlags(Flag[] flagArray, SubtypeSwitcher switcher) { int flags = 0; - for (Flags.FlagEntry entry : Flags.ALL_FLAGS) { - if (mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(entry.mName)) + for (Flag entry : flagArray) { + if (switcher == null || switcher.currentSubtypeContainsExtraValueKey(entry.mName)) flags |= entry.mValue; } - mFlags = flags; + return flags; } static { Utils.loadNativeLibrary(); } + /** + * Initializes a dictionary from a dictionary pack. + * + * This searches for a content provider providing a dictionary pack for the specified + * locale. If none is found, it falls back to using the resource passed as fallBackResId + * as a dictionary. + * @param context application context for reading resources + * @param dicTypeId the type of the dictionary being created, out of the list in Suggest.DIC_* + * @param locale the locale for which to create the dictionary + * @param fallBackResId the id of the resource to use as a fallback if no pack is found + * @return an initialized instance of BinaryDictionary + */ + public static BinaryDictionary initDictionaryFromManager(Context context, int dicTypeId, + Locale locale, int fallbackResId) { + if (null == locale) { + Log.e(TAG, "No locale defined for dictionary"); + return initDictionary(context, fallbackResId, dicTypeId); + } + synchronized (sInstance) { + sInstance.closeInternal(); + + final AssetFileAddress dictFile = BinaryDictionaryGetter.getDictionaryFile(locale, + context, fallbackResId); + if (null != dictFile) { + sInstance.loadDictionary(dictFile.mFilename, dictFile.mOffset, dictFile.mLength); + sInstance.mDicTypeId = dicTypeId; + } + } + return sInstance; + } + private native int openNative(String sourceDir, long dictOffset, long dictSize, int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords, int maxAlternatives); @@ -149,14 +189,14 @@ public class BinaryDictionary extends Dictionary { private native boolean isValidWordNative(int nativeData, char[] word, int wordLength); private native int getSuggestionsNative(int dict, int proximityInfo, int[] xCoordinates, int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars, - int[] frequencies); + int[] scores); private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength, - int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies, + int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores, int maxWordLength, int maxBigrams, int maxAlternatives); private final void loadDictionary(String path, long startOffset, long length) { mNativeDict = openNative(path, startOffset, length, - TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER, + TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER, MAX_WORD_LENGTH, MAX_WORDS, MAX_PROXIMITY_CHARS_SIZE); mDictLength = length; } @@ -168,7 +208,7 @@ public class BinaryDictionary extends Dictionary { char[] chars = previousWord.toString().toCharArray(); Arrays.fill(mOutputChars_bigrams, (char) 0); - Arrays.fill(mFrequencies_bigrams, 0); + Arrays.fill(mBigramScores, 0); int codesSize = codes.size(); Arrays.fill(mInputCodes, -1); @@ -177,18 +217,18 @@ public class BinaryDictionary extends Dictionary { Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE)); int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize, - mOutputChars_bigrams, mFrequencies_bigrams, MAX_WORD_LENGTH, MAX_BIGRAMS, + mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS, MAX_PROXIMITY_CHARS_SIZE); for (int j = 0; j < count; ++j) { - if (mFrequencies_bigrams[j] < 1) break; + if (mBigramScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; int len = 0; while (len < MAX_WORD_LENGTH && mOutputChars_bigrams[start + len] != 0) { ++len; } if (len > 0) { - callback.addWord(mOutputChars_bigrams, start, len, mFrequencies_bigrams[j], + callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j], mDicTypeId, DataType.BIGRAM); } } @@ -197,17 +237,17 @@ public class BinaryDictionary extends Dictionary { @Override public void getWords(final WordComposer codes, final WordCallback callback) { final int count = getSuggestions(codes, mKeyboardSwitcher.getLatinKeyboard(), - mOutputChars, mFrequencies); + mOutputChars, mScores); for (int j = 0; j < count; ++j) { - if (mFrequencies[j] < 1) break; + if (mScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; int len = 0; while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) { ++len; } if (len > 0) { - callback.addWord(mOutputChars, start, len, mFrequencies[j], mDicTypeId, + callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId, DataType.UNIGRAM); } } @@ -218,7 +258,7 @@ public class BinaryDictionary extends Dictionary { } /* package for test */ int getSuggestions(final WordComposer codes, final Keyboard keyboard, - char[] outputChars, int[] frequencies) { + char[] outputChars, int[] scores) { if (!isValidDictionary()) return -1; final int codesSize = codes.size(); @@ -232,12 +272,12 @@ public class BinaryDictionary extends Dictionary { Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE)); } Arrays.fill(outputChars, (char) 0); - Arrays.fill(frequencies, 0); + Arrays.fill(scores, 0); return getSuggestionsNative( mNativeDict, keyboard.getProximityInfo(), codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, - mFlags, outputChars, frequencies); + mFlags, outputChars, scores); } @Override |