Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.latin.utils;
     18 
     19 import com.android.inputmethod.annotations.UsedForTesting;
     20 import com.android.inputmethod.latin.BinaryDictionary;
     21 import com.android.inputmethod.latin.common.StringUtils;
     22 import com.android.inputmethod.latin.makedict.DictionaryHeader;
     23 import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
     24 
     25 import java.io.File;
     26 import java.io.IOException;
     27 import java.util.Locale;
     28 import java.util.Map;
     29 import java.util.regex.Matcher;
     30 import java.util.regex.Pattern;
     31 
     32 public final class BinaryDictionaryUtils {
     33     private static final String TAG = BinaryDictionaryUtils.class.getSimpleName();
     34 
     35     private BinaryDictionaryUtils() {
     36         // This utility class is not publicly instantiable.
     37     }
     38 
     39     static {
     40         JniUtils.loadNativeLibrary();
     41     }
     42 
     43     @UsedForTesting
     44     private static native boolean createEmptyDictFileNative(String filePath, long dictVersion,
     45             String locale, String[] attributeKeyStringArray, String[] attributeValueStringArray);
     46     private static native float calcNormalizedScoreNative(int[] before, int[] after, int score);
     47     private static native int setCurrentTimeForTestNative(int currentTime);
     48 
     49     public static DictionaryHeader getHeader(final File dictFile)
     50             throws IOException, UnsupportedFormatException {
     51         return getHeaderWithOffsetAndLength(dictFile, 0 /* offset */, dictFile.length());
     52     }
     53 
     54     public static DictionaryHeader getHeaderWithOffsetAndLength(final File dictFile,
     55             final long offset, final long length) throws IOException, UnsupportedFormatException {
     56         // dictType is never used for reading the header. Passing an empty string.
     57         final BinaryDictionary binaryDictionary = new BinaryDictionary(
     58                 dictFile.getAbsolutePath(), offset, length,
     59                 true /* useFullEditDistance */, null /* locale */, "" /* dictType */,
     60                 false /* isUpdatable */);
     61         final DictionaryHeader header = binaryDictionary.getHeader();
     62         binaryDictionary.close();
     63         if (header == null) {
     64             throw new IOException();
     65         }
     66         return header;
     67     }
     68 
     69     public static boolean renameDict(final File dictFile, final File newDictFile) {
     70         if (dictFile.isFile()) {
     71             return dictFile.renameTo(newDictFile);
     72         } else if (dictFile.isDirectory()) {
     73             final String dictName = dictFile.getName();
     74             final String newDictName = newDictFile.getName();
     75             if (newDictFile.exists()) {
     76                 return false;
     77             }
     78             for (final File file : dictFile.listFiles()) {
     79                 if (!file.isFile()) {
     80                     continue;
     81                 }
     82                 final String fileName = file.getName();
     83                 final String newFileName = fileName.replaceFirst(
     84                         Pattern.quote(dictName), Matcher.quoteReplacement(newDictName));
     85                 if (!file.renameTo(new File(dictFile, newFileName))) {
     86                     return false;
     87                 }
     88             }
     89             return dictFile.renameTo(newDictFile);
     90         }
     91         return false;
     92     }
     93 
     94     @UsedForTesting
     95     public static boolean createEmptyDictFile(final String filePath, final long dictVersion,
     96             final Locale locale, final Map<String, String> attributeMap) {
     97         final String[] keyArray = new String[attributeMap.size()];
     98         final String[] valueArray = new String[attributeMap.size()];
     99         int index = 0;
    100         for (final String key : attributeMap.keySet()) {
    101             keyArray[index] = key;
    102             valueArray[index] = attributeMap.get(key);
    103             index++;
    104         }
    105         return createEmptyDictFileNative(filePath, dictVersion, locale.toString(), keyArray,
    106                 valueArray);
    107     }
    108 
    109     public static float calcNormalizedScore(final String before, final String after,
    110             final int score) {
    111         return calcNormalizedScoreNative(StringUtils.toCodePointArray(before),
    112                 StringUtils.toCodePointArray(after), score);
    113     }
    114 
    115     /**
    116      * Control the current time to be used in the native code. If currentTime >= 0, this method sets
    117      * the current time and gets into test mode.
    118      * In test mode, set timestamp is used as the current time in the native code.
    119      * If currentTime < 0, quit the test mode and returns to using time() to get the current time.
    120      *
    121      * @param currentTime seconds since the unix epoch
    122      * @return current time got in the native code.
    123      */
    124     @UsedForTesting
    125     public static int setCurrentTimeForTest(final int currentTime) {
    126         return setCurrentTimeForTestNative(currentTime);
    127     }
    128 }
    129