Skip to content

Commit

Permalink
refactor: simplify IO
Browse files Browse the repository at this point in the history
Renamed IReadOnlyAccess to SeekableReadOnlyByteChannel.
Renamed ReadOnlyAccessFile to SeekableReadOnlyFile.
Renamed InputStreamReadOnlyAccessFile to SeekableReadOnlyInputStream.
The naming refers to the ones in the nio package.
Channel refers to the underlying data provider.
Seekable refers to the fact that those providers will allow to set position arbitrarily.

Changed ReadOnlyAccessFile to not extend RandomAccessFile and use it in a field instead.
This brings a similar behavior as SeekableReadOnlyInputStream.

Removed ReadOnlyAccessInputStream which was a thin wrapper around a IReadOnlyAccess.
ComprDataIO now uses the underlying archive's channel directly.

Removed the ability to create a RandomAccessStream from a RandomAccessFile.

Renamed the impl package to volume.

BREAKING CHANGE: name of classes have changed
  • Loading branch information
gotson committed Jul 24, 2020
1 parent 2711e46 commit b59fc78
Show file tree
Hide file tree
Showing 18 changed files with 99 additions and 301 deletions.
58 changes: 29 additions & 29 deletions src/main/java/com/github/junrar/Archive.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
import com.github.junrar.exception.RarException;
import com.github.junrar.exception.UnsupportedRarEncryptedException;
import com.github.junrar.exception.UnsupportedRarV5Exception;
import com.github.junrar.impl.FileVolumeManager;
import com.github.junrar.impl.InputStreamVolumeManager;
import com.github.junrar.io.IReadOnlyAccess;
import com.github.junrar.io.SeekableReadOnlyByteChannel;
import com.github.junrar.rarfile.AVHeader;
import com.github.junrar.rarfile.BaseBlock;
import com.github.junrar.rarfile.BlockHeader;
Expand All @@ -48,6 +46,8 @@
import com.github.junrar.rarfile.UnrarHeadertype;
import com.github.junrar.unpack.ComprDataIO;
import com.github.junrar.unpack.Unpack;
import com.github.junrar.volume.FileVolumeManager;
import com.github.junrar.volume.InputStreamVolumeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -76,7 +76,7 @@ public class Archive implements Closeable, Iterable<FileHeader> {

private static final int MAX_HEADER_SIZE = 20971520; //20MB

private IReadOnlyAccess rof;
private SeekableReadOnlyByteChannel channel;

private final UnrarCallback unrarCallback;

Expand Down Expand Up @@ -161,11 +161,11 @@ public Archive(final InputStream rarAsStream) throws RarException, IOException {
this(new InputStreamVolumeManager(rarAsStream), null);
}

private void setFile(final IReadOnlyAccess file, final long length) throws IOException, RarException {
private void setChannel(final SeekableReadOnlyByteChannel channel, final long length) throws IOException, RarException {
this.totalPackedSize = 0L;
this.totalPackedRead = 0L;
close();
this.rof = file;
this.channel = channel;
try {
readHeaders(length);
} catch (UnsupportedRarEncryptedException | UnsupportedRarV5Exception | CorruptHeaderException e) {
Expand Down Expand Up @@ -197,8 +197,8 @@ public void bytesReadRead(final int count) {
}
}

public IReadOnlyAccess getRof() {
return this.rof;
public SeekableReadOnlyByteChannel getChannel() {
return this.channel;
}

/**
Expand Down Expand Up @@ -270,15 +270,15 @@ private void readHeaders(final long fileLength) throws IOException, RarException
long newpos = 0;
final byte[] baseBlockBuffer = safelyAllocate(BaseBlock.BaseBlockSize, MAX_HEADER_SIZE);

final long position = this.rof.getPosition();
final long position = this.channel.getPosition();

// Weird, but is trying to read beyond the end of the file
if (position >= fileLength) {
break;
}

// logger.info("\n--------reading header--------");
size = this.rof.readFully(baseBlockBuffer, BaseBlock.BaseBlockSize);
size = this.channel.readFully(baseBlockBuffer, BaseBlock.BaseBlockSize);
if (size == 0) {
break;
}
Expand Down Expand Up @@ -311,7 +311,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
toRead = block.hasEncryptVersion() ? MainHeader.mainHeaderSizeWithEnc
: MainHeader.mainHeaderSize;
final byte[] mainbuff = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(mainbuff, toRead);
this.channel.readFully(mainbuff, toRead);
final MainHeader mainhead = new MainHeader(block, mainbuff);
this.headers.add(mainhead);
this.newMhd = mainhead;
Expand All @@ -324,7 +324,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
case SignHeader:
toRead = SignHeader.signHeaderSize;
final byte[] signBuff = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(signBuff, toRead);
this.channel.readFully(signBuff, toRead);
final SignHeader signHead = new SignHeader(block, signBuff);
this.headers.add(signHead);
// logger.info("HeaderType: SignHeader");
Expand All @@ -334,7 +334,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
case AvHeader:
toRead = AVHeader.avHeaderSize;
final byte[] avBuff = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(avBuff, toRead);
this.channel.readFully(avBuff, toRead);
final AVHeader avHead = new AVHeader(block, avBuff);
this.headers.add(avHead);
// logger.info("headertype: AVHeader");
Expand All @@ -343,7 +343,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
case CommHeader:
toRead = CommentHeader.commentHeaderSize;
final byte[] commBuff = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(commBuff, toRead);
this.channel.readFully(commBuff, toRead);
final CommentHeader commHead = new CommentHeader(block, commBuff);
this.headers.add(commHead);
// logger.info("method: "+commHead.getUnpMethod()+"; 0x"+
Expand All @@ -354,7 +354,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
throw new BadRarArchiveException();
}
processedPositions.add(newpos);
this.rof.setPosition(newpos);
this.channel.setPosition(newpos);

break;
case EndArcHeader:
Expand All @@ -369,7 +369,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
EndArcHeader endArcHead;
if (toRead > 0) {
final byte[] endArchBuff = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(endArchBuff, toRead);
this.channel.readFully(endArchBuff, toRead);
endArcHead = new EndArcHeader(block, endArchBuff);
// logger.info("HeaderType: endarch\ndatacrc:"+
// endArcHead.getArchiveDataCRC());
Expand All @@ -383,7 +383,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException

default:
final byte[] blockHeaderBuffer = safelyAllocate(BlockHeader.blockHeaderSize, MAX_HEADER_SIZE);
this.rof.readFully(blockHeaderBuffer, BlockHeader.blockHeaderSize);
this.channel.readFully(blockHeaderBuffer, BlockHeader.blockHeaderSize);
final BlockHeader blockHead = new BlockHeader(block,
blockHeaderBuffer);

Expand All @@ -394,7 +394,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
- BlockHeader.BaseBlockSize
- BlockHeader.blockHeaderSize;
final byte[] fileHeaderBuffer = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(fileHeaderBuffer, toRead);
this.channel.readFully(fileHeaderBuffer, toRead);

final FileHeader fh = new FileHeader(blockHead, fileHeaderBuffer);
this.headers.add(fh);
Expand All @@ -404,15 +404,15 @@ private void readHeaders(final long fileLength) throws IOException, RarException
throw new BadRarArchiveException();
}
processedPositions.add(newpos);
this.rof.setPosition(newpos);
this.channel.setPosition(newpos);
break;

case ProtectHeader:
toRead = blockHead.getHeaderSize()
- BlockHeader.BaseBlockSize
- BlockHeader.blockHeaderSize;
final byte[] protectHeaderBuffer = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(protectHeaderBuffer, toRead);
this.channel.readFully(protectHeaderBuffer, toRead);
final ProtectHeader ph = new ProtectHeader(blockHead,
protectHeaderBuffer);
newpos = ph.getPositionInFile() + ph.getHeaderSize()
Expand All @@ -421,20 +421,20 @@ private void readHeaders(final long fileLength) throws IOException, RarException
throw new BadRarArchiveException();
}
processedPositions.add(newpos);
this.rof.setPosition(newpos);
this.channel.setPosition(newpos);
break;

case SubHeader: {
final byte[] subHeadbuffer = safelyAllocate(SubBlockHeader.SubBlockHeaderSize, MAX_HEADER_SIZE);
this.rof.readFully(subHeadbuffer,
this.channel.readFully(subHeadbuffer,
SubBlockHeader.SubBlockHeaderSize);
final SubBlockHeader subHead = new SubBlockHeader(blockHead,
subHeadbuffer);
subHead.print();
switch (subHead.getSubType()) {
case MAC_HEAD: {
final byte[] macHeaderbuffer = safelyAllocate(MacInfoHeader.MacInfoHeaderSize, MAX_HEADER_SIZE);
this.rof.readFully(macHeaderbuffer,
this.channel.readFully(macHeaderbuffer,
MacInfoHeader.MacInfoHeaderSize);
final MacInfoHeader macHeader = new MacInfoHeader(subHead,
macHeaderbuffer);
Expand All @@ -448,7 +448,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
break;
case EA_HEAD: {
final byte[] eaHeaderBuffer = safelyAllocate(EAHeader.EAHeaderSize, MAX_HEADER_SIZE);
this.rof.readFully(eaHeaderBuffer, EAHeader.EAHeaderSize);
this.channel.readFully(eaHeaderBuffer, EAHeader.EAHeaderSize);
final EAHeader eaHeader = new EAHeader(subHead,
eaHeaderBuffer);
eaHeader.print();
Expand All @@ -466,7 +466,7 @@ private void readHeaders(final long fileLength) throws IOException, RarException
toRead -= BlockHeader.blockHeaderSize;
toRead -= SubBlockHeader.SubBlockHeaderSize;
final byte[] uoHeaderBuffer = safelyAllocate(toRead, MAX_HEADER_SIZE);
this.rof.readFully(uoHeaderBuffer, toRead);
this.channel.readFully(uoHeaderBuffer, toRead);
final UnixOwnersHeader uoHeader = new UnixOwnersHeader(
subHead, uoHeaderBuffer);
uoHeader.print();
Expand Down Expand Up @@ -610,9 +610,9 @@ public boolean isOldFormat() {
*/
@Override
public void close() throws IOException {
if (this.rof != null) {
this.rof.close();
this.rof = null;
if (this.channel != null) {
this.channel.close();
this.channel = null;
}
if (this.unpack != null) {
this.unpack.cleanUp();
Expand Down Expand Up @@ -647,7 +647,7 @@ public Volume getVolume() {
*/
public void setVolume(final Volume volume) throws IOException, RarException {
this.volume = volume;
setFile(volume.getReadOnlyAccess(), volume.getLength());
setChannel(volume.getChannel(), volume.getLength());
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/github/junrar/Junrar.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.github.junrar;

import com.github.junrar.exception.RarException;
import com.github.junrar.impl.FileVolumeManager;
import com.github.junrar.rarfile.FileHeader;
import com.github.junrar.volume.FileVolumeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down
9 changes: 4 additions & 5 deletions src/main/java/com/github/junrar/Volume.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.github.junrar;

import java.io.IOException;
import com.github.junrar.io.SeekableReadOnlyByteChannel;

import com.github.junrar.io.IReadOnlyAccess;
import java.io.IOException;


/**
Expand All @@ -11,11 +11,10 @@
*/
public interface Volume {
/**
* @return SeekableReadOnlyByteChannel the channel
* @throws IOException .
*
* @return IReadOnlyAccess the access
*/
IReadOnlyAccess getReadOnlyAccess() throws IOException;
SeekableReadOnlyByteChannel getChannel() throws IOException;

/**
* @return the data length
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,22 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
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.
* InputStream. Based on the JAI MemoryCacheSeekableStream class.
*/
@SuppressWarnings("rawtypes")
public final class RandomAccessStream extends InputStream {
public final class RandomAccessInputStream 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 final InputStream src;
private long pointer;
private Vector data;
private final Vector data;
private int length;
private boolean foundEOS;

Expand All @@ -34,46 +30,24 @@ public final class RandomAccessStream extends InputStream {
* supported using a memory cache.
*
* @param inputstream .
*
*/
public RandomAccessStream(InputStream inputstream) {
public RandomAccessInputStream(InputStream inputstream) {
pointer = 0L;
data = new Vector();
length = 0;
foundEOS = false;
src = inputstream;
}

/**
* Constructs a RandomAccessStream from an RandomAccessFile.
*
* @param ras ras
*
*/
public RandomAccessStream(RandomAccessFile ras) {
this.ras = ras;
}

public int getFilePointer() throws IOException {
if (ras != null) {
return (int) ras.getFilePointer();
} else {
return (int) pointer;
}
return (int) pointer;
}

public long getLongFilePointer() throws IOException {
if (ras != null) {
return ras.getFilePointer();
} else {
return pointer;
}
return pointer;
}

public int read() throws IOException {
if (ras != null) {
return ras.read();
}
long l = pointer + 1L;
long l1 = readUntil(l);
if (l1 >= l) {
Expand All @@ -89,9 +63,6 @@ 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();
}
Expand All @@ -106,7 +77,7 @@ public int read(byte[] bytes, int off, int len) throws IOException {
.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);
k);
pointer += k;
return k;
}
Expand Down Expand Up @@ -159,10 +130,6 @@ private long readUntil(long l) throws IOException {
}

public void seek(long loc) throws IOException {
if (ras != null) {
ras.seek(loc);
return;
}
if (loc < 0L) {
pointer = 0L;
} else {
Expand All @@ -172,10 +139,6 @@ public void seek(long loc) throws IOException {

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 {
Expand Down Expand Up @@ -218,12 +181,8 @@ public float readFloat() throws IOException {
}

public void close() throws IOException {
if (ras != null) {
ras.close();
} else {
data.removeAllElements();
src.close();
}
data.removeAllElements();
src.close();
}

}
Loading

0 comments on commit b59fc78

Please sign in to comment.