summaryrefslogtreecommitdiff
path: root/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/io/RandomAccessStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/io/RandomAccessStream.java')
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/io/RandomAccessStream.java195
1 files changed, 195 insertions, 0 deletions
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/io/RandomAccessStream.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/io/RandomAccessStream.java
new file mode 100644
index 0000000..3f8085f
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/io/RandomAccessStream.java
@@ -0,0 +1,195 @@
+/*
+ * public domain as of http://rsbweb.nih.gov/ij/disclaimer.html
+ */
+package org.fox.ttcomics2.junrar.io;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.util.Vector;
+
+@SuppressWarnings("rawtypes")
+public final class RandomAccessStream extends InputStream {
+
+ private static final int BLOCK_SIZE = 512;
+ private static final int BLOCK_MASK = 511;
+ private static final int BLOCK_SHIFT = 9;
+
+ private InputStream src;
+ private RandomAccessFile ras;
+ private long pointer;
+ private Vector data;
+ private int length;
+ private boolean foundEOS;
+
+ public RandomAccessStream(InputStream inputstream) {
+ pointer = 0L;
+ data = new Vector();
+ length = 0;
+ foundEOS = false;
+ src = inputstream;
+ }
+
+ public RandomAccessStream(RandomAccessFile ras) {
+ this.ras = ras;
+ }
+
+ public int getFilePointer() throws IOException {
+ if (ras != null)
+ return (int) ras.getFilePointer();
+ else
+ return (int) pointer;
+ }
+
+ public long getLongFilePointer() throws IOException {
+ if (ras != null)
+ return ras.getFilePointer();
+ else
+ return pointer;
+ }
+
+ public int read() throws IOException {
+ if (ras != null)
+ return ras.read();
+ long l = pointer + 1L;
+ long l1 = readUntil(l);
+ if (l1 >= l) {
+ byte abyte0[] = (byte[]) data
+ .elementAt((int) (pointer >> BLOCK_SHIFT));
+ return abyte0[(int) (pointer++ & BLOCK_MASK)] & 0xff;
+ } else
+ return -1;
+ }
+
+ public int read(byte[] bytes, int off, int len) throws IOException {
+ if (bytes == null)
+ throw new NullPointerException();
+ if (ras != null)
+ return ras.read(bytes, off, len);
+ if (off < 0 || len < 0 || off + len > bytes.length)
+ throw new IndexOutOfBoundsException();
+ if (len == 0)
+ return 0;
+ long l = readUntil(pointer + len);
+ if (l <= pointer)
+ return -1;
+ else {
+ byte abyte1[] = (byte[]) data
+ .elementAt((int) (pointer >> BLOCK_SHIFT));
+ int k = Math.min(len, BLOCK_SIZE - (int) (pointer & BLOCK_MASK));
+ System.arraycopy(abyte1, (int) (pointer & BLOCK_MASK), bytes, off,
+ k);
+ pointer += k;
+ return k;
+ }
+ }
+
+ public final void readFully(byte[] bytes) throws IOException {
+ readFully(bytes, bytes.length);
+ }
+
+ public final void readFully(byte[] bytes, int len) throws IOException {
+ int read = 0;
+ do {
+ int l = read(bytes, read, len - read);
+ if (l < 0)
+ break;
+ read += l;
+ } while (read < len);
+ }
+
+ @SuppressWarnings("unchecked")
+ private long readUntil(long l) throws IOException {
+ if (l < length)
+ return l;
+ if (foundEOS)
+ return length;
+ int i = (int) (l >> BLOCK_SHIFT);
+ int j = length >> BLOCK_SHIFT;
+ for (int k = j; k <= i; k++) {
+ byte abyte0[] = new byte[BLOCK_SIZE];
+ data.addElement(abyte0);
+ int i1 = BLOCK_SIZE;
+ int j1 = 0;
+ while (i1 > 0) {
+ int k1 = src.read(abyte0, j1, i1);
+ if (k1 == -1) {
+ foundEOS = true;
+ return length;
+ }
+ j1 += k1;
+ i1 -= k1;
+ length += k1;
+ }
+
+ }
+
+ return length;
+ }
+
+ public void seek(long loc) throws IOException {
+ if (ras != null) {
+ ras.seek(loc);
+ return;
+ }
+ if (loc < 0L)
+ pointer = 0L;
+ else
+ pointer = loc;
+ }
+
+ public void seek(int loc) throws IOException {
+ long lloc = ((long) loc) & 0xffffffffL;
+ if (ras != null) {
+ ras.seek(lloc);
+ return;
+ }
+ if (lloc < 0L)
+ pointer = 0L;
+ else
+ pointer = lloc;
+ }
+
+ public final int readInt() throws IOException {
+ int i = read();
+ int j = read();
+ int k = read();
+ int l = read();
+ if ((i | j | k | l) < 0)
+ throw new EOFException();
+ else
+ return (i << 24) + (j << 16) + (k << 8) + l;
+ }
+
+ public final long readLong() throws IOException {
+ return ((long) readInt() << 32) + ((long) readInt() & 0xffffffffL);
+ }
+
+ public final double readDouble() throws IOException {
+ return Double.longBitsToDouble(readLong());
+ }
+
+ public final short readShort() throws IOException {
+ int i = read();
+ int j = read();
+ if ((i | j) < 0)
+ throw new EOFException();
+ else
+ return (short) ((i << 8) + j);
+ }
+
+ public final float readFloat() throws IOException {
+ return Float.intBitsToFloat(readInt());
+ }
+
+ public void close() throws IOException {
+ if (ras != null)
+ ras.close();
+ else {
+ data.removeAllElements();
+ src.close();
+ }
+ }
+
+} \ No newline at end of file