From 124f869faae3a0f75a3825e6a8e195c17f3c626a Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Thu, 16 Oct 2014 23:34:20 +0400 Subject: initial for idea --- .../com/github/junrar/io/RandomAccessStream.java | 203 +++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 org.fox.ttcomics/src/main/java/com/github/junrar/io/RandomAccessStream.java (limited to 'org.fox.ttcomics/src/main/java/com/github/junrar/io/RandomAccessStream.java') diff --git a/org.fox.ttcomics/src/main/java/com/github/junrar/io/RandomAccessStream.java b/org.fox.ttcomics/src/main/java/com/github/junrar/io/RandomAccessStream.java new file mode 100644 index 0000000..49442bf --- /dev/null +++ b/org.fox.ttcomics/src/main/java/com/github/junrar/io/RandomAccessStream.java @@ -0,0 +1,203 @@ +/* + * public domain as of http://rsbweb.nih.gov/ij/disclaimer.html + */ +package com.github.junrar.io; + +import java.io.*; +import java.util.Vector; + +/** + * This is a class that uses a memory cache to allow seeking within an + * InputStream. Based on the JAI MemoryCacheSeekableStream class. Can also be + * constructed from a RandomAccessFile, which uses less memory since the memory + * cache is not required. + */ +@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; + + /** + * Constructs a RandomAccessStream from an InputStream. Seeking backwards is + * supported using a memory cache. + */ + public RandomAccessStream(InputStream inputstream) { + pointer = 0L; + data = new Vector(); + length = 0; + foundEOS = false; + src = inputstream; + } + + /** Constructs a RandomAccessStream from an RandomAccessFile. */ + 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 -- cgit v1.2.3