summaryrefslogtreecommitdiff
path: root/src/com/github/junrar/Archive.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/github/junrar/Archive.java')
-rw-r--r--src/com/github/junrar/Archive.java583
1 files changed, 0 insertions, 583 deletions
diff --git a/src/com/github/junrar/Archive.java b/src/com/github/junrar/Archive.java
deleted file mode 100644
index 23ca39b..0000000
--- a/src/com/github/junrar/Archive.java
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
- * Original author: Edmund Wagner
- * Creation date: 22.05.2007
- *
- * Source: $HeadURL$
- * Last changed: $LastChangedDate$
- *
- * the unrar licence applies to all junrar source and binary distributions
- * you are not allowed to use this source to re-create the RAR compression
- * algorithm
- *
- * Here some html entities which can be used for escaping javadoc tags:
- * "&": "&" or "&"
- * "<": "&#060;" or "&lt;"
- * ">": "&#062;" or "&gt;"
- * "@": "&#064;"
- */
-package com.github.junrar;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.github.junrar.exception.RarException;
-import com.github.junrar.exception.RarException.RarExceptionType;
-import com.github.junrar.impl.FileVolumeManager;
-import com.github.junrar.io.IReadOnlyAccess;
-import com.github.junrar.rarfile.AVHeader;
-import com.github.junrar.rarfile.BaseBlock;
-import com.github.junrar.rarfile.BlockHeader;
-import com.github.junrar.rarfile.CommentHeader;
-import com.github.junrar.rarfile.EAHeader;
-import com.github.junrar.rarfile.EndArcHeader;
-import com.github.junrar.rarfile.FileHeader;
-import com.github.junrar.rarfile.MacInfoHeader;
-import com.github.junrar.rarfile.MainHeader;
-import com.github.junrar.rarfile.MarkHeader;
-import com.github.junrar.rarfile.ProtectHeader;
-import com.github.junrar.rarfile.SignHeader;
-import com.github.junrar.rarfile.SubBlockHeader;
-import com.github.junrar.rarfile.UnixOwnersHeader;
-import com.github.junrar.rarfile.UnrarHeadertype;
-import com.github.junrar.unpack.ComprDataIO;
-import com.github.junrar.unpack.Unpack;
-
-
-/**
- * The Main Rar Class; represents a rar Archive
- *
- * @author $LastChangedBy$
- * @version $LastChangedRevision$
- */
-public class Archive implements Closeable {
- private static Logger logger = Logger.getLogger(Archive.class.getName());
-
- private IReadOnlyAccess rof;
-
- private final UnrarCallback unrarCallback;
-
- private final ComprDataIO dataIO;
-
- private final List<BaseBlock> headers = new ArrayList<BaseBlock>();
-
- private MarkHeader markHead = null;
-
- private MainHeader newMhd = null;
-
- private Unpack unpack;
-
- private int currentHeaderIndex;
-
- /** Size of packed data in current file. */
- private long totalPackedSize = 0L;
-
- /** Number of bytes of compressed data read from current file. */
- private long totalPackedRead = 0L;
-
- private VolumeManager volumeManager;
- private Volume volume;
-
- public Archive(VolumeManager volumeManager) throws RarException,
- IOException {
- this(volumeManager, null);
- }
-
- /**
- * create a new archive object using the given {@link VolumeManager}
- *
- * @param volumeManager
- * the the {@link VolumeManager} that will provide volume stream
- * data
- * @throws RarException
- */
- public Archive(VolumeManager volumeManager, UnrarCallback unrarCallback)
- throws RarException, IOException {
- this.volumeManager = volumeManager;
- this.unrarCallback = unrarCallback;
-
- setVolume(this.volumeManager.nextArchive(this, null));
- dataIO = new ComprDataIO(this);
- }
-
- public Archive(File firstVolume) throws RarException, IOException {
- this(new FileVolumeManager(firstVolume), null);
- }
-
- public Archive(File firstVolume, UnrarCallback unrarCallback)
- throws RarException, IOException {
- this(new FileVolumeManager(firstVolume), unrarCallback);
- }
-
- // public File getFile() {
- // return file;
- // }
- //
- // void setFile(File file) throws IOException {
- // this.file = file;
- // setFile(new ReadOnlyAccessFile(file), file.length());
- // }
-
- private void setFile(IReadOnlyAccess file, long length) throws IOException {
- totalPackedSize = 0L;
- totalPackedRead = 0L;
- close();
- rof = file;
- try {
- readHeaders(length);
- } catch (Exception e) {
- logger.log(Level.WARNING,
- "exception in archive constructor maybe file is encrypted "
- + "or currupt", e);
- // ignore exceptions to allow exraction of working files in
- // corrupt archive
- }
- // Calculate size of packed data
- for (BaseBlock block : headers) {
- if (block.getHeaderType() == UnrarHeadertype.FileHeader) {
- totalPackedSize += ((FileHeader) block).getFullPackSize();
- }
- }
- if (unrarCallback != null) {
- unrarCallback.volumeProgressChanged(totalPackedRead,
- totalPackedSize);
- }
- }
-
- public void bytesReadRead(int count) {
- if (count > 0) {
- totalPackedRead += count;
- if (unrarCallback != null) {
- unrarCallback.volumeProgressChanged(totalPackedRead,
- totalPackedSize);
- }
- }
- }
-
- public IReadOnlyAccess getRof() {
- return rof;
- }
-
- /**
- * @return returns all file headers of the archive
- */
- public List<FileHeader> getFileHeaders() {
- List<FileHeader> list = new ArrayList<FileHeader>();
- for (BaseBlock block : headers) {
- if (block.getHeaderType().equals(UnrarHeadertype.FileHeader)) {
- list.add((FileHeader) block);
- }
- }
- return list;
- }
-
- public FileHeader nextFileHeader() {
- int n = headers.size();
- while (currentHeaderIndex < n) {
- BaseBlock block = headers.get(currentHeaderIndex++);
- if (block.getHeaderType() == UnrarHeadertype.FileHeader) {
- return (FileHeader) block;
- }
- }
- return null;
- }
-
- public UnrarCallback getUnrarCallback() {
- return unrarCallback;
- }
-
- /**
- *
- * @return whether the archive is encrypted
- */
- public boolean isEncrypted() {
- if (newMhd != null) {
- return newMhd.isEncrypted();
- } else {
- throw new NullPointerException("mainheader is null");
- }
- }
-
- /**
- * Read the headers of the archive
- *
- * @param fileLength
- * Length of file.
- * @throws RarException
- */
- private void readHeaders(long fileLength) throws IOException, RarException {
- markHead = null;
- newMhd = null;
- headers.clear();
- currentHeaderIndex = 0;
- int toRead = 0;
-
- while (true) {
- int size = 0;
- long newpos = 0;
- byte[] baseBlockBuffer = new byte[BaseBlock.BaseBlockSize];
-
- long position = rof.getPosition();
-
- // Weird, but is trying to read beyond the end of the file
- if (position >= fileLength) {
- break;
- }
-
- // logger.info("\n--------reading header--------");
- size = rof.readFully(baseBlockBuffer, BaseBlock.BaseBlockSize);
- if (size == 0) {
- break;
- }
- BaseBlock block = new BaseBlock(baseBlockBuffer);
-
- block.setPositionInFile(position);
-
- switch (block.getHeaderType()) {
-
- case MarkHeader:
- markHead = new MarkHeader(block);
- if (!markHead.isSignature()) {
- throw new RarException(
- RarException.RarExceptionType.badRarArchive);
- }
- headers.add(markHead);
- // markHead.print();
- break;
-
- case MainHeader:
- toRead = block.hasEncryptVersion() ? MainHeader.mainHeaderSizeWithEnc
- : MainHeader.mainHeaderSize;
- byte[] mainbuff = new byte[toRead];
- rof.readFully(mainbuff, toRead);
- MainHeader mainhead = new MainHeader(block, mainbuff);
- headers.add(mainhead);
- this.newMhd = mainhead;
- if (newMhd.isEncrypted()) {
- throw new RarException(
- RarExceptionType.rarEncryptedException);
- }
- // mainhead.print();
- break;
-
- case SignHeader:
- toRead = SignHeader.signHeaderSize;
- byte[] signBuff = new byte[toRead];
- rof.readFully(signBuff, toRead);
- SignHeader signHead = new SignHeader(block, signBuff);
- headers.add(signHead);
- // logger.info("HeaderType: SignHeader");
-
- break;
-
- case AvHeader:
- toRead = AVHeader.avHeaderSize;
- byte[] avBuff = new byte[toRead];
- rof.readFully(avBuff, toRead);
- AVHeader avHead = new AVHeader(block, avBuff);
- headers.add(avHead);
- // logger.info("headertype: AVHeader");
- break;
-
- case CommHeader:
- toRead = CommentHeader.commentHeaderSize;
- byte[] commBuff = new byte[toRead];
- rof.readFully(commBuff, toRead);
- CommentHeader commHead = new CommentHeader(block, commBuff);
- headers.add(commHead);
- // logger.info("method: "+commHead.getUnpMethod()+"; 0x"+
- // Integer.toHexString(commHead.getUnpMethod()));
- newpos = commHead.getPositionInFile()
- + commHead.getHeaderSize();
- rof.setPosition(newpos);
-
- break;
- case EndArcHeader:
-
- toRead = 0;
- if (block.hasArchiveDataCRC()) {
- toRead += EndArcHeader.endArcArchiveDataCrcSize;
- }
- if (block.hasVolumeNumber()) {
- toRead += EndArcHeader.endArcVolumeNumberSize;
- }
- EndArcHeader endArcHead;
- if (toRead > 0) {
- byte[] endArchBuff = new byte[toRead];
- rof.readFully(endArchBuff, toRead);
- endArcHead = new EndArcHeader(block, endArchBuff);
- // logger.info("HeaderType: endarch\ndatacrc:"+
- // endArcHead.getArchiveDataCRC());
- } else {
- // logger.info("HeaderType: endarch - no Data");
- endArcHead = new EndArcHeader(block, null);
- }
- headers.add(endArcHead);
- // logger.info("\n--------end header--------");
- return;
-
- default:
- byte[] blockHeaderBuffer = new byte[BlockHeader.blockHeaderSize];
- rof.readFully(blockHeaderBuffer, BlockHeader.blockHeaderSize);
- BlockHeader blockHead = new BlockHeader(block,
- blockHeaderBuffer);
-
- switch (blockHead.getHeaderType()) {
- case NewSubHeader:
- case FileHeader:
- toRead = blockHead.getHeaderSize()
- - BlockHeader.BaseBlockSize
- - BlockHeader.blockHeaderSize;
- byte[] fileHeaderBuffer = new byte[toRead];
- rof.readFully(fileHeaderBuffer, toRead);
-
- FileHeader fh = new FileHeader(blockHead, fileHeaderBuffer);
- headers.add(fh);
- newpos = fh.getPositionInFile() + fh.getHeaderSize()
- + fh.getFullPackSize();
- rof.setPosition(newpos);
- break;
-
- case ProtectHeader:
- toRead = blockHead.getHeaderSize()
- - BlockHeader.BaseBlockSize
- - BlockHeader.blockHeaderSize;
- byte[] protectHeaderBuffer = new byte[toRead];
- rof.readFully(protectHeaderBuffer, toRead);
- ProtectHeader ph = new ProtectHeader(blockHead,
- protectHeaderBuffer);
-
- newpos = ph.getPositionInFile() + ph.getHeaderSize()
- + ph.getDataSize();
- rof.setPosition(newpos);
- break;
-
- case SubHeader: {
- byte[] subHeadbuffer = new byte[SubBlockHeader.SubBlockHeaderSize];
- rof.readFully(subHeadbuffer,
- SubBlockHeader.SubBlockHeaderSize);
- SubBlockHeader subHead = new SubBlockHeader(blockHead,
- subHeadbuffer);
- subHead.print();
- switch (subHead.getSubType()) {
- case MAC_HEAD: {
- byte[] macHeaderbuffer = new byte[MacInfoHeader.MacInfoHeaderSize];
- rof.readFully(macHeaderbuffer,
- MacInfoHeader.MacInfoHeaderSize);
- MacInfoHeader macHeader = new MacInfoHeader(subHead,
- macHeaderbuffer);
- macHeader.print();
- headers.add(macHeader);
-
- break;
- }
- // TODO implement other subheaders
- case BEEA_HEAD:
- break;
- case EA_HEAD: {
- byte[] eaHeaderBuffer = new byte[EAHeader.EAHeaderSize];
- rof.readFully(eaHeaderBuffer, EAHeader.EAHeaderSize);
- EAHeader eaHeader = new EAHeader(subHead,
- eaHeaderBuffer);
- eaHeader.print();
- headers.add(eaHeader);
-
- break;
- }
- case NTACL_HEAD:
- break;
- case STREAM_HEAD:
- break;
- case UO_HEAD:
- toRead = subHead.getHeaderSize();
- toRead -= BaseBlock.BaseBlockSize;
- toRead -= BlockHeader.blockHeaderSize;
- toRead -= SubBlockHeader.SubBlockHeaderSize;
- byte[] uoHeaderBuffer = new byte[toRead];
- rof.readFully(uoHeaderBuffer, toRead);
- UnixOwnersHeader uoHeader = new UnixOwnersHeader(
- subHead, uoHeaderBuffer);
- uoHeader.print();
- headers.add(uoHeader);
- break;
- default:
- break;
- }
-
- break;
- }
- default:
- logger.warning("Unknown Header");
- throw new RarException(RarExceptionType.notRarArchive);
-
- }
- }
- // logger.info("\n--------end header--------");
- }
- }
-
- /**
- * Extract the file specified by the given header and write it to the
- * supplied output stream
- *
- * @param header
- * the header to be extracted
- * @param os
- * the outputstream
- * @throws RarException
- */
- public void extractFile(FileHeader hd, OutputStream os) throws RarException {
- if (!headers.contains(hd)) {
- throw new RarException(RarExceptionType.headerNotInArchive);
- }
- try {
- doExtractFile(hd, os);
- } catch (Exception e) {
- if (e instanceof RarException) {
- throw (RarException) e;
- } else {
- throw new RarException(e);
- }
- }
- }
-
- /**
- * Returns an {@link InputStream} that will allow to read the file and
- * stream it. Please note that this method will create a new Thread and an a
- * pair of Pipe streams.
- *
- * @param header
- * the header to be extracted
- * @throws RarException
- * @throws IOException
- * if any IO error occur
- */
- public InputStream getInputStream(final FileHeader hd) throws RarException,
- IOException {
- final PipedInputStream in = new PipedInputStream(32 * 1024);
- final PipedOutputStream out = new PipedOutputStream(in);
-
- // creates a new thread that will write data to the pipe. Data will be
- // available in another InputStream, connected to the OutputStream.
- new Thread(new Runnable() {
- public void run() {
- try {
- extractFile(hd, out);
- } catch (RarException e) {
- } finally {
- try {
- out.close();
- } catch (IOException e) {
- }
- }
- }
- }).start();
-
- return in;
- }
-
- private void doExtractFile(FileHeader hd, OutputStream os)
- throws RarException, IOException {
- dataIO.init(os);
- dataIO.init(hd);
- dataIO.setUnpFileCRC(this.isOldFormat() ? 0 : 0xffFFffFF);
- if (unpack == null) {
- unpack = new Unpack(dataIO);
- }
- if (!hd.isSolid()) {
- unpack.init(null);
- }
- unpack.setDestSize(hd.getFullUnpackSize());
- try {
- unpack.doUnpack(hd.getUnpVersion(), hd.isSolid());
- // Verify file CRC
- hd = dataIO.getSubHeader();
- long actualCRC = hd.isSplitAfter() ? ~dataIO.getPackedCRC()
- : ~dataIO.getUnpFileCRC();
- int expectedCRC = hd.getFileCRC();
- if (actualCRC != expectedCRC) {
- throw new RarException(RarExceptionType.crcError);
- }
- // if (!hd.isSplitAfter()) {
- // // Verify file CRC
- // if(~dataIO.getUnpFileCRC() != hd.getFileCRC()){
- // throw new RarException(RarExceptionType.crcError);
- // }
- // }
- } catch (Exception e) {
- unpack.cleanUp();
- if (e instanceof RarException) {
- // throw new RarException((RarException)e);
- throw (RarException) e;
- } else {
- throw new RarException(e);
- }
- }
- }
-
- /**
- * @return returns the main header of this archive
- */
- public MainHeader getMainHeader() {
- return newMhd;
- }
-
- /**
- * @return whether the archive is old format
- */
- public boolean isOldFormat() {
- return markHead.isOldFormat();
- }
-
- /** Close the underlying compressed file. */
- public void close() throws IOException {
- if (rof != null) {
- rof.close();
- rof = null;
- }
- if (unpack != null) {
- unpack.cleanUp();
- }
- }
-
- /**
- * @return the volumeManager
- */
- public VolumeManager getVolumeManager() {
- return volumeManager;
- }
-
- /**
- * @param volumeManager
- * the volumeManager to set
- */
- public void setVolumeManager(VolumeManager volumeManager) {
- this.volumeManager = volumeManager;
- }
-
- /**
- * @return the volume
- */
- public Volume getVolume() {
- return volume;
- }
-
- /**
- * @param volume
- * the volume to set
- * @throws IOException
- */
- public void setVolume(Volume volume) throws IOException {
- this.volume = volume;
- setFile(volume.getReadOnlyAccess(), volume.getLength());
- }
-}