am 5ea4365f: Merge "Create methods in LatinIME to make the current dict lists"
# Via Android (Google) Code Review (1) and Jean Chalard (1) * commit '5ea4365f077f59341430e00ed34a5d74b7877931': Create methods in LatinIME to make the current dict listsmain
commit
0d42b8cb8a
|
@ -76,7 +76,7 @@ final class BinaryDictionaryGetter {
|
||||||
/**
|
/**
|
||||||
* Returns a file address from a resource, or null if it cannot be opened.
|
* Returns a file address from a resource, or null if it cannot be opened.
|
||||||
*/
|
*/
|
||||||
private static AssetFileAddress loadFallbackResource(final Context context,
|
public static AssetFileAddress loadFallbackResource(final Context context,
|
||||||
final int fallbackResId) {
|
final int fallbackResId) {
|
||||||
final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId);
|
final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId);
|
||||||
if (afd == null) {
|
if (afd == null) {
|
||||||
|
@ -149,7 +149,7 @@ final class BinaryDictionaryGetter {
|
||||||
* @param context the context on which to open the files upon.
|
* @param context the context on which to open the files upon.
|
||||||
* @return an array of binary dictionary files, which may be empty but may not be null.
|
* @return an array of binary dictionary files, which may be empty but may not be null.
|
||||||
*/
|
*/
|
||||||
private static File[] getCachedWordLists(final String locale, final Context context) {
|
public static File[] getCachedWordLists(final String locale, final Context context) {
|
||||||
final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
|
final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
|
||||||
if (null == directoryList) return EMPTY_FILE_ARRAY;
|
if (null == directoryList) return EMPTY_FILE_ARRAY;
|
||||||
final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap();
|
final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,6 +43,18 @@ public class DictionaryInfoUtils {
|
||||||
// 6 digits - unicode is limited to 21 bits
|
// 6 digits - unicode is limited to 21 bits
|
||||||
private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6;
|
private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6;
|
||||||
|
|
||||||
|
public static class DictionaryInfo {
|
||||||
|
public final Locale mLocale;
|
||||||
|
public final AssetFileAddress mFileAddress;
|
||||||
|
public final int mVersion;
|
||||||
|
public DictionaryInfo(final Locale locale, final AssetFileAddress fileAddress,
|
||||||
|
final int version) {
|
||||||
|
mLocale = locale;
|
||||||
|
mFileAddress = fileAddress;
|
||||||
|
mVersion = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private DictionaryInfoUtils() {
|
private DictionaryInfoUtils() {
|
||||||
// Private constructor to forbid instantation of this helper class.
|
// Private constructor to forbid instantation of this helper class.
|
||||||
}
|
}
|
||||||
|
@ -234,12 +248,79 @@ public class DictionaryInfoUtils {
|
||||||
|
|
||||||
public static FileHeader getDictionaryFileHeaderOrNull(final File file) {
|
public static FileHeader getDictionaryFileHeaderOrNull(final File file) {
|
||||||
try {
|
try {
|
||||||
final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeader(file);
|
return BinaryDictIOUtils.getDictionaryFileHeader(file, 0, file.length());
|
||||||
return header;
|
|
||||||
} catch (UnsupportedFormatException e) {
|
} catch (UnsupportedFormatException e) {
|
||||||
return null;
|
return null;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DictionaryInfo createDictionaryInfoFromFileAddress(
|
||||||
|
final AssetFileAddress fileAddress) {
|
||||||
|
final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeaderOrNull(
|
||||||
|
new File(fileAddress.mFilename), fileAddress.mOffset, fileAddress.mLength);
|
||||||
|
final Locale locale = LocaleUtils.constructLocaleFromString(header.getLocaleString());
|
||||||
|
final String version = header.getVersion();
|
||||||
|
return new DictionaryInfo(locale, fileAddress, Integer.parseInt(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addOrUpdateDictInfo(final ArrayList<DictionaryInfo> dictList,
|
||||||
|
final DictionaryInfo newElement) {
|
||||||
|
for (final DictionaryInfo info : dictList) {
|
||||||
|
if (info.mLocale.equals(newElement.mLocale)) {
|
||||||
|
if (newElement.mVersion <= info.mVersion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dictList.remove(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dictList.add(newElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo(
|
||||||
|
final Context context) {
|
||||||
|
final ArrayList<DictionaryInfo> dictList = CollectionUtils.newArrayList();
|
||||||
|
|
||||||
|
// Retrieve downloaded dictionaries
|
||||||
|
final File[] directoryList = getCachedDirectoryList(context);
|
||||||
|
for (final File directory : directoryList) {
|
||||||
|
final String localeString = getWordListIdFromFileName(directory.getName());
|
||||||
|
File[] dicts = BinaryDictionaryGetter.getCachedWordLists(localeString, context);
|
||||||
|
for (final File dict : dicts) {
|
||||||
|
final String wordListId = getWordListIdFromFileName(dict.getName());
|
||||||
|
if (!DictionaryInfoUtils.isMainWordListId(wordListId)) continue;
|
||||||
|
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
|
||||||
|
final AssetFileAddress fileAddress = AssetFileAddress.makeFromFile(dict);
|
||||||
|
final DictionaryInfo dictionaryInfo =
|
||||||
|
createDictionaryInfoFromFileAddress(fileAddress);
|
||||||
|
// Protect against cases of a less-specific dictionary being found, like an
|
||||||
|
// en dictionary being used for an en_US locale. In this case, the en dictionary
|
||||||
|
// should be used for en_US but discounted for listing purposes.
|
||||||
|
if (!dictionaryInfo.mLocale.equals(locale)) continue;
|
||||||
|
addOrUpdateDictInfo(dictList, dictionaryInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve files from assets
|
||||||
|
final Resources resources = context.getResources();
|
||||||
|
final AssetManager assets = resources.getAssets();
|
||||||
|
for (final String localeString : assets.getLocales()) {
|
||||||
|
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
|
||||||
|
final int resourceId =
|
||||||
|
DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale(
|
||||||
|
context.getResources(), locale);
|
||||||
|
if (0 == resourceId) continue;
|
||||||
|
final AssetFileAddress fileAddress =
|
||||||
|
BinaryDictionaryGetter.loadFallbackResource(context, resourceId);
|
||||||
|
final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress);
|
||||||
|
// Protect against cases of a less-specific dictionary being found, like an
|
||||||
|
// en dictionary being used for an en_US locale. In this case, the en dictionary
|
||||||
|
// should be used for en_US but discounted for listing purposes.
|
||||||
|
if (!dictionaryInfo.mLocale.equals(locale)) continue;
|
||||||
|
addOrUpdateDictInfo(dictList, dictionaryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ import java.util.Locale;
|
||||||
public class ExternalDictionaryGetterForDebug {
|
public class ExternalDictionaryGetterForDebug {
|
||||||
private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
|
private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
|
||||||
+ "/Download";
|
+ "/Download";
|
||||||
private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
|
|
||||||
|
|
||||||
private static String[] findDictionariesInTheDownloadedFolder() {
|
private static String[] findDictionariesInTheDownloadedFolder() {
|
||||||
final File[] files = new File(SOURCE_FOLDER).listFiles();
|
final File[] files = new File(SOURCE_FOLDER).listFiles();
|
||||||
|
@ -90,8 +89,7 @@ public class ExternalDictionaryGetterForDebug {
|
||||||
final File file = new File(SOURCE_FOLDER, fileName.toString());
|
final File file = new File(SOURCE_FOLDER, fileName.toString());
|
||||||
final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file);
|
final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file);
|
||||||
final StringBuilder message = new StringBuilder();
|
final StringBuilder message = new StringBuilder();
|
||||||
final String locale =
|
final String locale = header.getLocaleString();
|
||||||
header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE);
|
|
||||||
for (String key : header.mDictionaryOptions.mAttributes.keySet()) {
|
for (String key : header.mDictionaryOptions.mAttributes.keySet()) {
|
||||||
message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
|
message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
|
||||||
message.append("\n");
|
message.append("\n");
|
||||||
|
@ -123,13 +121,11 @@ public class ExternalDictionaryGetterForDebug {
|
||||||
BufferedOutputStream outputStream = null;
|
BufferedOutputStream outputStream = null;
|
||||||
File tempFile = null;
|
File tempFile = null;
|
||||||
try {
|
try {
|
||||||
final String locale =
|
final String locale = header.getLocaleString();
|
||||||
header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE);
|
|
||||||
// Create the id for a main dictionary for this locale
|
// Create the id for a main dictionary for this locale
|
||||||
final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY
|
final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY
|
||||||
+ BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale;
|
+ BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale;
|
||||||
final String finalFileName =
|
final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context);
|
||||||
DictionaryInfoUtils.getCacheFileName(id, locale, context);
|
|
||||||
final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
|
final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
|
||||||
tempFile = new File(tempFileName);
|
tempFile = new File(tempFileName);
|
||||||
tempFile.delete();
|
tempFile.delete();
|
||||||
|
|
|
@ -988,9 +988,12 @@ public final class BinaryDictIOUtils {
|
||||||
* This is quite resource intensive - don't call when performance is critical.
|
* This is quite resource intensive - don't call when performance is critical.
|
||||||
*
|
*
|
||||||
* @param file The file to read.
|
* @param file The file to read.
|
||||||
|
* @param offset The offset in the file where to start reading the data.
|
||||||
|
* @param length The length of the data file.
|
||||||
*/
|
*/
|
||||||
private static final int HEADER_READING_BUFFER_SIZE = 16384;
|
private static final int HEADER_READING_BUFFER_SIZE = 16384;
|
||||||
public static FileHeader getDictionaryFileHeader(final File file)
|
public static FileHeader getDictionaryFileHeader(
|
||||||
|
final File file, final long offset, final long length)
|
||||||
throws FileNotFoundException, IOException, UnsupportedFormatException {
|
throws FileNotFoundException, IOException, UnsupportedFormatException {
|
||||||
final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE];
|
final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE];
|
||||||
final FileInputStream inStream = new FileInputStream(file);
|
final FileInputStream inStream = new FileInputStream(file);
|
||||||
|
@ -998,10 +1001,22 @@ public final class BinaryDictIOUtils {
|
||||||
inStream.read(buffer);
|
inStream.read(buffer);
|
||||||
final BinaryDictInputOutput.ByteBufferWrapper wrapper =
|
final BinaryDictInputOutput.ByteBufferWrapper wrapper =
|
||||||
new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map(
|
new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map(
|
||||||
FileChannel.MapMode.READ_ONLY, 0, file.length()));
|
FileChannel.MapMode.READ_ONLY, offset, length));
|
||||||
return BinaryDictInputOutput.readHeader(wrapper);
|
return BinaryDictInputOutput.readHeader(wrapper);
|
||||||
} finally {
|
} finally {
|
||||||
inStream.close();
|
inStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileHeader getDictionaryFileHeaderOrNull(final File file, final long offset,
|
||||||
|
final long length) {
|
||||||
|
try {
|
||||||
|
final FileHeader header = getDictionaryFileHeader(file, offset, length);
|
||||||
|
return header;
|
||||||
|
} catch (UnsupportedFormatException e) {
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,12 +256,24 @@ public final class FormatSpec {
|
||||||
public final int mHeaderSize;
|
public final int mHeaderSize;
|
||||||
public final DictionaryOptions mDictionaryOptions;
|
public final DictionaryOptions mDictionaryOptions;
|
||||||
public final FormatOptions mFormatOptions;
|
public final FormatOptions mFormatOptions;
|
||||||
|
private static final String DICTIONARY_VERSION_ATTRIBUTE = "version";
|
||||||
|
private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
|
||||||
public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
|
public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
|
||||||
final FormatOptions formatOptions) {
|
final FormatOptions formatOptions) {
|
||||||
mHeaderSize = headerSize;
|
mHeaderSize = headerSize;
|
||||||
mDictionaryOptions = dictionaryOptions;
|
mDictionaryOptions = dictionaryOptions;
|
||||||
mFormatOptions = formatOptions;
|
mFormatOptions = formatOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to get the locale as a String
|
||||||
|
public String getLocaleString() {
|
||||||
|
return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to get the version String
|
||||||
|
public String getVersion() {
|
||||||
|
return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_VERSION_ATTRIBUTE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private FormatSpec() {
|
private FormatSpec() {
|
||||||
|
|
Loading…
Reference in New Issue