1 /* 2 * Copyright (C) 2013 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.makedict; 18 19 import com.android.inputmethod.annotations.UsedForTesting; 20 import com.android.inputmethod.latin.BinaryDictionary; 21 import com.android.inputmethod.latin.utils.FileUtils; 22 23 import java.io.File; 24 import java.io.FileNotFoundException; 25 import java.io.IOException; 26 import java.util.ArrayList; 27 28 /** 29 * An implementation of binary dictionary decoder for version 4 binary dictionary. 30 */ 31 @UsedForTesting 32 public class Ver4DictDecoder extends AbstractDictDecoder { 33 final File mDictDirectory; 34 35 @UsedForTesting 36 /* package */ Ver4DictDecoder(final File dictDirectory, final int factoryFlag) { 37 this(dictDirectory, null /* factory */); 38 } 39 40 @UsedForTesting 41 /* package */ Ver4DictDecoder(final File dictDirectory, final DictionaryBufferFactory factory) { 42 mDictDirectory = dictDirectory; 43 44 } 45 46 @Override 47 public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException { 48 // dictType is not being used in dicttool. Passing an empty string. 49 final BinaryDictionary binaryDictionary= new BinaryDictionary( 50 mDictDirectory.getAbsolutePath(), 0 /* offset */, 0 /* length */, 51 true /* useFullEditDistance */, null /* locale */, 52 "" /* dictType */, true /* isUpdatable */); 53 final DictionaryHeader header = binaryDictionary.getHeader(); 54 binaryDictionary.close(); 55 if (header == null) { 56 throw new IOException("Cannot read the dictionary header."); 57 } 58 return header; 59 } 60 61 @Override 62 public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken) 63 throws FileNotFoundException, IOException, UnsupportedFormatException { 64 // dictType is not being used in dicttool. Passing an empty string. 65 final BinaryDictionary binaryDictionary = new BinaryDictionary( 66 mDictDirectory.getAbsolutePath(), 0 /* offset */, 0 /* length */, 67 true /* useFullEditDistance */, null /* locale */, 68 "" /* dictType */, true /* isUpdatable */); 69 final DictionaryHeader header = readHeader(); 70 final FusionDictionary fusionDict = 71 new FusionDictionary(new FusionDictionary.PtNodeArray(), header.mDictionaryOptions); 72 int token = 0; 73 final ArrayList<WordProperty> wordProperties = new ArrayList<>(); 74 do { 75 final BinaryDictionary.GetNextWordPropertyResult result = 76 binaryDictionary.getNextWordProperty(token); 77 final WordProperty wordProperty = result.mWordProperty; 78 if (wordProperty == null) { 79 binaryDictionary.close(); 80 if (deleteDictIfBroken) { 81 FileUtils.deleteRecursively(mDictDirectory); 82 } 83 return null; 84 } 85 wordProperties.add(wordProperty); 86 token = result.mNextToken; 87 } while (token != 0); 88 89 // Insert unigrams into the fusion dictionary. 90 for (final WordProperty wordProperty : wordProperties) { 91 if (wordProperty.mIsBlacklistEntry) { 92 fusionDict.addBlacklistEntry(wordProperty.mWord, wordProperty.mShortcutTargets, 93 wordProperty.mIsNotAWord); 94 } else { 95 fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, 96 wordProperty.mShortcutTargets, wordProperty.mIsNotAWord); 97 } 98 } 99 // Insert bigrams into the fusion dictionary. 100 for (final WordProperty wordProperty : wordProperties) { 101 if (wordProperty.mBigrams == null) { 102 continue; 103 } 104 final String word0 = wordProperty.mWord; 105 for (final WeightedString bigram : wordProperty.mBigrams) { 106 fusionDict.setBigram(word0, bigram.mWord, bigram.mProbabilityInfo); 107 } 108 } 109 binaryDictionary.close(); 110 return fusionDict; 111 } 112 } 113