]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - src/com/hughes/android/dictionary/engine/Dictionary.java
Make more robust by catching some exceptions.
[Dictionary.git] / src / com / hughes / android / dictionary / engine / Dictionary.java
index 6539bc9b0f0a52afce3eae135fa681bf527ddc53..03984315afa7ef2921390fbbfcd14c3a91b22b30 100644 (file)
@@ -20,6 +20,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.RandomAccessFile;
+import java.nio.BufferUnderflowException;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.ArrayList;
@@ -31,9 +32,8 @@ import com.hughes.util.CachingList;
 import com.hughes.util.DataInputBuffer;
 import com.hughes.util.raf.RAFList;
 import com.hughes.util.raf.RAFListSerializer;
-import com.hughes.util.raf.RAFSerializable;
 
-public class Dictionary implements RAFSerializable<Dictionary> {
+public class Dictionary {
 
     private static final int CACHE_SIZE = 5000;
 
@@ -50,6 +50,9 @@ public class Dictionary implements RAFSerializable<Dictionary> {
     public final List<DataInputBuffer> htmlData;
     public final List<EntrySource> sources;
     public final List<Index> indices;
+    // Could be a local variable in constructor, but
+    // this way avoids a native-image VM bug.
+    private final MappedByteBuffer wholefile;
 
     /**
      * dictFileVersion 1 adds: <li>links to sources? dictFileVersion 2 adds: <li>
@@ -66,10 +69,11 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         htmlData = null;
         sources = new ArrayList<>();
         indices = new ArrayList<>();
+        wholefile = null;
     }
 
     public Dictionary(final FileChannel ch) throws IOException {
-        MappedByteBuffer wholefile = ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size());
+        wholefile = ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size());
         DataInputBuffer in = new DataInputBuffer(wholefile, 0);
         dictFileVersion = in.readInt();
         if (dictFileVersion < 0 || dictFileVersion > CURRENT_DICT_VERSION) {
@@ -115,7 +119,6 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         }
     }
 
-    @Override
     public void write(DataOutput out) throws IOException {
         RandomAccessFile raf = (RandomAccessFile)out;
         if (dictFileVersion < 7) throw new RuntimeException("write function cannot write formats older than v7!");
@@ -186,6 +189,14 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         return result;
     }
 
+    // get DictionaryInfo for case when Dictionary cannot be opened
+    private static DictionaryInfo getErrorDictionaryInfo(final File file) {
+        final DictionaryInfo dictionaryInfo = new DictionaryInfo();
+        dictionaryInfo.uncompressedFilename = file.getName();
+        dictionaryInfo.uncompressedBytes = file.length();
+        return dictionaryInfo;
+    }
+
     public static DictionaryInfo getDictionaryInfo(final File file) {
         RandomAccessFile raf = null;
         try {
@@ -197,10 +208,15 @@ public class Dictionary implements RAFSerializable<Dictionary> {
             raf.close();
             return dictionaryInfo;
         } catch (IOException e) {
-            final DictionaryInfo dictionaryInfo = new DictionaryInfo();
-            dictionaryInfo.uncompressedFilename = file.getName();
-            dictionaryInfo.uncompressedBytes = file.length();
-            return dictionaryInfo;
+            return getErrorDictionaryInfo(file);
+        } catch (IllegalArgumentException e) {
+            // Most likely due to a Buffer.limit beyond size of file,
+            // do not crash just because of a truncated dictionary file
+            return getErrorDictionaryInfo(file);
+        } catch (BufferUnderflowException e) {
+            // Most likely due to a read beyond the buffer limit set,
+            // do not crash just because of a truncated or corrupt dictionary file
+            return getErrorDictionaryInfo(file);
         } finally {
             if (raf != null) {
                 try {