1065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada/*
2065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * Copyright (C) 2013 The Android Open Source Project
3065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada *
4065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * Licensed under the Apache License, Version 2.0 (the "License");
5065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * you may not use this file except in compliance with the License.
6065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * You may obtain a copy of the License at
7065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada *
8065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada *      http://www.apache.org/licenses/LICENSE-2.0
9065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada *
10065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * Unless required by applicable law or agreed to in writing, software
11065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * distributed under the License is distributed on an "AS IS" BASIS,
12065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * See the License for the specific language governing permissions and
14065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada * limitations under the License.
15065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada */
16065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
17065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadapackage com.android.inputmethod.latin.makedict;
18065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
19065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport com.android.inputmethod.annotations.UsedForTesting;
20065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
21065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
22065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
23065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.io.File;
24065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.io.FileInputStream;
25065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.io.FileNotFoundException;
26065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.io.IOException;
27065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.io.RandomAccessFile;
28065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.nio.ByteBuffer;
29065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanadaimport java.nio.channels.FileChannel;
30752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanadaimport java.util.ArrayList;
31752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanadaimport java.util.TreeMap;
32065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
33065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada/**
3414d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada * An interface of binary dictionary decoders.
35065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada */
362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa// TODO: Straighten out responsibility for the buffer's file pointer.
3714d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanadapublic interface DictDecoder {
3814087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada
3914087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada    /**
4014087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada     * Reads and returns the file header.
4114087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada     */
42b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi    public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException;
43558e34c7bd8b146695ce1dbda6ed9933ddd19300Yuichiro Hanada
44107a5f6fb81a91a98fecd4c291aabb421e963291Yuichiro Hanada    /**
452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa     * Reads PtNode from ptNodePos.
46558e34c7bd8b146695ce1dbda6ed9933ddd19300Yuichiro Hanada     * @param ptNodePos the position of PtNode.
47576f625ee1b22e26baab46cc4ad3138e901383e2Yuichiro Hanada     * @return PtNodeInfo.
48107a5f6fb81a91a98fecd4c291aabb421e963291Yuichiro Hanada     */
4995d16561e0e6c38dbd99c893f09c5dbe9d4a465dKeisuke Kuroyanagi    public PtNodeInfo readPtNode(final int ptNodePos);
50065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
51e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada    /**
52e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada     * Reads a buffer and returns the memory representation of the dictionary.
53e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada     *
54e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada     * This high-level method takes a buffer and reads its contents, populating a
558e3a1d0f89ac5a0c7d31effb8cbb447f93f70310Keisuke Kuroyanagi     * FusionDictionary structure.
56e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada     *
5795bc256f419e9e47c26dfefd1ac31266dac2f344Yuichiro Hanada     * @param deleteDictIfBroken a flag indicating whether this method should remove the broken
5895bc256f419e9e47c26dfefd1ac31266dac2f344Yuichiro Hanada     * dictionary or not.
598e3a1d0f89ac5a0c7d31effb8cbb447f93f70310Keisuke Kuroyanagi     * @return the created dictionary.
60e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada     */
61e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada    @UsedForTesting
628e3a1d0f89ac5a0c7d31effb8cbb447f93f70310Keisuke Kuroyanagi    public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken)
638e3a1d0f89ac5a0c7d31effb8cbb447f93f70310Keisuke Kuroyanagi            throws FileNotFoundException, IOException, UnsupportedFormatException;
64e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada
65bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada    /**
66bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     * Gets the address of the last PtNode of the exact matching word in the dictionary.
67bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     * If no match is found, returns NOT_VALID_WORD.
68bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     *
69bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     * @param word the word we search for.
70bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     * @return the address of the terminal node.
71bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     * @throws IOException if the file can't be read.
72bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     * @throws UnsupportedFormatException if the format of the file is not recognized.
73bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada     */
74bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada    @UsedForTesting
75bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada    public int getTerminalPosition(final String word)
7614d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada            throws IOException, UnsupportedFormatException;
77bb5b84a82630bc2309c9ae866d43c7934768bb2eYuichiro Hanada
78752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada    /**
79752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * Reads unigrams and bigrams from the binary file.
80752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * Doesn't store a full memory representation of the dictionary.
81752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     *
82752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * @param words the map to store the address as a key and the word as a value.
83752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * @param frequencies the map to store the address as a key and the frequency as a value.
84752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * @param bigrams the map to store the address as a key and the list of address as a value.
85752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * @throws IOException if the file can't be read.
86752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     * @throws UnsupportedFormatException if the format of the file is not recognized.
87752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada     */
8814087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada    @UsedForTesting
89752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada    public void readUnigramsAndBigramsBinary(final TreeMap<Integer, String> words,
90752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada            final TreeMap<Integer, Integer> frequencies,
91752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada            final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams)
9214d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada                throws IOException, UnsupportedFormatException;
93752a33640c0160a2f836f716bf60e4991c07da1cYuichiro Hanada
94be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada    /**
95be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     * Sets the position of the buffer to the given value.
96be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     *
97be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     * @param newPos the new position
98be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     */
9914d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada    public void setPosition(final int newPos);
100be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada
101be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada    /**
102be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     * Gets the position of the buffer.
103be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     *
104be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     * @return the position
105be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     */
10614d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada    public int getPosition();
107be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada
108be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada    /**
109be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     * Reads and returns the PtNode count out of a buffer and forwards the pointer.
110be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada     */
11114d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada    public int readPtNodeCount();
112be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada
113be470f06e48e40a0def32e0f34e3ca48113937b5Yuichiro Hanada    /**
1140e40cd0c40f2c731f91ccd0561e251262e5a2614Yuichiro Hanada     * Opens the dictionary file and makes DictBuffer.
1150e40cd0c40f2c731f91ccd0561e251262e5a2614Yuichiro Hanada     */
1160e40cd0c40f2c731f91ccd0561e251262e5a2614Yuichiro Hanada    @UsedForTesting
1172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    public void openDictBuffer() throws FileNotFoundException, IOException,
1182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            UnsupportedFormatException;
1190e40cd0c40f2c731f91ccd0561e251262e5a2614Yuichiro Hanada    @UsedForTesting
12014d31d464037c31e7f7d382a8a86f6acf4694b06Yuichiro Hanada    public boolean isDictBufferOpen();
1210e40cd0c40f2c731f91ccd0561e251262e5a2614Yuichiro Hanada
12214087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada    // Constants for DictionaryBufferFactory.
123e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada    public static final int USE_READONLY_BYTEBUFFER = 0x01000000;
124e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada    public static final int USE_BYTEARRAY = 0x02000000;
12514087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada    public static final int USE_WRITABLE_BYTEBUFFER = 0x03000000;
126e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada    public static final int MASK_DICTBUFFER = 0x0F000000;
127e9a10ff0f026b5ec458f116afc7a75806574cbcdYuichiro Hanada
128065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    public interface DictionaryBufferFactory {
129065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        public DictBuffer getDictionaryBuffer(final File file)
130065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                throws FileNotFoundException, IOException;
131065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    }
132065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
133065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    /**
134065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * Creates DictionaryBuffer using a ByteBuffer
135065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     *
136065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * This class uses less memory than DictionaryBufferFromByteArrayFactory,
137065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * but doesn't perform as fast.
138065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * When operating on a big dictionary, this class is preferred.
139065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     */
140065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    public static final class DictionaryBufferFromReadOnlyByteBufferFactory
141065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            implements DictionaryBufferFactory {
142065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        @Override
143065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        public DictBuffer getDictionaryBuffer(final File file)
144065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                throws FileNotFoundException, IOException {
145065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            FileInputStream inStream = null;
146065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            ByteBuffer buffer = null;
147065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            try {
148065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                inStream = new FileInputStream(file);
149065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                buffer = inStream.getChannel().map(FileChannel.MapMode.READ_ONLY,
150065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                        0, file.length());
151065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            } finally {
152065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                if (inStream != null) {
153065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                    inStream.close();
154065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                }
155065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            }
156065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            if (buffer != null) {
157065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer);
158065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            }
159065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            return null;
160065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        }
161065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    }
162065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
163065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    /**
164065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * Creates DictionaryBuffer using a byte array
165065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     *
166065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * This class performs faster than other classes, but consumes more memory.
167065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * When operating on a small dictionary, this class is preferred.
168065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     */
169065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    public static final class DictionaryBufferFromByteArrayFactory
170065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            implements DictionaryBufferFactory {
171065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        @Override
172065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        public DictBuffer getDictionaryBuffer(final File file)
173065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                throws FileNotFoundException, IOException {
174065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            FileInputStream inStream = null;
175065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            try {
176065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                inStream = new FileInputStream(file);
177065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                final byte[] array = new byte[(int) file.length()];
178065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                inStream.read(array);
179065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                return new ByteArrayDictBuffer(array);
180065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            } finally {
181065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                if (inStream != null) {
182065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                    inStream.close();
183065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                }
184065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            }
185065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        }
186065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    }
187065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada
188065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    /**
189065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * Creates DictionaryBuffer using a writable ByteBuffer and a RandomAccessFile.
190065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     *
191065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * This class doesn't perform as fast as other classes,
192065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * but this class is the only option available for destructive operations (insert or delete)
193065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     * on a dictionary.
194065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada     */
195065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    @UsedForTesting
196065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    public static final class DictionaryBufferFromWritableByteBufferFactory
197065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            implements DictionaryBufferFactory {
198065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        @Override
199065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        public DictBuffer getDictionaryBuffer(final File file)
200065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                throws FileNotFoundException, IOException {
201065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            RandomAccessFile raFile = null;
202065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            ByteBuffer buffer = null;
203065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            try {
204065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                raFile = new RandomAccessFile(file, "rw");
205065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                buffer = raFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, file.length());
206065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            } finally {
207065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                if (raFile != null) {
208065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                    raFile.close();
209065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                }
210065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            }
211065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            if (buffer != null) {
212065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada                return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer);
213065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            }
214065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada            return null;
215065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada        }
216065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada    }
21714087ba52c6b5b7acd25ee4a1ef1663ceb72bbf4Yuichiro Hanada
2182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    /**
2192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa     * @return whether this decoder has a valid binary dictionary that it can decode.
2202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa     */
2212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    public boolean hasValidRawBinaryDictionary();
222065aad9501ae446aee5d73450c01dc21b8f3242aYuichiro Hanada}
223