Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 753f7b12 authored by Jean Chalard's avatar Jean Chalard Committed by Android (Google) Code Review
Browse files

Merge "Hack to skip reading an outdated binary file." into jb-mr1-dev

parents 6c63f712 13822d2b
Loading
Loading
Loading
Loading
+46 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.inputmethod.latin;

import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -23,6 +25,7 @@ import android.content.res.AssetFileDescriptor;
import android.util.Log;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
@@ -51,6 +54,9 @@ class BinaryDictionaryGetter {
    private static final String MAIN_DICTIONARY_CATEGORY = "main";
    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
    private BinaryDictionaryGetter() {}

@@ -336,6 +342,42 @@ class BinaryDictionaryGetter {
        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.
     *
@@ -366,14 +408,15 @@ class BinaryDictionaryGetter {
        // cachedWordLists may not be null, see doc for getCachedDictionaryList
        for (final File f : cachedWordLists) {
            final String wordListId = getWordListIdFromFileName(f.getName());
            if (isMainWordListId(wordListId)) {
            final boolean canUse = f.canRead() && hackCanUseDictionaryFile(locale, f);
            if (canUse && isMainWordListId(wordListId)) {
                foundMainDict = true;
            }
            if (!dictPackSettings.isWordListActive(wordListId)) continue;
            if (f.canRead()) {
            if (canUse) {
                fileList.add(AssetFileAddress.makeFromFileName(f.getPath()));
            } 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");
            }
        }

+17 −6
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ public class BinaryDictInputOutput {
     */

    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 MAXIMUM_SUPPORTED_VERSION = 2;
    private static final int NOT_A_VERSION_NUMBER = -1;
@@ -1327,6 +1327,21 @@ public class BinaryDictInputOutput {
        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.
     *
@@ -1358,11 +1373,7 @@ public class BinaryDictInputOutput {
        } else {
            headerSize = (source.readUnsignedByte() << 24) + (source.readUnsignedByte() << 16)
                    + (source.readUnsignedByte() << 8) + source.readUnsignedByte();
            while (source.getFilePointer() < headerSize) {
                final String key = CharEncoding.readString(source);
                final String value = CharEncoding.readString(source);
                options.put(key, value);
            }
            populateOptionsFromFile(source, headerSize, options);
            source.seek(headerSize);
        }