diff --git a/TODO.1.4.2 b/TODO.1.4.2 index 45c138055..ffb33485e 100644 --- a/TODO.1.4.2 +++ b/TODO.1.4.2 @@ -8,7 +8,7 @@ litres: author photos DONE rtf: images * rtf: underline & strikethrough -* native fb2 plugin: images +* native fb2 plugin: images: Base64InputStream optimization * native fb2 plugin: underline * native fb2 plugin: strikethrough * native fb2 plugin: cover diff --git a/src/org/geometerplus/fbreader/formats/PluginCollection.java b/src/org/geometerplus/fbreader/formats/PluginCollection.java index 970e1c053..face7726f 100644 --- a/src/org/geometerplus/fbreader/formats/PluginCollection.java +++ b/src/org/geometerplus/fbreader/formats/PluginCollection.java @@ -88,9 +88,9 @@ public class PluginCollection { } if (formatType == FormatPlugin.Type.ANY) { - FormatPlugin p = getPlugin(fileType, FormatPlugin.Type.JAVA); + FormatPlugin p = getPlugin(fileType, FormatPlugin.Type.NATIVE); if (p == null) { - p = getPlugin(fileType, FormatPlugin.Type.NATIVE); + p = getPlugin(fileType, FormatPlugin.Type.JAVA); } return p; } else { diff --git a/src/org/geometerplus/zlibrary/core/util/Base64InputStream.java b/src/org/geometerplus/zlibrary/core/util/Base64InputStream.java index d4c21c6d2..a42b4d776 100644 --- a/src/org/geometerplus/zlibrary/core/util/Base64InputStream.java +++ b/src/org/geometerplus/zlibrary/core/util/Base64InputStream.java @@ -25,6 +25,7 @@ import java.io.InputStream; public class Base64InputStream extends InputStream { private final InputStream myBaseStream; + private final int[] myDecodedBuffer = { -1, -1, -1 }; private final byte[] myBuffer = new byte[32768]; private int myBufferOffset; private int myBufferLength; @@ -35,54 +36,43 @@ public class Base64InputStream extends InputStream { @Override public int available() throws IOException { - // TODO: implement - return (myBufferLength + myBaseStream.available()) / 2; + // TODO: real value might be less than returned one + return (myBufferLength + myBaseStream.available()) * 3 / 4; } @Override public long skip(long n) throws IOException { - // TODO: implement - int offset = myBufferOffset; - int available = myBufferLength; - byte first = 0; - for (long skipped = 0; skipped < 2 * n;) { - while (skipped < 2 * n && available-- > 0) { - if (decode(myBuffer[offset++]) != -1) { - ++skipped; - } - } - if (skipped < 2 * n) { - fillBuffer(); - available = myBufferLength; - if (available == -1) { - return skipped / 2; - } - offset = 0; + // TODO: optimize + for (long skipped = 0; skipped < n; ++skipped) { + if (read() == -1) { + return skipped; } } - myBufferLength = available; - myBufferOffset = offset; return n; } @Override public int read() throws IOException { - // TODO: implement - int first = -1; - while (myBufferLength >= 0) { - while (myBufferLength-- > 0) { - final int digit = decode(myBuffer[myBufferOffset++]); - if (digit != -1) { - if (first == -1) { - first = digit; - } else { - return (first << 4) + digit; - } - } - } - fillBuffer(); + int result = myDecodedBuffer[0]; + if (result != -1) { + myDecodedBuffer[0] = -1; + return result; } - return -1; + result = myDecodedBuffer[1]; + if (result != -1) { + myDecodedBuffer[1] = -1; + return result; + } + result = myDecodedBuffer[2]; + if (result != -1) { + myDecodedBuffer[2] = -1; + return result; + } + + fillDecodedBuffer(); + result = myDecodedBuffer[0]; + myDecodedBuffer[0] = -1; + return result; } @Override @@ -92,33 +82,14 @@ public class Base64InputStream extends InputStream { @Override public int read(byte[] b, int off, int len) throws IOException { - // TODO: implement - int offset = myBufferOffset; - int available = myBufferLength; - int first = -1; - for (int ready = 0; ready < len;) { - while (ready < len && available-- > 0) { - final int digit = decode(myBuffer[offset++]); - if (digit != -1) { - if (first == -1) { - first = digit; - } else { - b[off + ready++] = (byte)((first << 4) + digit); - first = -1; - } - } - } - if (ready < len) { - fillBuffer(); - available = myBufferLength; - if (available == -1) { - return ready == 0 ? -1 : ready; - } - offset = 0; + // TODO: optimize + for (int ready = 0; ready < len; ++ready) { + final int num = read(); + if (num == -1) { + return ready > 0 ? ready : -1; } + b[off + ready] = (byte)num; } - myBufferLength = available; - myBufferOffset = offset; return len; } @@ -127,6 +98,40 @@ public class Base64InputStream extends InputStream { myBaseStream.reset(); myBufferOffset = 0; myBufferLength = 0; + myDecodedBuffer[0] = -1; + myDecodedBuffer[1] = -1; + myDecodedBuffer[2] = -1; + } + + private void fillDecodedBuffer() throws IOException { + int first = -1; + int second = -1; + int third = -1; + int fourth = -1; +main: + while (myBufferLength >= 0) { + while (myBufferLength-- > 0) { + final int digit = decode(myBuffer[myBufferOffset++]); + if (digit != -1) { + if (first == -1) { + first = digit; + } else if (second == -1) { + second = digit; + } else if (third == -1) { + third = digit; + } else { + fourth = digit; + break main; + } + } + } + fillBuffer(); + } + if (first != -1) { + myDecodedBuffer[0] = (first << 2) | (second >> 4); + myDecodedBuffer[1] = 0xFF & ((second << 4) | (third >> 2)); + myDecodedBuffer[2] = 0xFF & ((third << 6) | fourth); + } } private void fillBuffer() throws IOException {