]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - src/com/hughes/android/dictionary/engine/HtmlEntry.java
Some lint fixes.
[Dictionary.git] / src / com / hughes / android / dictionary / engine / HtmlEntry.java
index 573a96992d88e2f53e33c44206c9486e927d3f2a..f279a3d8f8fa14071dd89bd2ba29d86c8ba15a23 100644 (file)
@@ -3,24 +3,26 @@ package com.hughes.android.dictionary.engine;
 
 import com.hughes.util.StringUtil;
 import com.hughes.util.raf.RAFListSerializer;
-import com.hughes.util.raf.RAFSerializable;
+import com.hughes.util.raf.RAFListSerializerSkippable;
 import com.ibm.icu.text.Transliterator;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.io.RandomAccessFile;
+import java.io.UnsupportedEncodingException;
 import java.lang.ref.SoftReference;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.regex.Pattern;
 
-public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntry>,
-        Comparable<HtmlEntry> {
+public class HtmlEntry extends AbstractEntry implements Comparable<HtmlEntry> {
 
     // Title is not HTML escaped.
     public final String title;
-    public final LazyHtmlLoader lazyHtmlLoader;
+    private final LazyHtmlLoader lazyHtmlLoader;
+    @SuppressWarnings("WeakerAccess")
     public String html;
 
     public HtmlEntry(final EntrySource entrySource, String title) {
@@ -29,23 +31,30 @@ public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntr
         lazyHtmlLoader = null;
     }
 
-    public HtmlEntry(Dictionary dictionary, DataInput raf, final int index)
-            throws IOException {
+    public HtmlEntry(Dictionary dictionary, FileChannel ch, DataInput raf, final int index)
+    throws IOException {
         super(dictionary, raf, index);
         title = raf.readUTF();
-        lazyHtmlLoader = new LazyHtmlLoader(raf, dictionary.dictFileVersion);
+        lazyHtmlLoader = new LazyHtmlLoader(ch, raf, dictionary.htmlData, index);
         html = null;
     }
 
-    @Override
-    public void write(DataOutput raf) throws IOException {
+    private void writeBase(DataOutput raf) throws IOException {
         super.write(raf);
         raf.writeUTF(title);
+    }
+
+    private void writeData(DataOutput raf) throws IOException {
+        final byte[] bytes = getHtml().getBytes(StandardCharsets.UTF_8);
+        StringUtil.writeVarInt(raf, bytes.length);
+        raf.write(bytes);
+    }
 
-        final byte[] bytes = getHtml().getBytes("UTF-8");
-        final byte[] zipBytes = StringUtil.zipBytes(bytes);
-        StringUtil.writeVarInt(raf, zipBytes.length);
-        raf.write(zipBytes);
+    private static byte[] readData(DataInput raf) throws IOException {
+        int len = StringUtil.readVarInt(raf);
+        final byte[] bytes = new byte[Math.min(len, 20 * 1024 * 1024)];
+        raf.readFully(bytes);
+        return bytes;
     }
 
     String getHtml() {
@@ -64,31 +73,72 @@ public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntr
         return new Row(this.index, rowIndex, dictionaryIndex);
     }
 
-    static final class Serializer implements RAFListSerializer<HtmlEntry> {
+    static final class Serializer implements RAFListSerializerSkippable<HtmlEntry> {
 
         final Dictionary dictionary;
+        final FileChannel ch;
 
-        Serializer(Dictionary dictionary) {
+        Serializer(Dictionary dictionary, FileChannel ch) {
             this.dictionary = dictionary;
+            this.ch = ch;
         }
 
         @Override
         public HtmlEntry read(DataInput raf, final int index) throws IOException {
-            return new HtmlEntry(dictionary, raf, index);
+            return new HtmlEntry(dictionary, ch, raf, index);
+        }
+
+        @Override
+        public void skip(DataInput raf, final int index) throws IOException {
+            if (dictionary.dictFileVersion >= 7)
+            {
+                StringUtil.readVarInt(raf);
+            }
+            else
+            {
+                raf.skipBytes(2);
+            }
+            int l = raf.readUnsignedShort();
+            raf.skipBytes(l);
+       }
+
+        @Override
+        public void write(DataOutput raf, HtmlEntry t) throws IOException {
+            t.writeBase(raf);
+        }
+    }
+
+    static final class DataSerializer implements RAFListSerializer<HtmlEntry> {
+        @Override
+        public HtmlEntry read(DataInput raf, final int index) {
+            assert false;
+            return null;
         }
 
         @Override
         public void write(DataOutput raf, HtmlEntry t) throws IOException {
-            t.write(raf);
+            t.writeData(raf);
         }
     }
 
-    public String getRawText(final boolean compact) {
+    static final class DataDeserializer implements RAFListSerializer<byte[]> {
+        @Override
+        public byte[] read(DataInput raf, final int index) throws IOException {
+            return HtmlEntry.readData(raf);
+        }
+
+        @Override
+        public void write(DataOutput raf, byte[] t) {
+            assert false;
+        }
+    }
+
+    private String getRawText(final boolean compact) {
         return title + ":\n" + getHtml();
     }
 
     @Override
-    public int compareTo(HtmlEntry another) {
+    public int compareTo(/*@NonNull*/ HtmlEntry another) {
         if (title.compareTo(another.title) != 0) {
             return title.compareTo(another.title);
         }
@@ -104,15 +154,13 @@ public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntr
 
     public static class Row extends RowBase {
 
-        boolean isExpanded = false;
-
         Row(final DataInput raf, final int thisRowIndex,
-                final Index index, int extra) throws IOException {
+            final Index index, int extra) throws IOException {
             super(raf, thisRowIndex, index, extra);
         }
 
         Row(final int referenceIndex, final int thisRowIndex,
-                final Index index) {
+            final Index index) {
             super(referenceIndex, thisRowIndex, index);
         }
 
@@ -139,8 +187,8 @@ public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntr
 
         @Override
         public RowMatchType matches(final List<String> searchTokens,
-                final Pattern orderedMatchPattern, final Transliterator normalizer,
-                final boolean swapPairEntries) {
+                                    final Pattern orderedMatchPattern, final Transliterator normalizer,
+                                    final boolean swapPairEntries) {
             final String text = normalizer.transform(getRawText(false));
             if (orderedMatchPattern.matcher(text).find()) {
                 return RowMatchType.ORDERED_MATCH;
@@ -160,12 +208,13 @@ public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntr
         for (final HtmlEntry htmlEntry : htmlEntries) {
             final String titleEscaped = StringUtil.escapeUnicodeToPureHtml(htmlEntry.title);
             result.append(String.format("<h1><a href=\"%s\">%s</a></h1>\n<p>%s\n",
-                    formatQuickdicUrl(indexShortName, htmlEntry.title), titleEscaped,
-                    htmlEntry.getHtml()));
+                                        formatQuickdicUrl(indexShortName, htmlEntry.title), titleEscaped,
+                                        htmlEntry.getHtml()));
         }
         return result.toString();
     }
 
+    @SuppressWarnings("WeakerAccess")
     public static String formatQuickdicUrl(final String indexShortName, final String text) {
         assert !indexShortName.contains(":");
         assert text.length() > 0;
@@ -178,51 +227,66 @@ public class HtmlEntry extends AbstractEntry implements RAFSerializable<HtmlEntr
 
     // --------------------------------------------------------------------
 
+    @SuppressWarnings("WeakerAccess")
     public static final class LazyHtmlLoader {
-        final RandomAccessFile raf;
+        final DataInput raf;
+        final FileChannel ch;
         final long offset;
         final int numBytes;
         final int numZipBytes;
+        final List<byte[]> data;
+        final int index;
 
         // Not sure this volatile is right, but oh well.
-        volatile SoftReference<String> htmlRef = new SoftReference<String>(null);
-
-        private LazyHtmlLoader(final DataInput inp, int version) throws IOException {
-            raf = (RandomAccessFile)inp;
-            if (version >= 7) {
-                numBytes = -1;
-                numZipBytes = StringUtil.readVarInt(raf);
-            } else {
-                numBytes = raf.readInt();
-                numZipBytes = raf.readInt();
+        volatile SoftReference<String> htmlRef = new SoftReference<>(null);
+
+        private LazyHtmlLoader(FileChannel ch, final DataInput inp, List<byte[]> data, int index) throws IOException {
+            this.data = data;
+            this.index = index;
+            if (data != null) {
+                this.raf = null;
+                this.ch = null;
+                this.offset = 0;
+                this.numBytes = -1;
+                this.numZipBytes = -1;
+                return;
             }
-            offset = raf.getFilePointer();
+            raf = inp;
+            this.ch = ch;
+            numBytes = Math.min(raf.readInt(), 20 * 1024 * 1024);
+            numZipBytes = Math.min(raf.readInt(), 20 * 1024 * 1024);
+            offset = ch.position();
             raf.skipBytes(numZipBytes);
         }
 
-        public String getHtml() {
+        String getHtml() {
             String html = htmlRef.get();
             if (html != null) {
                 return html;
             }
+            if (data != null) {
+                html = new String(data.get(index), StandardCharsets.UTF_8);
+                htmlRef = new SoftReference<>(html);
+                return html;
+            }
             System.out.println("Loading Html: numBytes=" + numBytes + ", numZipBytes="
-                    + numZipBytes);
+                               + numZipBytes);
             final byte[] zipBytes = new byte[numZipBytes];
-            synchronized (raf) {
+            synchronized (ch) {
                 try {
-                    raf.seek(offset);
-                    raf.read(zipBytes);
+                    ch.position(offset);
+                    raf.readFully(zipBytes);
                 } catch (IOException e) {
-                    throw new RuntimeException(e);
+                    throw new RuntimeException("Failed to read HTML data from dictionary", e);
                 }
             }
             try {
                 final byte[] bytes = StringUtil.unzipFully(zipBytes, numBytes);
-                html = new String(bytes, "UTF-8");
+                html = new String(bytes, StandardCharsets.UTF_8);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new RuntimeException("Dictionary HTML data corrupted", e);
             }
-            htmlRef = new SoftReference<String>(html);
+            htmlRef = new SoftReference<>(html);
             return html;
         }
     }