From 065aad9501ae446aee5d73450c01dc21b8f3242a Mon Sep 17 00:00:00 2001 From: Yuichiro Hanada Date: Tue, 20 Aug 2013 15:52:02 +0900 Subject: [PATCH] Add DictDecoder. Change-Id: Ia1c32f21fe07081ce04d093660e18146b93275a4 --- .../latin/makedict/BinaryDictIOUtils.java | 2 +- .../latin/makedict/DictDecoder.java | 127 ++++++++++++++++++ .../latin/makedict/Ver3DictDecoder.java | 108 +-------------- .../makedict/BinaryDictIOUtilsTests.java | 4 +- .../latin/makedict/Ver3DictDecoderTests.java | 15 +-- 5 files changed, 143 insertions(+), 113 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/makedict/DictDecoder.java diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java index 2539313c2..0fa2cf428 100644 --- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java +++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java @@ -546,7 +546,7 @@ public final class BinaryDictIOUtils { throws FileNotFoundException, IOException, UnsupportedFormatException { final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE]; final Ver3DictDecoder dictDecoder = new Ver3DictDecoder(file); - dictDecoder.openDictBuffer(new Ver3DictDecoder.DictionaryBufferFactory() { + dictDecoder.openDictBuffer(new DictDecoder.DictionaryBufferFactory() { @Override public DictBuffer getDictionaryBuffer(File file) throws FileNotFoundException, IOException { diff --git a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java new file mode 100644 index 000000000..a63d9d5ba --- /dev/null +++ b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makedict; + +import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; +import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; +import com.android.inputmethod.latin.utils.ByteArrayDictBuffer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +/** + * An interface of binary dictionary decoder. + */ +public interface DictDecoder { + public FileHeader readHeader() throws IOException, UnsupportedFormatException; + + public interface DictionaryBufferFactory { + public DictBuffer getDictionaryBuffer(final File file) + throws FileNotFoundException, IOException; + } + + /** + * Creates DictionaryBuffer using a ByteBuffer + * + * This class uses less memory than DictionaryBufferFromByteArrayFactory, + * but doesn't perform as fast. + * When operating on a big dictionary, this class is preferred. + */ + public static final class DictionaryBufferFromReadOnlyByteBufferFactory + implements DictionaryBufferFactory { + @Override + public DictBuffer getDictionaryBuffer(final File file) + throws FileNotFoundException, IOException { + FileInputStream inStream = null; + ByteBuffer buffer = null; + try { + inStream = new FileInputStream(file); + buffer = inStream.getChannel().map(FileChannel.MapMode.READ_ONLY, + 0, file.length()); + } finally { + if (inStream != null) { + inStream.close(); + } + } + if (buffer != null) { + return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer); + } + return null; + } + } + + /** + * Creates DictionaryBuffer using a byte array + * + * This class performs faster than other classes, but consumes more memory. + * When operating on a small dictionary, this class is preferred. + */ + public static final class DictionaryBufferFromByteArrayFactory + implements DictionaryBufferFactory { + @Override + public DictBuffer getDictionaryBuffer(final File file) + throws FileNotFoundException, IOException { + FileInputStream inStream = null; + try { + inStream = new FileInputStream(file); + final byte[] array = new byte[(int) file.length()]; + inStream.read(array); + return new ByteArrayDictBuffer(array); + } finally { + if (inStream != null) { + inStream.close(); + } + } + } + } + + /** + * Creates DictionaryBuffer using a writable ByteBuffer and a RandomAccessFile. + * + * This class doesn't perform as fast as other classes, + * but this class is the only option available for destructive operations (insert or delete) + * on a dictionary. + */ + @UsedForTesting + public static final class DictionaryBufferFromWritableByteBufferFactory + implements DictionaryBufferFactory { + @Override + public DictBuffer getDictionaryBuffer(final File file) + throws FileNotFoundException, IOException { + RandomAccessFile raFile = null; + ByteBuffer buffer = null; + try { + raFile = new RandomAccessFile(file, "rw"); + buffer = raFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, file.length()); + } finally { + if (raFile != null) { + raFile.close(); + } + } + if (buffer != null) { + return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer); + } + return null; + } + } +} diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java index 7c18c8caa..7a9323c2f 100644 --- a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java +++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java @@ -21,21 +21,18 @@ import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncodin import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; -import com.android.inputmethod.latin.utils.ByteArrayDictBuffer; import com.android.inputmethod.latin.utils.JniUtils; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import java.util.HashMap; -// TODO: Make an interface "DictDecoder". +/** + * An implementation of DictDecoder for version 3 binary dictionary. + */ @UsedForTesting -public class Ver3DictDecoder { +public class Ver3DictDecoder implements DictDecoder { static { JniUtils.loadNativeLibrary(); @@ -44,96 +41,6 @@ public class Ver3DictDecoder { // TODO: implement something sensical instead of just a phony method private static native int doNothing(); - public interface DictionaryBufferFactory { - public DictBuffer getDictionaryBuffer(final File file) - throws FileNotFoundException, IOException; - } - - /** - * Creates DictionaryBuffer using a ByteBuffer - * - * This class uses less memory than DictionaryBufferFromByteArrayFactory, - * but doesn't perform as fast. - * When operating on a big dictionary, this class is preferred. - */ - public static final class DictionaryBufferFromReadOnlyByteBufferFactory - implements DictionaryBufferFactory { - @Override - public DictBuffer getDictionaryBuffer(final File file) - throws FileNotFoundException, IOException { - FileInputStream inStream = null; - ByteBuffer buffer = null; - try { - inStream = new FileInputStream(file); - buffer = inStream.getChannel().map(FileChannel.MapMode.READ_ONLY, - 0, file.length()); - } finally { - if (inStream != null) { - inStream.close(); - } - } - if (buffer != null) { - return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer); - } - return null; - } - } - - /** - * Creates DictionaryBuffer using a byte array - * - * This class performs faster than other classes, but consumes more memory. - * When operating on a small dictionary, this class is preferred. - */ - public static final class DictionaryBufferFromByteArrayFactory - implements DictionaryBufferFactory { - @Override - public DictBuffer getDictionaryBuffer(final File file) - throws FileNotFoundException, IOException { - FileInputStream inStream = null; - try { - inStream = new FileInputStream(file); - final byte[] array = new byte[(int) file.length()]; - inStream.read(array); - return new ByteArrayDictBuffer(array); - } finally { - if (inStream != null) { - inStream.close(); - } - } - } - } - - /** - * Creates DictionaryBuffer using a writable ByteBuffer and a RandomAccessFile. - * - * This class doesn't perform as fast as other classes, - * but this class is the only option available for destructive operations (insert or delete) - * on a dictionary. - */ - @UsedForTesting - public static final class DictionaryBufferFromWritableByteBufferFactory - implements DictionaryBufferFactory { - @Override - public DictBuffer getDictionaryBuffer(final File file) - throws FileNotFoundException, IOException { - RandomAccessFile raFile = null; - ByteBuffer buffer = null; - try { - raFile = new RandomAccessFile(file, "rw"); - buffer = raFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, file.length()); - } finally { - if (raFile != null) { - raFile.close(); - } - } - if (buffer != null) { - return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer); - } - return null; - } - } - private final static class HeaderReader { protected static int readVersion(final DictBuffer dictBuffer) throws IOException, UnsupportedFormatException { @@ -171,7 +78,7 @@ public class Ver3DictDecoder { mDictBuffer = null; } - public void openDictBuffer(final DictionaryBufferFactory factory) + public void openDictBuffer(final DictDecoder.DictionaryBufferFactory factory) throws FileNotFoundException, IOException { mDictBuffer = factory.getDictionaryBuffer(mDictionaryBinaryFile); } @@ -181,14 +88,13 @@ public class Ver3DictDecoder { } @UsedForTesting - public DictBuffer openAndGetDictBuffer( - final DictionaryBufferFactory factory) + public DictBuffer openAndGetDictBuffer(final DictDecoder.DictionaryBufferFactory factory) throws FileNotFoundException, IOException { openDictBuffer(factory); return getDictBuffer(); } - // TODO : Define public functions of decoders + @Override public FileHeader readHeader() throws IOException, UnsupportedFormatException { final int version = HeaderReader.readVersion(mDictBuffer); final int optionsFlags = HeaderReader.readOptionFlags(mDictBuffer); diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java index f0ad58fea..74c20a38c 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java @@ -22,12 +22,12 @@ import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; +import com.android.inputmethod.latin.makedict.DictDecoder. + DictionaryBufferFromWritableByteBufferFactory; import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; import com.android.inputmethod.latin.utils.CollectionUtils; -import com.android.inputmethod.latin.makedict.Ver3DictDecoder. - DictionaryBufferFromWritableByteBufferFactory; import java.io.BufferedOutputStream; import java.io.File; diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java index 43c9b919b..20e8b4fda 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java @@ -17,12 +17,11 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; -import com.android.inputmethod.latin.makedict.Ver3DictDecoder.DictionaryBufferFactory; -import com.android.inputmethod.latin.makedict.Ver3DictDecoder. - DictionaryBufferFromByteArrayFactory; -import com.android.inputmethod.latin.makedict.Ver3DictDecoder. +import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory; +import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFromByteArrayFactory; +import com.android.inputmethod.latin.makedict.DictDecoder. DictionaryBufferFromReadOnlyByteBufferFactory; -import com.android.inputmethod.latin.makedict.Ver3DictDecoder. +import com.android.inputmethod.latin.makedict.DictDecoder. DictionaryBufferFromWritableByteBufferFactory; import android.test.AndroidTestCase; @@ -60,8 +59,7 @@ public class Ver3DictDecoderTests extends AndroidTestCase { } @SuppressWarnings("null") - public void runTestOpenBuffer(final String testName, - final DictionaryBufferFactory factory) { + public void runTestOpenBuffer(final String testName, final DictionaryBufferFactory factory) { File testFile = null; try { testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); @@ -104,8 +102,7 @@ public class Ver3DictDecoderTests extends AndroidTestCase { } @SuppressWarnings("null") - public void runTestGetBuffer(final String testName, - final DictionaryBufferFactory factory) { + public void runTestGetBuffer(final String testName, final DictionaryBufferFactory factory) { File testFile = null; try { testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir());