am 7bf71ca8: am 753f7b12: Merge "Hack to skip reading an outdated binary file." into jb-mr1-dev
* commit '7bf71ca8090208a14716bcbbab992a0d90764cfc': Hack to skip reading an outdated binary file.main
commit
6563ba3b28
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
@ -23,6 +25,7 @@ import android.content.res.AssetFileDescriptor;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -51,6 +54,9 @@ class BinaryDictionaryGetter {
|
||||||
private static final String MAIN_DICTIONARY_CATEGORY = "main";
|
private static final String MAIN_DICTIONARY_CATEGORY = "main";
|
||||||
public static final String ID_CATEGORY_SEPARATOR = ":";
|
public static final String ID_CATEGORY_SEPARATOR = ":";
|
||||||
|
|
||||||
|
// The key considered to read the version attribute in a dictionary file.
|
||||||
|
private static String VERSION_KEY = "version";
|
||||||
|
|
||||||
// Prevents this from being instantiated
|
// Prevents this from being instantiated
|
||||||
private BinaryDictionaryGetter() {}
|
private BinaryDictionaryGetter() {}
|
||||||
|
|
||||||
|
@ -336,6 +342,42 @@ class BinaryDictionaryGetter {
|
||||||
return MAIN_DICTIONARY_CATEGORY.equals(idArray[0]);
|
return MAIN_DICTIONARY_CATEGORY.equals(idArray[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ## HACK ## we prevent usage of a dictionary before version 18 for English only. The reason
|
||||||
|
// for this is, since those do not include whitelist entries, the new code with an old version
|
||||||
|
// of the dictionary would lose whitelist functionality.
|
||||||
|
private static boolean hackCanUseDictionaryFile(final Locale locale, final File f) {
|
||||||
|
// Only for English - other languages didn't have a whitelist, hence this
|
||||||
|
// ad-hock ## HACK ##
|
||||||
|
if (!Locale.ENGLISH.getLanguage().equals(locale.getLanguage())) return true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Read the version of the file
|
||||||
|
final RandomAccessFile raf = new RandomAccessFile(f, "r");
|
||||||
|
final int magic = raf.readInt();
|
||||||
|
if (magic != BinaryDictInputOutput.VERSION_2_MAGIC_NUMBER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final int formatVersion = raf.readInt();
|
||||||
|
final int headerSize = raf.readInt();
|
||||||
|
final HashMap<String, String> options = new HashMap<String, String>();
|
||||||
|
BinaryDictInputOutput.populateOptionsFromFile(raf, headerSize, options);
|
||||||
|
final String version = options.get(VERSION_KEY);
|
||||||
|
if (null == version) {
|
||||||
|
// No version in the options : the format is unexpected
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Version 18 is the first one to include the whitelist
|
||||||
|
// Obviously this is a big ## HACK ##
|
||||||
|
return Integer.parseInt(version) >= 18;
|
||||||
|
} catch (java.io.FileNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
return false;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of file addresses for a given locale, trying relevant methods in order.
|
* Returns a list of file addresses for a given locale, trying relevant methods in order.
|
||||||
*
|
*
|
||||||
|
@ -366,14 +408,15 @@ class BinaryDictionaryGetter {
|
||||||
// cachedWordLists may not be null, see doc for getCachedDictionaryList
|
// cachedWordLists may not be null, see doc for getCachedDictionaryList
|
||||||
for (final File f : cachedWordLists) {
|
for (final File f : cachedWordLists) {
|
||||||
final String wordListId = getWordListIdFromFileName(f.getName());
|
final String wordListId = getWordListIdFromFileName(f.getName());
|
||||||
if (isMainWordListId(wordListId)) {
|
final boolean canUse = f.canRead() && hackCanUseDictionaryFile(locale, f);
|
||||||
|
if (canUse && isMainWordListId(wordListId)) {
|
||||||
foundMainDict = true;
|
foundMainDict = true;
|
||||||
}
|
}
|
||||||
if (!dictPackSettings.isWordListActive(wordListId)) continue;
|
if (!dictPackSettings.isWordListActive(wordListId)) continue;
|
||||||
if (f.canRead()) {
|
if (canUse) {
|
||||||
fileList.add(AssetFileAddress.makeFromFileName(f.getPath()));
|
fileList.add(AssetFileAddress.makeFromFileName(f.getPath()));
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Found a cached dictionary file but cannot read it");
|
Log.e(TAG, "Found a cached dictionary file but cannot read or use it");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class BinaryDictInputOutput {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static final int VERSION_1_MAGIC_NUMBER = 0x78B1;
|
private static final int VERSION_1_MAGIC_NUMBER = 0x78B1;
|
||||||
private static final int VERSION_2_MAGIC_NUMBER = 0x9BC13AFE;
|
public static final int VERSION_2_MAGIC_NUMBER = 0x9BC13AFE;
|
||||||
private static final int MINIMUM_SUPPORTED_VERSION = 1;
|
private static final int MINIMUM_SUPPORTED_VERSION = 1;
|
||||||
private static final int MAXIMUM_SUPPORTED_VERSION = 2;
|
private static final int MAXIMUM_SUPPORTED_VERSION = 2;
|
||||||
private static final int NOT_A_VERSION_NUMBER = -1;
|
private static final int NOT_A_VERSION_NUMBER = -1;
|
||||||
|
@ -1327,6 +1327,21 @@ public class BinaryDictInputOutput {
|
||||||
return NOT_A_VERSION_NUMBER;
|
return NOT_A_VERSION_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads options from a file and populate a map with their contents.
|
||||||
|
*
|
||||||
|
* The file is read at the current file pointer, so the caller must take care the pointer
|
||||||
|
* is in the right place before calling this.
|
||||||
|
*/
|
||||||
|
public static void populateOptionsFromFile(final RandomAccessFile source, final long headerSize,
|
||||||
|
final HashMap<String, String> options) throws IOException {
|
||||||
|
while (source.getFilePointer() < headerSize) {
|
||||||
|
final String key = CharEncoding.readString(source);
|
||||||
|
final String value = CharEncoding.readString(source);
|
||||||
|
options.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a random access file and returns the memory representation of the dictionary.
|
* Reads a random access file and returns the memory representation of the dictionary.
|
||||||
*
|
*
|
||||||
|
@ -1358,11 +1373,7 @@ public class BinaryDictInputOutput {
|
||||||
} else {
|
} else {
|
||||||
headerSize = (source.readUnsignedByte() << 24) + (source.readUnsignedByte() << 16)
|
headerSize = (source.readUnsignedByte() << 24) + (source.readUnsignedByte() << 16)
|
||||||
+ (source.readUnsignedByte() << 8) + source.readUnsignedByte();
|
+ (source.readUnsignedByte() << 8) + source.readUnsignedByte();
|
||||||
while (source.getFilePointer() < headerSize) {
|
populateOptionsFromFile(source, headerSize, options);
|
||||||
final String key = CharEncoding.readString(source);
|
|
||||||
final String value = CharEncoding.readString(source);
|
|
||||||
options.put(key, value);
|
|
||||||
}
|
|
||||||
source.seek(headerSize);
|
source.seek(headerSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue