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

Commit f5fd990f authored by Yuichiro Hanada's avatar Yuichiro Hanada Committed by Android Git Automerger
Browse files

am 065aad95: Add DictDecoder.

* commit '065aad95':
  Add DictDecoder.
parents ad531fd2 065aad95
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+127 −0
Original line number Diff line number Diff line
/*
 * 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;
        }
    }
}
+7 −101
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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;
+6 −9
Original line number Diff line number Diff line
@@ -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());