mirror of
https://github.com/mupen64plus-ae/mupen64plus-ae-deps.git
synced 2024-11-26 23:00:22 +00:00
build: Added Android inorichi jnurar-android library
https://github.com/inorichi/junrar-android
This commit is contained in:
parent
0053012426
commit
aec18f21e5
19
junrar/build.gradle
Normal file
19
junrar/build.gradle
Normal file
@ -0,0 +1,19 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion "27.0.2"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 27
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
}
|
||||
}
|
99
junrar/junrar.iml
Normal file
99
junrar/junrar.iml
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":junrar" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":junrar" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="release" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleRelease" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileReleaseSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateReleaseSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
<option name="PROJECT_TYPE" value="1" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/release" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/release" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/release" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/release" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/release" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/attr" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-manifest" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/typedefs.txt" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 27 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
4
junrar/src/main/AndroidManifest.xml
Normal file
4
junrar/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.junrar">
|
||||
|
||||
</manifest>
|
592
junrar/src/main/java/junrar/Archive.java
Normal file
592
junrar/src/main/java/junrar/Archive.java
Normal file
@ -0,0 +1,592 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package 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 junrar.exception.RarException;
|
||||
import junrar.exception.RarException.RarExceptionType;
|
||||
import junrar.impl.FileVolumeManager;
|
||||
import junrar.io.IReadOnlyAccess;
|
||||
import junrar.rarfile.AVHeader;
|
||||
import junrar.rarfile.BaseBlock;
|
||||
import junrar.rarfile.BlockHeader;
|
||||
import junrar.rarfile.CommentHeader;
|
||||
import junrar.rarfile.EAHeader;
|
||||
import junrar.rarfile.EndArcHeader;
|
||||
import junrar.rarfile.FileHeader;
|
||||
import junrar.rarfile.MacInfoHeader;
|
||||
import junrar.rarfile.MainHeader;
|
||||
import junrar.rarfile.MarkHeader;
|
||||
import junrar.rarfile.ProtectHeader;
|
||||
import junrar.rarfile.SignHeader;
|
||||
import junrar.rarfile.SubBlockHeader;
|
||||
import junrar.rarfile.UnixOwnersHeader;
|
||||
import junrar.rarfile.UnrarHeadertype;
|
||||
import junrar.unpack.ComprDataIO;
|
||||
import 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the headers in the archive.
|
||||
*
|
||||
* @return returns the headers.
|
||||
*/
|
||||
public List<BaseBlock> getHeaders() {
|
||||
return new ArrayList<BaseBlock>(headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 hd
|
||||
* 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 hd
|
||||
* 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());
|
||||
}
|
||||
}
|
21
junrar/src/main/java/junrar/UnrarCallback.java
Normal file
21
junrar/src/main/java/junrar/UnrarCallback.java
Normal file
@ -0,0 +1,21 @@
|
||||
package junrar;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author alban
|
||||
*/
|
||||
public interface UnrarCallback {
|
||||
|
||||
/**
|
||||
* Return <tt>true</tt> if the next volume is ready to be processed,
|
||||
* <tt>false</tt> otherwise.
|
||||
*/
|
||||
boolean isNextVolumeReady(Volume nextVolume);
|
||||
|
||||
/**
|
||||
* This method is invoked each time the progress of the current
|
||||
* volume changes.
|
||||
*/
|
||||
void volumeProgressChanged(long current, long total);
|
||||
}
|
44
junrar/src/main/java/junrar/Volume.java
Normal file
44
junrar/src/main/java/junrar/Volume.java
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of seedbox <github.com/seedbox>.
|
||||
*
|
||||
* seedbox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* seedbox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with seedbox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package junrar;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import junrar.io.IReadOnlyAccess;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface Volume {
|
||||
/**
|
||||
* @return the access
|
||||
* @throws IOException
|
||||
*/
|
||||
IReadOnlyAccess getReadOnlyAccess() throws IOException;
|
||||
|
||||
/**
|
||||
* @return the data length
|
||||
*/
|
||||
long getLength();
|
||||
|
||||
/**
|
||||
* @return the archive this volume belongs to
|
||||
*/
|
||||
Archive getArchive();
|
||||
}
|
28
junrar/src/main/java/junrar/VolumeManager.java
Normal file
28
junrar/src/main/java/junrar/VolumeManager.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of seedbox <github.com/seedbox>.
|
||||
*
|
||||
* seedbox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* seedbox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with seedbox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package junrar;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface VolumeManager {
|
||||
public Volume nextArchive(Archive archive, Volume lastVolume)
|
||||
throws IOException;
|
||||
}
|
145
junrar/src/main/java/junrar/crc/RarCRC.java
Normal file
145
junrar/src/main/java/junrar/crc/RarCRC.java
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 29.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.crc;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class RarCRC {
|
||||
|
||||
private final static int crcTab[];
|
||||
static {
|
||||
crcTab = new int[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int c = i;
|
||||
for (int j = 0; j < 8; j++){
|
||||
if ((c & 1) !=0) {
|
||||
c >>>= 1;
|
||||
c ^= 0xEDB88320;
|
||||
}
|
||||
else{
|
||||
c >>>= 1;
|
||||
}
|
||||
}
|
||||
crcTab[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
private RarCRC() {
|
||||
}
|
||||
|
||||
public static int checkCrc(int startCrc, byte[] data, int offset,
|
||||
int count) {
|
||||
int size = Math.min(data.length-offset,count);
|
||||
// #if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) &&
|
||||
// defined(ALLOW_NOT_ALIGNED_INT)
|
||||
/*
|
||||
for (int i = 0; (0 < size) && i < data.length - 8
|
||||
&& ((data[i + 8] & 7) != 0); i++) {
|
||||
startCrc = crcTab[(short) (startCrc ^ data[i]) & 0x00FF] ^ (startCrc >>> 8);
|
||||
size--;
|
||||
}
|
||||
|
||||
for (int i = 0; size >= 8; i += 8) {
|
||||
startCrc ^= data[i + 0] << 24;
|
||||
startCrc ^= data[i + 1] << 16;
|
||||
startCrc ^= data[i + 2] << 8;
|
||||
startCrc ^= data[i + 3];
|
||||
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
|
||||
startCrc ^= data[i + 4] << 24;
|
||||
startCrc ^= data[i + 5] << 16;
|
||||
startCrc ^= data[i + 6] << 8;
|
||||
startCrc ^= data[i + 7];
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);
|
||||
size -= 8;
|
||||
}*/
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
/*
|
||||
// (byte)(StartCRC^Data[I])
|
||||
int pos = 0; // pos=0x00000000
|
||||
pos |= startCrc; // pos=ffffffff
|
||||
|
||||
pos ^= data[i]; // data[0]=0x73=115dec --> pos=140
|
||||
System.out.println(Integer.toHexString(pos));
|
||||
|
||||
// Only last 8 bit because CRCtab has length 256
|
||||
pos = pos & 0x000000FF;
|
||||
System.out.println("pos:"+pos);
|
||||
//startCrc >>>= 8;
|
||||
|
||||
|
||||
//StartCRC>>8
|
||||
int temp =0;
|
||||
temp|=startCrc;
|
||||
temp >>>= 8;
|
||||
System.out.println("temp:"+Integer.toHexString(temp));
|
||||
|
||||
|
||||
startCrc = (crcTab[pos]^temp);
|
||||
System.out.println("--"+Integer.toHexString(startCrc));*/
|
||||
|
||||
startCrc=(crcTab[((int)((int)startCrc ^
|
||||
(int)data[offset+i]))&0xff]^(startCrc>>>8));
|
||||
|
||||
//System.out.println(Integer.toHexString(startCrc));
|
||||
|
||||
// Original code:
|
||||
//StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);
|
||||
}
|
||||
return (startCrc);
|
||||
}
|
||||
|
||||
public static short checkOldCrc(short startCrc, byte[] data, int count) {
|
||||
int n = Math.min(data.length, count);
|
||||
for (int i = 0; i < n; i++) {
|
||||
startCrc = (short) ((short) (startCrc + (short) (data[i]&0x00ff)) & -1);
|
||||
startCrc = (short) (((startCrc << 1) | (startCrc >>> 15)) & -1);
|
||||
}
|
||||
return (startCrc);
|
||||
}
|
||||
|
||||
// public static void main(String[] args)
|
||||
// {
|
||||
// RarCRC rc = new RarCRC();
|
||||
// //byte[] data = { 0x72, 0x21, 0x1A, 0x07, 0x00};
|
||||
//
|
||||
// byte[] data = {0x73 ,0x00 ,0x00 ,0x0D ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00};
|
||||
//
|
||||
// int crc = 0x90CF;
|
||||
//
|
||||
//
|
||||
// int result = rc.checkCrc(0xFFFFffff, data,0,data.length);
|
||||
// System.out.println("3: "+Integer.toHexString(~result&0xffff));
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
27
junrar/src/main/java/junrar/crypt/Rijndael.java
Normal file
27
junrar/src/main/java/junrar/crypt/Rijndael.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.05.2007
|
||||
*
|
||||
* 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
|
||||
* Source: $HeadURL$
|
||||
* Last changed: $LastChangedDate$
|
||||
*
|
||||
* Here some html entities which can be used for escaping javadoc tags:
|
||||
* "&": "&" or "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.crypt;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class Rijndael {
|
||||
|
||||
}
|
73
junrar/src/main/java/junrar/exception/RarException.java
Normal file
73
junrar/src/main/java/junrar/exception/RarException.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 30.07.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.exception;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class RarException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private RarExceptionType type;
|
||||
|
||||
public RarException(Exception e){
|
||||
super(RarExceptionType.unkownError.name(),e);
|
||||
this.type = RarExceptionType.unkownError;
|
||||
}
|
||||
|
||||
public RarException(RarException e)
|
||||
{
|
||||
|
||||
super(e.getMessage(),e);
|
||||
this.type = e.getType();
|
||||
}
|
||||
|
||||
public RarException(RarExceptionType type){
|
||||
super(type.name());
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public enum RarExceptionType{
|
||||
notImplementedYet,
|
||||
crcError,
|
||||
notRarArchive,
|
||||
badRarArchive,
|
||||
unkownError,
|
||||
headerNotInArchive,
|
||||
wrongHeaderType,
|
||||
ioError,
|
||||
rarEncryptedException ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public RarExceptionType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(RarExceptionType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
}
|
185
junrar/src/main/java/junrar/extract/RarExtractor.java
Normal file
185
junrar/src/main/java/junrar/extract/RarExtractor.java
Normal file
@ -0,0 +1,185 @@
|
||||
package junrar.extract;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import junrar.Archive;
|
||||
import junrar.exception.RarException;
|
||||
import junrar.rarfile.FileHeader;
|
||||
|
||||
/**
|
||||
* extract an archive to the given location
|
||||
*
|
||||
* @author edmund wagner
|
||||
*
|
||||
*/
|
||||
public class RarExtractor {
|
||||
|
||||
private static String TAG = RarExtractor.class.getName();
|
||||
|
||||
public void extractArchive(String archive, String destination) throws RarException, IOException {
|
||||
extractArchive(new File(archive), new File(destination));
|
||||
}
|
||||
|
||||
public void extractArchive(File archive, File destination) throws RarException, IOException {
|
||||
Archive arch = null;
|
||||
try {
|
||||
arch = new Archive(archive);
|
||||
}
|
||||
catch (RarException re) {
|
||||
Log.e(TAG, re.getMessage(), re);
|
||||
throw re;
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
Log.e(TAG, ioe.getMessage(), ioe);
|
||||
throw ioe;
|
||||
}
|
||||
if (arch != null) {
|
||||
if (arch.isEncrypted()) {
|
||||
Log.e(TAG, "Unsupported encrypted archive " + archive.getName());
|
||||
try {
|
||||
arch.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
Log.e(TAG, e.getMessage(), e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Log.e(TAG, "Extracting from " + archive.getName());
|
||||
}
|
||||
try {
|
||||
FileHeader fh = null;
|
||||
while (true) {
|
||||
fh = arch.nextFileHeader();
|
||||
if (fh == null) {
|
||||
break;
|
||||
}
|
||||
String fileNameString = fh.getFileNameString();
|
||||
if (fh.isEncrypted()) {
|
||||
Log.e(TAG, "Unsupported encrypted file " + fileNameString);
|
||||
continue;
|
||||
}
|
||||
OutputStream stream = null;
|
||||
try {
|
||||
if (fh.isDirectory()) {
|
||||
createDirectory(fh, destination);
|
||||
}
|
||||
else {
|
||||
Log.e(TAG, "Extracting " + fileNameString);
|
||||
File f = createFile(fh, destination);
|
||||
stream = new FileOutputStream(f);
|
||||
arch.extractFile(fh, stream);
|
||||
}
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
Log.e(TAG, "Error extracting " + fileNameString, ioe);
|
||||
throw ioe;
|
||||
}
|
||||
catch (RarException re) {
|
||||
Log.e(TAG, "Error extracting " + fileNameString, re);
|
||||
throw re;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (stream != null) {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Log.e(TAG, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
arch.close();
|
||||
Log.i(TAG, "Extraction completed.");
|
||||
}
|
||||
catch (Exception e) {
|
||||
Log.w(TAG, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File createFile(FileHeader fh, File destination) {
|
||||
File f = null;
|
||||
String name = null;
|
||||
if (fh.isFileHeader() && fh.isUnicode()) {
|
||||
name = fh.getFileNameW();
|
||||
}
|
||||
else {
|
||||
name = fh.getFileNameString();
|
||||
}
|
||||
f = new File(destination, name);
|
||||
if (!f.exists()) {
|
||||
try {
|
||||
f = makeFile(destination, name);
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.e(TAG, "Error creating the new file " + f.getName(), e);
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
private static File makeFile(File destination, String name) throws IOException {
|
||||
String[] dirs = name.split("\\\\");
|
||||
if (dirs == null) {
|
||||
return null;
|
||||
}
|
||||
String path = "";
|
||||
int size = dirs.length;
|
||||
if (size == 1) {
|
||||
return new File(destination, name);
|
||||
}
|
||||
else if (size > 1) {
|
||||
for (int i = 0; i < dirs.length - 1; i++) {
|
||||
path = path + File.separator + dirs[i];
|
||||
new File(destination, path).mkdir();
|
||||
}
|
||||
path = path + File.separator + dirs[dirs.length - 1];
|
||||
File f = new File(destination, path);
|
||||
f.createNewFile();
|
||||
return f;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void createDirectory(FileHeader fh, File destination) {
|
||||
File f = null;
|
||||
if (fh.isDirectory() && fh.isUnicode()) {
|
||||
f = new File(destination, fh.getFileNameW());
|
||||
if (!f.exists()) {
|
||||
makeDirectory(destination, fh.getFileNameW());
|
||||
}
|
||||
}
|
||||
else if (fh.isDirectory() && !fh.isUnicode()) {
|
||||
f = new File(destination, fh.getFileNameString());
|
||||
if (!f.exists()) {
|
||||
makeDirectory(destination, fh.getFileNameString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeDirectory(File destination, String fileName) {
|
||||
String[] dirs = fileName.split("\\\\");
|
||||
if (dirs == null) {
|
||||
return;
|
||||
}
|
||||
String path = "";
|
||||
for (String dir : dirs) {
|
||||
path = path + File.separator + dir;
|
||||
new File(destination, path).mkdir();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
65
junrar/src/main/java/junrar/impl/FileVolume.java
Normal file
65
junrar/src/main/java/junrar/impl/FileVolume.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of seedbox <github.com/seedbox>.
|
||||
*
|
||||
* seedbox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* seedbox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with seedbox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package junrar.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junrar.Archive;
|
||||
import junrar.Volume;
|
||||
import junrar.io.IReadOnlyAccess;
|
||||
import junrar.io.ReadOnlyAccessFile;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class FileVolume implements Volume {
|
||||
private final Archive archive;
|
||||
private final File file;
|
||||
|
||||
/**
|
||||
* @param file
|
||||
*/
|
||||
public FileVolume(Archive archive, File file) {
|
||||
this.archive = archive;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyAccess getReadOnlyAccess() throws IOException {
|
||||
return new ReadOnlyAccessFile(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return file.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Archive getArchive() {
|
||||
return archive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
54
junrar/src/main/java/junrar/impl/FileVolumeManager.java
Normal file
54
junrar/src/main/java/junrar/impl/FileVolumeManager.java
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of seedbox <github.com/seedbox>.
|
||||
*
|
||||
* seedbox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* seedbox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with seedbox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package junrar.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junrar.Archive;
|
||||
import junrar.Volume;
|
||||
import junrar.VolumeManager;
|
||||
import junrar.util.VolumeHelper;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class FileVolumeManager implements VolumeManager {
|
||||
private final File firstVolume;
|
||||
|
||||
public FileVolumeManager(File firstVolume) {
|
||||
this.firstVolume = firstVolume;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Volume nextArchive(Archive archive, Volume last)
|
||||
throws IOException {
|
||||
if (last == null)
|
||||
return new FileVolume(archive, firstVolume);
|
||||
|
||||
FileVolume lastFileVolume = (FileVolume) last;
|
||||
boolean oldNumbering = !archive.getMainHeader().isNewNumbering()
|
||||
|| archive.isOldFormat();
|
||||
String nextName = VolumeHelper.nextVolumeName(lastFileVolume.getFile()
|
||||
.getAbsolutePath(), oldNumbering);
|
||||
File nextVolume = new File(nextName);
|
||||
|
||||
return new FileVolume(archive, nextVolume);
|
||||
}
|
||||
}
|
61
junrar/src/main/java/junrar/io/IReadOnlyAccess.java
Normal file
61
junrar/src/main/java/junrar/io/IReadOnlyAccess.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 23.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.io;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public interface IReadOnlyAccess {
|
||||
|
||||
/**
|
||||
* @return the current position in the file
|
||||
*/
|
||||
public long getPosition() throws IOException;
|
||||
|
||||
/**
|
||||
* @param pos the position in the file
|
||||
* @return success ? true : false
|
||||
*/
|
||||
public void setPosition(long pos) throws IOException;
|
||||
|
||||
/** Read a single byte of data. */
|
||||
public int read() throws IOException;
|
||||
|
||||
/**
|
||||
* Read up to <tt>count</tt> bytes to the specified buffer.
|
||||
*/
|
||||
public int read(byte[] buffer, int off, int count) throws IOException;
|
||||
|
||||
/**
|
||||
* Read exactly <tt>count</tt> bytes to the specified buffer.
|
||||
*
|
||||
* @param buffer where to store the read data
|
||||
* @param count how many bytes to read
|
||||
* @return bytes read || -1 if IO problem
|
||||
*/
|
||||
public int readFully(byte[] buffer, int count) throws IOException;
|
||||
|
||||
/** Close this file. */
|
||||
public void close() throws IOException;
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package junrar.io;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* InputStream based implementation of the <code>IReadOnlyAccess</code> interface.
|
||||
*
|
||||
* @see http://rsbweb.nih.gov/ij/
|
||||
* @author martinr
|
||||
*/
|
||||
public class InputStreamReadOnlyAccessFile implements IReadOnlyAccess {
|
||||
private RandomAccessStream is;
|
||||
|
||||
/**
|
||||
* Create new instance.
|
||||
*
|
||||
* @param is The input stream to wrap.
|
||||
*/
|
||||
public InputStreamReadOnlyAccessFile(final InputStream is) {
|
||||
this.is = new RandomAccessStream(new BufferedInputStream(is));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPosition() throws IOException {
|
||||
return is.getLongFilePointer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(long pos) throws IOException {
|
||||
is.seek(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return is.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int off, int count) throws IOException {
|
||||
return is.read(buffer, off, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readFully(byte[] buffer, int count) throws IOException {
|
||||
is.readFully(buffer, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
is.close();
|
||||
}
|
||||
|
||||
}
|
203
junrar/src/main/java/junrar/io/RandomAccessStream.java
Normal file
203
junrar/src/main/java/junrar/io/RandomAccessStream.java
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* public domain as of http://rsbweb.nih.gov/ij/disclaimer.html
|
||||
*/
|
||||
package 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
305
junrar/src/main/java/junrar/io/Raw.java
Normal file
305
junrar/src/main/java/junrar/io/Raw.java
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 18.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.io;
|
||||
|
||||
/**
|
||||
* Read / write numbers to a byte[] regarding the endianness of the array
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class Raw {
|
||||
/**
|
||||
* Read a short value from the byte array at the given position (Big Endian)
|
||||
*
|
||||
* @param array
|
||||
* the array to read from
|
||||
* @param pos
|
||||
* the position
|
||||
* @return the value
|
||||
*/
|
||||
public static final short readShortBigEndian(byte[] array, int pos) {
|
||||
short temp = 0;
|
||||
temp |= array[pos] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 1] & 0xff;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a int value from the byte array at the given position (Big Endian)
|
||||
*
|
||||
* @param array
|
||||
* the array to read from
|
||||
* @param pos
|
||||
* the offset
|
||||
* @return the value
|
||||
*/
|
||||
public static final int readIntBigEndian(byte[] array, int pos) {
|
||||
int temp = 0;
|
||||
temp |= array[pos] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 1] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 2] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 3] & 0xff;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a long value from the byte array at the given position (Big Endian)
|
||||
*
|
||||
* @param array
|
||||
* the array to read from
|
||||
* @param pos
|
||||
* the offset
|
||||
* @return the value
|
||||
*/
|
||||
public static final long readLongBigEndian(byte[] array, int pos) {
|
||||
int temp = 0;
|
||||
temp |= array[pos] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 1] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 2] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 3] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 4] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 5] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 6] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 7] & 0xff;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a short value from the byte array at the given position (little
|
||||
* Endian)
|
||||
*
|
||||
* @param array
|
||||
* the array to read from
|
||||
* @param pos
|
||||
* the offset
|
||||
* @return the value
|
||||
*/
|
||||
public static final short readShortLittleEndian(byte[] array, int pos) {
|
||||
short result = 0;
|
||||
result += array[pos + 1] & 0xff;
|
||||
result <<= 8;
|
||||
result += array[pos] & 0xff;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an int value from the byte array at the given position (little
|
||||
* Endian)
|
||||
*
|
||||
* @param array
|
||||
* the array to read from
|
||||
* @param pos
|
||||
* the offset
|
||||
* @return the value
|
||||
*/
|
||||
public static final int readIntLittleEndian(byte[] array, int pos) {
|
||||
return ((array[pos + 3] & 0xff) << 24)
|
||||
| ((array[pos + 2] & 0xff) << 16)
|
||||
| ((array[pos + 1] & 0xff) << 8) | ((array[pos] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an long value(unsigned int) from the byte array at the given
|
||||
* position (little Endian)
|
||||
*
|
||||
* @param array
|
||||
* @param pos
|
||||
* @return
|
||||
*/
|
||||
public static final long readIntLittleEndianAsLong(byte[] array, int pos) {
|
||||
return (((long) array[pos + 3] & 0xff) << 24)
|
||||
| (((long) array[pos + 2] & 0xff) << 16)
|
||||
| (((long) array[pos + 1] & 0xff) << 8)
|
||||
| (((long) array[pos] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a long value from the byte array at the given position (little
|
||||
* Endian)
|
||||
*
|
||||
* @param array
|
||||
* the array to read from
|
||||
* @param pos
|
||||
* the offset
|
||||
* @return the value
|
||||
*/
|
||||
public static final long readLongLittleEndian(byte[] array, int pos) {
|
||||
int temp = 0;
|
||||
temp |= array[pos + 7] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 6] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 5] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 4] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 3] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 2] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 1] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos];
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a short value into the byte array at the given position (Big
|
||||
* endian)
|
||||
*
|
||||
* @param array
|
||||
* the array
|
||||
* @param pos
|
||||
* the offset
|
||||
* @param value
|
||||
* the value to write
|
||||
*/
|
||||
public static final void writeShortBigEndian(byte[] array, int pos,
|
||||
short value) {
|
||||
array[pos] = (byte) (value >>> 8);
|
||||
array[pos + 1] = (byte) (value & 0xFF);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an int value into the byte array at the given position (Big endian)
|
||||
*
|
||||
* @param array
|
||||
* the array
|
||||
* @param pos
|
||||
* the offset
|
||||
* @param value
|
||||
* the value to write
|
||||
*/
|
||||
public static final void writeIntBigEndian(byte[] array, int pos, int value) {
|
||||
array[pos] = (byte) ((value >>> 24) & 0xff);
|
||||
array[pos + 1] = (byte) ((value >>> 16) & 0xff);
|
||||
array[pos + 2] = (byte) ((value >>> 8) & 0xff);
|
||||
array[pos + 3] = (byte) ((value) & 0xff);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a long value into the byte array at the given position (Big endian)
|
||||
*
|
||||
* @param array
|
||||
* the array
|
||||
* @param pos
|
||||
* the offset
|
||||
* @param value
|
||||
* the value to write
|
||||
*/
|
||||
public static final void writeLongBigEndian(byte[] array, int pos,
|
||||
long value) {
|
||||
array[pos] = (byte) (value >>> 56);
|
||||
array[pos + 1] = (byte) (value >>> 48);
|
||||
array[pos + 2] = (byte) (value >>> 40);
|
||||
array[pos + 3] = (byte) (value >>> 32);
|
||||
array[pos + 4] = (byte) (value >>> 24);
|
||||
array[pos + 5] = (byte) (value >>> 16);
|
||||
array[pos + 6] = (byte) (value >>> 8);
|
||||
array[pos + 7] = (byte) (value & 0xFF);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a short value into the byte array at the given position (little
|
||||
* endian)
|
||||
*
|
||||
* @param array
|
||||
* the array
|
||||
* @param pos
|
||||
* the offset
|
||||
* @param value
|
||||
* the value to write
|
||||
*/
|
||||
public static final void writeShortLittleEndian(byte[] array, int pos,
|
||||
short value) {
|
||||
array[pos + 1] = (byte) (value >>> 8);
|
||||
array[pos] = (byte) (value & 0xFF);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a short value at the specified position by the specified amount
|
||||
* (little endian).
|
||||
*/
|
||||
public static final void incShortLittleEndian(byte[] array, int pos, int dv) {
|
||||
int c = ((array[pos] & 0xff) + (dv & 0xff)) >>> 8;
|
||||
array[pos] += dv & 0xff;
|
||||
if ((c > 0) || ((dv & 0xff00) != 0)) {
|
||||
array[pos + 1] += ((dv >>> 8) & 0xff) + c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an int value into the byte array at the given position (little
|
||||
* endian)
|
||||
*
|
||||
* @param array
|
||||
* the array
|
||||
* @param pos
|
||||
* the offset
|
||||
* @param value
|
||||
* the value to write
|
||||
*/
|
||||
public static final void writeIntLittleEndian(byte[] array, int pos,
|
||||
int value) {
|
||||
array[pos + 3] = (byte) (value >>> 24);
|
||||
array[pos + 2] = (byte) (value >>> 16);
|
||||
array[pos + 1] = (byte) (value >>> 8);
|
||||
array[pos] = (byte) (value & 0xFF);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a long value into the byte array at the given position (little
|
||||
* endian)
|
||||
*
|
||||
* @param array
|
||||
* the array
|
||||
* @param pos
|
||||
* the offset
|
||||
* @param value
|
||||
* the value to write
|
||||
*/
|
||||
public static final void writeLongLittleEndian(byte[] array, int pos,
|
||||
long value) {
|
||||
array[pos + 7] = (byte) (value >>> 56);
|
||||
array[pos + 6] = (byte) (value >>> 48);
|
||||
array[pos + 5] = (byte) (value >>> 40);
|
||||
array[pos + 4] = (byte) (value >>> 32);
|
||||
array[pos + 3] = (byte) (value >>> 24);
|
||||
array[pos + 2] = (byte) (value >>> 16);
|
||||
array[pos + 1] = (byte) (value >>> 8);
|
||||
array[pos] = (byte) (value & 0xFF);
|
||||
|
||||
}
|
||||
}
|
90
junrar/src/main/java/junrar/io/ReadOnlyAccessByteArray.java
Normal file
90
junrar/src/main/java/junrar/io/ReadOnlyAccessByteArray.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 30.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.io;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A File like access to a byte array.
|
||||
* (seek and read certain number of bytes)
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class ReadOnlyAccessByteArray implements IReadOnlyAccess{
|
||||
|
||||
private int positionInFile;
|
||||
private byte[] file;
|
||||
|
||||
/**
|
||||
* Initialize with byte[ ]
|
||||
* @param file the file given as byte array
|
||||
*/
|
||||
public ReadOnlyAccessByteArray(byte[] file){
|
||||
if(file == null){
|
||||
throw new NullPointerException("file must not be null!!");
|
||||
}
|
||||
this.file = file;
|
||||
this.positionInFile = 0;
|
||||
}
|
||||
|
||||
public long getPosition() throws IOException {
|
||||
return positionInFile;
|
||||
}
|
||||
|
||||
public void setPosition(long pos) throws IOException {
|
||||
if (pos < file.length && pos >= 0){
|
||||
this.positionInFile = (int)pos;
|
||||
}
|
||||
else{
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Read a single byte of data. */
|
||||
public int read() throws IOException {
|
||||
return file[positionInFile++];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read up to <tt>count</tt> bytes to the specified buffer.
|
||||
*/
|
||||
public int read(byte[] buffer, int off, int count) throws IOException {
|
||||
int read = Math.min(count, file.length-positionInFile);
|
||||
System.arraycopy(file, positionInFile, buffer, off, read);
|
||||
positionInFile += read;
|
||||
return read;
|
||||
}
|
||||
|
||||
public int readFully(byte[] buffer, int count) throws IOException {
|
||||
if(buffer == null ){
|
||||
throw new NullPointerException("buffer must not be null");
|
||||
}
|
||||
if(count == 0){
|
||||
throw new IllegalArgumentException("cannot read 0 bytes ;-)");
|
||||
}
|
||||
int read = Math.min(count, file.length-(int)positionInFile-1);
|
||||
System.arraycopy(file, (int)positionInFile, buffer, 0, read );
|
||||
positionInFile+=read;
|
||||
return read;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
}
|
||||
}
|
55
junrar/src/main/java/junrar/io/ReadOnlyAccessFile.java
Normal file
55
junrar/src/main/java/junrar/io/ReadOnlyAccessFile.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 23.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class ReadOnlyAccessFile extends RandomAccessFile
|
||||
implements IReadOnlyAccess{
|
||||
|
||||
/**
|
||||
* @param file the file
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public ReadOnlyAccessFile(File file) throws FileNotFoundException {
|
||||
super(file, "r");
|
||||
}
|
||||
|
||||
public int readFully(byte[] buffer, int count) throws IOException {
|
||||
assert (count > 0) : count;
|
||||
this.readFully(buffer, 0, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
public long getPosition() throws IOException {
|
||||
return this.getFilePointer();
|
||||
}
|
||||
|
||||
public void setPosition(long pos) throws IOException {
|
||||
this.seek(pos);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 26.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class ReadOnlyAccessInputStream extends InputStream {
|
||||
private IReadOnlyAccess file;
|
||||
|
||||
private long curPos;
|
||||
private final long endPos;
|
||||
|
||||
public ReadOnlyAccessInputStream(IReadOnlyAccess file, long startPos,
|
||||
long endPos) throws IOException {
|
||||
super();
|
||||
this.file = file;
|
||||
curPos = startPos;
|
||||
this.endPos = endPos;
|
||||
file.setPosition(curPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (curPos == endPos) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
int b = file.read();
|
||||
curPos++;
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (curPos == endPos) {
|
||||
return -1;
|
||||
}
|
||||
int bytesRead = file.read(b, off,
|
||||
(int)Math.min(len, endPos - curPos));
|
||||
curPos += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
//
|
||||
// public void close() throws IOException {
|
||||
// file.close();
|
||||
// }
|
||||
}
|
66
junrar/src/main/java/junrar/rarfile/AVHeader.java
Normal file
66
junrar/src/main/java/junrar/rarfile/AVHeader.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 24.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* extended version info header
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class AVHeader extends BaseBlock {
|
||||
|
||||
public static final int avHeaderSize = 7;
|
||||
|
||||
private byte unpackVersion;
|
||||
private byte method;
|
||||
private byte avVersion;
|
||||
private int avInfoCRC;
|
||||
|
||||
public AVHeader(BaseBlock bb, byte[] avHeader){
|
||||
super(bb);
|
||||
|
||||
int pos =0;
|
||||
unpackVersion |= avHeader[pos]&0xff;
|
||||
pos++;
|
||||
method |= avHeader[pos]&0xff;
|
||||
pos++;
|
||||
avVersion |= avHeader[pos]&0xff;
|
||||
pos++;
|
||||
avInfoCRC = Raw.readIntLittleEndian(avHeader, pos);
|
||||
}
|
||||
|
||||
public int getAvInfoCRC() {
|
||||
return avInfoCRC;
|
||||
}
|
||||
|
||||
public byte getAvVersion() {
|
||||
return avVersion;
|
||||
}
|
||||
|
||||
public byte getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public byte getUnpackVersion() {
|
||||
return unpackVersion;
|
||||
}
|
||||
}
|
181
junrar/src/main/java/junrar/rarfile/BaseBlock.java
Normal file
181
junrar/src/main/java/junrar/rarfile/BaseBlock.java
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class of all rar headers
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class BaseBlock{
|
||||
|
||||
private static String TAG = BaseBlock.class.getName();
|
||||
|
||||
public static final short BaseBlockSize = 7;
|
||||
|
||||
//TODO move somewhere else
|
||||
|
||||
public static final short MHD_VOLUME = 0x0001;
|
||||
public static final short MHD_COMMENT = 0x0002;
|
||||
public static final short MHD_LOCK = 0x0004;
|
||||
public static final short MHD_SOLID = 0x0008;
|
||||
public static final short MHD_PACK_COMMENT = 0x0010;
|
||||
public static final short MHD_NEWNUMBERING = 0x0010;
|
||||
public static final short MHD_AV = 0x0020;
|
||||
public static final short MHD_PROTECT = 0x0040;
|
||||
public static final short MHD_PASSWORD = 0x0080;
|
||||
public static final short MHD_FIRSTVOLUME = 0x0100;
|
||||
public static final short MHD_ENCRYPTVER = 0x0200;
|
||||
|
||||
|
||||
public static final short LHD_SPLIT_BEFORE = 0x0001;
|
||||
public static final short LHD_SPLIT_AFTER = 0x0002;
|
||||
public static final short LHD_PASSWORD = 0x0004;
|
||||
public static final short LHD_COMMENT = 0x0008;
|
||||
public static final short LHD_SOLID = 0x0010;
|
||||
|
||||
public static final short LHD_WINDOWMASK = 0x00e0;
|
||||
public static final short LHD_WINDOW64 = 0x0000;
|
||||
public static final short LHD_WINDOW128 = 0x0020;
|
||||
public static final short LHD_WINDOW256 = 0x0040;
|
||||
public static final short LHD_WINDOW512 = 0x0060;
|
||||
public static final short LHD_WINDOW1024 = 0x0080;
|
||||
public static final short LHD_WINDOW2048 = 0x00a0;
|
||||
public static final short LHD_WINDOW4096 = 0x00c0;
|
||||
public static final short LHD_DIRECTORY = 0x00e0;
|
||||
|
||||
public static final short LHD_LARGE = 0x0100;
|
||||
public static final short LHD_UNICODE = 0x0200;
|
||||
public static final short LHD_SALT = 0x0400;
|
||||
public static final short LHD_VERSION = 0x0800;
|
||||
public static final short LHD_EXTTIME = 0x1000;
|
||||
public static final short LHD_EXTFLAGS = 0x2000;
|
||||
|
||||
public static final short SKIP_IF_UNKNOWN = 0x4000;
|
||||
public static final short LONG_BLOCK = -0x8000;
|
||||
|
||||
public static final short EARC_NEXT_VOLUME = 0x0001;
|
||||
public static final short EARC_DATACRC = 0x0002;
|
||||
public static final short EARC_REVSPACE = 0x0004;
|
||||
public static final short EARC_VOLNUMBER = 0x0008;
|
||||
|
||||
|
||||
protected long positionInFile;
|
||||
|
||||
protected short headCRC = 0;
|
||||
protected byte headerType = 0;
|
||||
protected short flags = 0;
|
||||
protected short headerSize = 0 ;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public BaseBlock(){
|
||||
|
||||
}
|
||||
|
||||
public BaseBlock(BaseBlock bb){
|
||||
this.flags = bb.getFlags();
|
||||
this.headCRC = bb.getHeadCRC();
|
||||
this.headerType = bb.getHeaderType().getHeaderByte();
|
||||
this.headerSize = bb.getHeaderSize();
|
||||
this.positionInFile = bb.getPositionInFile();
|
||||
}
|
||||
public BaseBlock(byte[] baseBlockHeader){
|
||||
|
||||
int pos = 0;
|
||||
this.headCRC = Raw.readShortLittleEndian(baseBlockHeader, pos);
|
||||
pos+=2;
|
||||
this.headerType |= baseBlockHeader[pos]&0xff;
|
||||
pos++;
|
||||
this.flags = Raw.readShortLittleEndian(baseBlockHeader, pos);
|
||||
pos+=2;
|
||||
this.headerSize = Raw.readShortLittleEndian(baseBlockHeader, pos);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasArchiveDataCRC(){
|
||||
return (this.flags & EARC_DATACRC)!=0;
|
||||
}
|
||||
|
||||
public boolean hasVolumeNumber(){
|
||||
return (this.flags & EARC_VOLNUMBER)!=0;
|
||||
}
|
||||
|
||||
public boolean hasEncryptVersion(){
|
||||
return (flags & MHD_ENCRYPTVER)!=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return is it a sub block
|
||||
*/
|
||||
public boolean isSubBlock()
|
||||
{
|
||||
if (UnrarHeadertype.SubHeader.equals(headerType)){
|
||||
return(true);
|
||||
}
|
||||
if (UnrarHeadertype.NewSubHeader.equals(headerType) && (flags & LHD_SOLID)!=0)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
public long getPositionInFile() {
|
||||
return positionInFile;
|
||||
}
|
||||
|
||||
public short getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public short getHeadCRC() {
|
||||
return headCRC;
|
||||
}
|
||||
|
||||
public short getHeaderSize() {
|
||||
return headerSize;
|
||||
}
|
||||
|
||||
public UnrarHeadertype getHeaderType() {
|
||||
return UnrarHeadertype.findType(headerType);
|
||||
}
|
||||
|
||||
public void setPositionInFile(long positionInFile) {
|
||||
this.positionInFile = positionInFile;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
StringBuilder str =new StringBuilder();
|
||||
str.append("HeaderType: " + getHeaderType());
|
||||
str.append("\nHeadCRC: "+Integer.toHexString(getHeadCRC()));
|
||||
str.append("\nFlags: "+Integer.toHexString(getFlags()));
|
||||
str.append("\nHeaderSize: "+getHeaderSize());
|
||||
str.append("\nPosition in file: "+getPositionInFile());
|
||||
Log.i(TAG, str.toString());
|
||||
}
|
||||
}
|
72
junrar/src/main/java/junrar/rarfile/BlockHeader.java
Normal file
72
junrar/src/main/java/junrar/rarfile/BlockHeader.java
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
/**
|
||||
* Base class of headers that contain data
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class BlockHeader extends BaseBlock{
|
||||
public static final short blockHeaderSize = 4;
|
||||
|
||||
private static String TAG = BlockHeader.class.getName();
|
||||
|
||||
private long dataSize;
|
||||
private long packSize;
|
||||
|
||||
public BlockHeader(){
|
||||
|
||||
}
|
||||
|
||||
public BlockHeader(BlockHeader bh){
|
||||
super(bh);
|
||||
this.packSize = bh.getDataSize();
|
||||
this.dataSize = packSize;
|
||||
this.positionInFile = bh.getPositionInFile();
|
||||
}
|
||||
|
||||
public BlockHeader(BaseBlock bb, byte[] blockHeader)
|
||||
{
|
||||
super(bb);
|
||||
|
||||
this.packSize = Raw.readIntLittleEndianAsLong(blockHeader, 0);
|
||||
this.dataSize = this.packSize;
|
||||
}
|
||||
|
||||
public long getDataSize() {
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
public long getPackSize() {
|
||||
return packSize;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
super.print();
|
||||
String s = "DataSize: "+getDataSize()+" packSize: "+getPackSize();
|
||||
Log.i(TAG, s);
|
||||
}
|
||||
}
|
70
junrar/src/main/java/junrar/rarfile/CommentHeader.java
Normal file
70
junrar/src/main/java/junrar/rarfile/CommentHeader.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 23.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
|
||||
package junrar.rarfile;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* Comment header
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class CommentHeader extends BaseBlock {
|
||||
|
||||
public static final short commentHeaderSize = 6;
|
||||
|
||||
private short unpSize;
|
||||
private byte unpVersion;
|
||||
private byte unpMethod;
|
||||
private short commCRC;
|
||||
|
||||
|
||||
public CommentHeader(BaseBlock bb, byte[] commentHeader){
|
||||
super(bb);
|
||||
|
||||
int pos =0;
|
||||
unpSize = Raw.readShortLittleEndian(commentHeader, pos);
|
||||
pos += 2;
|
||||
unpVersion |= commentHeader[pos]&0xff;
|
||||
pos++;
|
||||
|
||||
unpMethod |= commentHeader[pos]&0xff;
|
||||
pos++;
|
||||
commCRC =Raw.readShortLittleEndian(commentHeader, pos);
|
||||
|
||||
}
|
||||
|
||||
public short getCommCRC() {
|
||||
return commCRC;
|
||||
}
|
||||
|
||||
public byte getUnpMethod() {
|
||||
return unpMethod;
|
||||
}
|
||||
|
||||
public short getUnpSize() {
|
||||
return unpSize;
|
||||
}
|
||||
|
||||
public byte getUnpVersion() {
|
||||
return unpVersion;
|
||||
}
|
||||
}
|
92
junrar/src/main/java/junrar/rarfile/EAHeader.java
Normal file
92
junrar/src/main/java/junrar/rarfile/EAHeader.java
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 27.11.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
/**
|
||||
* extended archive CRC header
|
||||
*
|
||||
*/
|
||||
public class EAHeader
|
||||
extends SubBlockHeader
|
||||
{
|
||||
private static String TAG = EAHeader.class.getName();
|
||||
|
||||
public static final short EAHeaderSize = 10;
|
||||
|
||||
private int unpSize;
|
||||
private byte unpVer;
|
||||
private byte method;
|
||||
private int EACRC;
|
||||
|
||||
public EAHeader(SubBlockHeader sb, byte[] eahead)
|
||||
{
|
||||
super(sb);
|
||||
int pos = 0;
|
||||
unpSize = Raw.readIntLittleEndian(eahead, pos);
|
||||
pos+=4;
|
||||
unpVer |= eahead[pos]&0xff;
|
||||
pos++;
|
||||
method |= eahead[pos]&0xff;
|
||||
pos++;
|
||||
EACRC = Raw.readIntLittleEndian(eahead, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the eACRC
|
||||
*/
|
||||
public int getEACRC() {
|
||||
return EACRC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the method
|
||||
*/
|
||||
public byte getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unpSize
|
||||
*/
|
||||
public int getUnpSize() {
|
||||
return unpSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unpVer
|
||||
*/
|
||||
public byte getUnpVer() {
|
||||
return unpVer;
|
||||
}
|
||||
|
||||
public void print()
|
||||
{
|
||||
super.print();
|
||||
Log.i(TAG, "unpSize: "+unpSize);
|
||||
Log.i(TAG, "unpVersion: " + unpVer);
|
||||
Log.i(TAG, "method: "+method);
|
||||
Log.i(TAG, "EACRC:" + EACRC);
|
||||
}
|
||||
}
|
||||
|
57
junrar/src/main/java/junrar/rarfile/EndArcHeader.java
Normal file
57
junrar/src/main/java/junrar/rarfile/EndArcHeader.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 24.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
*
|
||||
* the optional End header
|
||||
*
|
||||
*/
|
||||
public class EndArcHeader extends BaseBlock{
|
||||
|
||||
public static final short endArcArchiveDataCrcSize = 4;
|
||||
public static final short endArcVolumeNumberSize = 2;
|
||||
|
||||
private int archiveDataCRC;
|
||||
private short volumeNumber;
|
||||
|
||||
|
||||
public EndArcHeader(BaseBlock bb, byte[] endArcHeader){
|
||||
super(bb);
|
||||
|
||||
int pos = 0;
|
||||
if(hasArchiveDataCRC()){
|
||||
archiveDataCRC =Raw.readIntLittleEndian(endArcHeader, pos);
|
||||
pos+=4;
|
||||
}
|
||||
if(hasVolumeNumber()){
|
||||
volumeNumber = Raw.readShortLittleEndian(endArcHeader, pos);
|
||||
}
|
||||
}
|
||||
|
||||
public int getArchiveDataCRC() {
|
||||
return archiveDataCRC;
|
||||
}
|
||||
|
||||
public short getVolumeNumber() {
|
||||
return volumeNumber;
|
||||
}
|
||||
}
|
423
junrar/src/main/java/junrar/rarfile/FileHeader.java
Normal file
423
junrar/src/main/java/junrar/rarfile/FileHeader.java
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class FileHeader extends BlockHeader {
|
||||
|
||||
private static String TAG = FileHeader.class.getName();
|
||||
|
||||
private static final byte SALT_SIZE = 8;
|
||||
|
||||
private static final byte NEWLHD_SIZE = 32;
|
||||
|
||||
private long unpSize;
|
||||
|
||||
private final HostSystem hostOS;
|
||||
|
||||
private final int fileCRC;
|
||||
|
||||
private final int fileTime;
|
||||
|
||||
private byte unpVersion;
|
||||
|
||||
private byte unpMethod;
|
||||
|
||||
private short nameSize;
|
||||
|
||||
private int highPackSize;
|
||||
|
||||
private int highUnpackSize;
|
||||
|
||||
private final byte[] fileNameBytes;
|
||||
|
||||
private String fileName;
|
||||
private String fileNameW;
|
||||
|
||||
private byte[] subData;
|
||||
|
||||
private final byte[] salt = new byte[SALT_SIZE];
|
||||
|
||||
private Date mTime;
|
||||
|
||||
private Date cTime;
|
||||
|
||||
private Date aTime;
|
||||
|
||||
private Date arcTime;
|
||||
|
||||
private long fullPackSize;
|
||||
|
||||
private long fullUnpackSize;
|
||||
|
||||
private int fileAttr;
|
||||
|
||||
private int subFlags; // same as fileAttr (in header)
|
||||
|
||||
private int recoverySectors = -1;
|
||||
|
||||
public FileHeader(BlockHeader bh, byte[] fileHeader) {
|
||||
super(bh);
|
||||
|
||||
int position = 0;
|
||||
unpSize = Raw.readIntLittleEndianAsLong(fileHeader, position);
|
||||
position += 4;
|
||||
hostOS = HostSystem.findHostSystem(fileHeader[4]);
|
||||
position++;
|
||||
|
||||
fileCRC = Raw.readIntLittleEndian(fileHeader, position);
|
||||
position += 4;
|
||||
|
||||
fileTime = Raw.readIntLittleEndian(fileHeader, position);
|
||||
position += 4;
|
||||
|
||||
unpVersion |= fileHeader[13] & 0xff;
|
||||
position++;
|
||||
unpMethod |= fileHeader[14] & 0xff;
|
||||
position++;
|
||||
nameSize = Raw.readShortLittleEndian(fileHeader, position);
|
||||
position += 2;
|
||||
|
||||
fileAttr = Raw.readIntLittleEndian(fileHeader, position);
|
||||
position += 4;
|
||||
if (isLargeBlock()) {
|
||||
highPackSize = Raw.readIntLittleEndian(fileHeader, position);
|
||||
position += 4;
|
||||
|
||||
highUnpackSize = Raw.readIntLittleEndian(fileHeader, position);
|
||||
position += 4;
|
||||
} else {
|
||||
highPackSize = 0;
|
||||
highUnpackSize = 0;
|
||||
if (unpSize == 0xffffffff) {
|
||||
|
||||
unpSize = 0xffffffff;
|
||||
highUnpackSize = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
fullPackSize |= highPackSize;
|
||||
fullPackSize <<= 32;
|
||||
fullPackSize |= getPackSize();
|
||||
|
||||
fullUnpackSize |= highUnpackSize;
|
||||
fullUnpackSize <<= 32;
|
||||
fullUnpackSize += unpSize;
|
||||
|
||||
nameSize = nameSize > 4 * 1024 ? 4 * 1024 : nameSize;
|
||||
|
||||
fileNameBytes = new byte[nameSize];
|
||||
for (int i = 0; i < nameSize; i++) {
|
||||
fileNameBytes[i] = fileHeader[position];
|
||||
position++;
|
||||
}
|
||||
|
||||
if (isFileHeader()) {
|
||||
if (isUnicode()) {
|
||||
int length = 0;
|
||||
fileName = "";
|
||||
fileNameW = "";
|
||||
while (length < fileNameBytes.length
|
||||
&& fileNameBytes[length] != 0) {
|
||||
length++;
|
||||
}
|
||||
byte[] name = new byte[length];
|
||||
System.arraycopy(fileNameBytes, 0, name, 0, name.length);
|
||||
fileName = new String(name);
|
||||
if (length != nameSize) {
|
||||
length++;
|
||||
fileNameW = FileNameDecoder.decode(fileNameBytes, length);
|
||||
}
|
||||
} else {
|
||||
fileName = new String(fileNameBytes);
|
||||
fileNameW = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (UnrarHeadertype.NewSubHeader.equals(headerType)) {
|
||||
int datasize = headerSize - NEWLHD_SIZE - nameSize;
|
||||
if (hasSalt()) {
|
||||
datasize -= SALT_SIZE;
|
||||
}
|
||||
if (datasize > 0) {
|
||||
subData = new byte[datasize];
|
||||
for (int i = 0; i < datasize; i++) {
|
||||
subData[i] = (fileHeader[position]);
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
if (NewSubHeaderType.SUBHEAD_TYPE_RR.byteEquals(fileNameBytes)) {
|
||||
recoverySectors = subData[8] + (subData[9] << 8)
|
||||
+ (subData[10] << 16) + (subData[11] << 24);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSalt()) {
|
||||
for (int i = 0; i < SALT_SIZE; i++) {
|
||||
salt[i] = fileHeader[position];
|
||||
position++;
|
||||
}
|
||||
}
|
||||
mTime = getDateDos(fileTime);
|
||||
// TODO rartime -> extended
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print() {
|
||||
super.print();
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("unpSize: " + getUnpSize());
|
||||
str.append("\nHostOS: " + hostOS.name());
|
||||
str.append("\nMDate: " + mTime);
|
||||
str.append("\nFileName: " + getFileNameString());
|
||||
str.append("\nunpMethod: " + Integer.toHexString(getUnpMethod()));
|
||||
str.append("\nunpVersion: " + Integer.toHexString(getUnpVersion()));
|
||||
str.append("\nfullpackedsize: " + getFullPackSize());
|
||||
str.append("\nfullunpackedsize: " + getFullUnpackSize());
|
||||
str.append("\nisEncrypted: " + isEncrypted());
|
||||
str.append("\nisfileHeader: " + isFileHeader());
|
||||
str.append("\nisSolid: " + isSolid());
|
||||
str.append("\nisSplitafter: " + isSplitAfter());
|
||||
str.append("\nisSplitBefore:" + isSplitBefore());
|
||||
str.append("\nunpSize: " + getUnpSize());
|
||||
str.append("\ndataSize: " + getDataSize());
|
||||
str.append("\nisUnicode: " + isUnicode());
|
||||
str.append("\nhasVolumeNumber: " + hasVolumeNumber());
|
||||
str.append("\nhasArchiveDataCRC: " + hasArchiveDataCRC());
|
||||
str.append("\nhasSalt: " + hasSalt());
|
||||
str.append("\nhasEncryptVersions: " + hasEncryptVersion());
|
||||
str.append("\nisSubBlock: " + isSubBlock());
|
||||
Log.i(TAG, str.toString());
|
||||
}
|
||||
|
||||
private Date getDateDos(int time) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.DAY_OF_MONTH, 1);
|
||||
cal.set(Calendar.YEAR, (time >>> 25) + 1980);
|
||||
cal.set(Calendar.MONTH, ((time >>> 21) & 0x0f) - 1);
|
||||
cal.set(Calendar.DAY_OF_MONTH, (time >>> 16) & 0x1f);
|
||||
cal.set(Calendar.HOUR_OF_DAY, (time >>> 11) & 0x1f);
|
||||
cal.set(Calendar.MINUTE, (time >>> 5) & 0x3f);
|
||||
cal.set(Calendar.SECOND, (time & 0x1f) * 2);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public Date getArcTime() {
|
||||
return arcTime;
|
||||
}
|
||||
|
||||
public void setArcTime(Date arcTime) {
|
||||
this.arcTime = arcTime;
|
||||
}
|
||||
|
||||
public Date getATime() {
|
||||
return aTime;
|
||||
}
|
||||
|
||||
public void setATime(Date time) {
|
||||
aTime = time;
|
||||
}
|
||||
|
||||
public Date getCTime() {
|
||||
return cTime;
|
||||
}
|
||||
|
||||
public void setCTime(Date time) {
|
||||
cTime = time;
|
||||
}
|
||||
|
||||
public int getFileAttr() {
|
||||
return fileAttr;
|
||||
}
|
||||
|
||||
public void setFileAttr(int fileAttr) {
|
||||
this.fileAttr = fileAttr;
|
||||
}
|
||||
|
||||
public int getFileCRC() {
|
||||
return fileCRC;
|
||||
}
|
||||
|
||||
public byte[] getFileNameByteArray() {
|
||||
return fileNameBytes;
|
||||
}
|
||||
|
||||
public String getFileNameString() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getFileNameW() {
|
||||
return fileNameW;
|
||||
}
|
||||
|
||||
public void setFileNameW(String fileNameW) {
|
||||
this.fileNameW = fileNameW;
|
||||
}
|
||||
|
||||
public int getHighPackSize() {
|
||||
return highPackSize;
|
||||
}
|
||||
|
||||
public int getHighUnpackSize() {
|
||||
return highUnpackSize;
|
||||
}
|
||||
|
||||
public HostSystem getHostOS() {
|
||||
return hostOS;
|
||||
}
|
||||
|
||||
public Date getMTime() {
|
||||
return mTime;
|
||||
}
|
||||
|
||||
public void setMTime(Date time) {
|
||||
mTime = time;
|
||||
}
|
||||
|
||||
public short getNameSize() {
|
||||
return nameSize;
|
||||
}
|
||||
|
||||
public int getRecoverySectors() {
|
||||
return recoverySectors;
|
||||
}
|
||||
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public byte[] getSubData() {
|
||||
return subData;
|
||||
}
|
||||
|
||||
public int getSubFlags() {
|
||||
return subFlags;
|
||||
}
|
||||
|
||||
public byte getUnpMethod() {
|
||||
return unpMethod;
|
||||
}
|
||||
|
||||
public long getUnpSize() {
|
||||
return unpSize;
|
||||
}
|
||||
|
||||
public byte getUnpVersion() {
|
||||
return unpVersion;
|
||||
}
|
||||
|
||||
public long getFullPackSize() {
|
||||
return fullPackSize;
|
||||
}
|
||||
|
||||
public long getFullUnpackSize() {
|
||||
return fullUnpackSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* the file will be continued in the next archive part
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSplitAfter() {
|
||||
return (this.flags & BlockHeader.LHD_SPLIT_AFTER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* the file is continued in this archive
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSplitBefore() {
|
||||
return (this.flags & LHD_SPLIT_BEFORE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* this file is compressed as solid (all files handeled as one)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSolid() {
|
||||
return (this.flags & LHD_SOLID) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* the file is encrypted
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEncrypted() {
|
||||
return (this.flags & BlockHeader.LHD_PASSWORD) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* the filename is also present in unicode
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isUnicode() {
|
||||
return (flags & LHD_UNICODE) != 0;
|
||||
}
|
||||
|
||||
public boolean isFileHeader() {
|
||||
return UnrarHeadertype.FileHeader.equals(headerType);
|
||||
}
|
||||
|
||||
public boolean hasSalt() {
|
||||
return (flags & LHD_SALT) != 0;
|
||||
}
|
||||
|
||||
public boolean isLargeBlock() {
|
||||
return (flags & LHD_LARGE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether this fileheader represents a directory
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDirectory() {
|
||||
return (flags & LHD_WINDOWMASK) == LHD_DIRECTORY;
|
||||
}
|
||||
}
|
76
junrar/src/main/java/junrar/rarfile/FileNameDecoder.java
Normal file
76
junrar/src/main/java/junrar/rarfile/FileNameDecoder.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
*
|
||||
* Original author: alpha_lam
|
||||
* Creation date: ?
|
||||
*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
public class FileNameDecoder {
|
||||
public static int getChar(byte [] name,int pos){
|
||||
return name[pos]&0xff;
|
||||
}
|
||||
|
||||
public static String decode(byte [] name,int encPos){
|
||||
int decPos = 0;
|
||||
int flags = 0;
|
||||
int flagBits = 0;
|
||||
|
||||
int low = 0;
|
||||
int high = 0;
|
||||
int highByte = getChar(name,encPos++);
|
||||
StringBuffer buf = new StringBuffer();
|
||||
while(encPos < name.length){
|
||||
if(flagBits == 0){
|
||||
flags = getChar(name,encPos++);
|
||||
flagBits = 8;
|
||||
}
|
||||
switch(flags >> 6){
|
||||
case 0:
|
||||
buf.append((char)(getChar(name,encPos++)));
|
||||
++decPos;
|
||||
break;
|
||||
case 1:
|
||||
buf.append((char)(getChar(name,encPos++)+(highByte<<8)));
|
||||
++decPos;
|
||||
break;
|
||||
case 2:
|
||||
low = getChar(name,encPos);
|
||||
high = getChar(name,encPos+1);
|
||||
buf.append((char)((high << 8) + low));
|
||||
++decPos;
|
||||
encPos += 2;
|
||||
break;
|
||||
case 3:
|
||||
int length = getChar(name,encPos++);
|
||||
if((length&0x80)!=0){
|
||||
int correction = getChar(name,encPos++);
|
||||
for(length=(length&0x7f)+2;length>0&&decPos<name.length;length--,decPos++){
|
||||
low = (getChar(name,decPos) + correction)&0xff;
|
||||
buf.append((char)((highByte << 8) + low));
|
||||
}
|
||||
}else{
|
||||
for(length+=2;length>0&&decPos<name.length;length--,decPos++){
|
||||
buf.append((char)(getChar(name,decPos)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
flags = (flags << 2) & 0xff;
|
||||
flagBits -= 2;
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
72
junrar/src/main/java/junrar/rarfile/HostSystem.java
Normal file
72
junrar/src/main/java/junrar/rarfile/HostSystem.java
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum HostSystem {
|
||||
msdos ((byte)0),
|
||||
os2 ((byte)1),
|
||||
win32 ((byte)2),
|
||||
unix ((byte)3),
|
||||
macos ((byte)4),
|
||||
beos ((byte)5);
|
||||
|
||||
private byte hostByte;
|
||||
|
||||
public static HostSystem findHostSystem(byte hostByte){
|
||||
if(HostSystem.msdos.equals(hostByte)){
|
||||
return HostSystem.msdos;
|
||||
}
|
||||
if(HostSystem.os2.equals(hostByte)){
|
||||
return HostSystem.os2;
|
||||
}
|
||||
if(HostSystem.win32.equals(hostByte)){
|
||||
return HostSystem.win32;
|
||||
}
|
||||
if(HostSystem.unix.equals(hostByte)){
|
||||
return HostSystem.unix;
|
||||
}
|
||||
if(HostSystem.macos.equals(hostByte)){
|
||||
return HostSystem.macos;
|
||||
}
|
||||
if(HostSystem.beos.equals(hostByte)){
|
||||
return HostSystem.beos;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private HostSystem(byte hostByte){
|
||||
this.hostByte = hostByte;
|
||||
}
|
||||
|
||||
public boolean equals(byte hostByte){
|
||||
return this.hostByte == hostByte;
|
||||
}
|
||||
|
||||
public byte getHostByte(){
|
||||
return hostByte;
|
||||
}
|
||||
//???? public static final byte max = 6;
|
||||
}
|
83
junrar/src/main/java/junrar/rarfile/MacInfoHeader.java
Normal file
83
junrar/src/main/java/junrar/rarfile/MacInfoHeader.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 26.11.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
/**
|
||||
* Mac File attribute header
|
||||
*
|
||||
*/
|
||||
public class MacInfoHeader
|
||||
extends SubBlockHeader
|
||||
{
|
||||
private static String TAG = MacInfoHeader.class.getName();
|
||||
|
||||
public static final short MacInfoHeaderSize = 8;
|
||||
|
||||
private int fileType;
|
||||
private int fileCreator;
|
||||
|
||||
public MacInfoHeader(SubBlockHeader sb, byte[] macHeader)
|
||||
{
|
||||
super(sb);
|
||||
int pos = 0;
|
||||
fileType = Raw.readIntLittleEndian(macHeader, pos);
|
||||
pos+=4;
|
||||
fileCreator = Raw.readIntLittleEndian(macHeader, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fileCreator
|
||||
*/
|
||||
public int getFileCreator() {
|
||||
return fileCreator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileCreator the fileCreator to set
|
||||
*/
|
||||
public void setFileCreator(int fileCreator) {
|
||||
this.fileCreator = fileCreator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fileType
|
||||
*/
|
||||
public int getFileType() {
|
||||
return fileType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileType the fileType to set
|
||||
*/
|
||||
public void setFileType(int fileType) {
|
||||
this.fileType = fileType;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
super.print();
|
||||
Log.i(TAG, "filetype: "+fileType);
|
||||
Log.i(TAG, "creator :"+fileCreator);
|
||||
}
|
||||
|
||||
}
|
143
junrar/src/main/java/junrar/rarfile/MainHeader.java
Normal file
143
junrar/src/main/java/junrar/rarfile/MainHeader.java
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
/**
|
||||
* The main header of an rar archive. holds information concerning the whole archive (solid, encrypted etc).
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class MainHeader extends BaseBlock {
|
||||
private static String TAG = MainHeader.class.getName();
|
||||
public static final short mainHeaderSizeWithEnc = 7;
|
||||
public static final short mainHeaderSize = 6;
|
||||
private short highPosAv;
|
||||
private int posAv;
|
||||
private byte encryptVersion;
|
||||
|
||||
public MainHeader(BaseBlock bb, byte[] mainHeader) {
|
||||
super(bb);
|
||||
int pos = 0;
|
||||
highPosAv = Raw.readShortLittleEndian(mainHeader, pos);
|
||||
pos += 2;
|
||||
posAv = Raw.readIntLittleEndian(mainHeader, pos);
|
||||
pos+=4;
|
||||
|
||||
if(hasEncryptVersion()){
|
||||
encryptVersion |= mainHeader[pos]&0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* old cmt block is present
|
||||
* @return true if has cmt block
|
||||
*/
|
||||
public boolean hasArchCmt(){
|
||||
return (this.flags & BaseBlock.MHD_COMMENT)!=0;
|
||||
}
|
||||
/**
|
||||
* the version the the encryption
|
||||
* @return
|
||||
*/
|
||||
public byte getEncryptVersion() {
|
||||
return encryptVersion;
|
||||
}
|
||||
|
||||
public short getHighPosAv() {
|
||||
return highPosAv;
|
||||
}
|
||||
|
||||
public int getPosAv() {
|
||||
return posAv;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns whether the archive is encrypted
|
||||
* @return
|
||||
*/
|
||||
public boolean isEncrypted(){
|
||||
return (this.flags & BaseBlock.MHD_PASSWORD)!=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* return whether the archive is a multivolume archive
|
||||
* @return
|
||||
*/
|
||||
public boolean isMultiVolume(){
|
||||
return (this.flags & BaseBlock.MHD_VOLUME)!=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* if the archive is a multivolume archive this method returns whether this instance is the first part of the multivolume archive
|
||||
* @return
|
||||
*/
|
||||
public boolean isFirstVolume(){
|
||||
return (this.flags & BaseBlock.MHD_FIRSTVOLUME)!=0;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
super.print();
|
||||
StringBuilder str=new StringBuilder();
|
||||
str.append("posav: "+getPosAv());
|
||||
str.append("\nhighposav: "+getHighPosAv());
|
||||
str.append("\nhasencversion: "+hasEncryptVersion()+(hasEncryptVersion()?getEncryptVersion():""));
|
||||
str.append("\nhasarchcmt: "+hasArchCmt());
|
||||
str.append("\nisEncrypted: "+isEncrypted());
|
||||
str.append("\nisMultivolume: "+isMultiVolume());
|
||||
str.append("\nisFirstvolume: "+isFirstVolume());
|
||||
str.append("\nisSolid: "+isSolid());
|
||||
str.append("\nisLocked: "+isLocked());
|
||||
str.append("\nisProtected: "+isProtected());
|
||||
str.append("\nisAV: "+isAV());
|
||||
Log.i(TAG, str.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* returns whether this archive is solid. in this case you can only extract all file at once
|
||||
* @return
|
||||
*/
|
||||
public boolean isSolid(){
|
||||
return (this.flags&MHD_SOLID)!=0;
|
||||
}
|
||||
|
||||
public boolean isLocked(){
|
||||
return (this.flags&MHD_LOCK)!=0;
|
||||
}
|
||||
|
||||
public boolean isProtected(){
|
||||
return (this.flags&MHD_PROTECT)!=0;
|
||||
}
|
||||
|
||||
public boolean isAV(){
|
||||
return (this.flags&MHD_AV)!=0;
|
||||
}
|
||||
/**
|
||||
* the numbering format a multivolume archive
|
||||
* @return
|
||||
*/
|
||||
public boolean isNewNumbering(){
|
||||
return (this.flags&MHD_NEWNUMBERING)!=0;
|
||||
}
|
||||
}
|
86
junrar/src/main/java/junrar/rarfile/MarkHeader.java
Normal file
86
junrar/src/main/java/junrar/rarfile/MarkHeader.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 24.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
/**
|
||||
* the header to recognize a file to be a rar archive
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class MarkHeader extends BaseBlock {
|
||||
|
||||
private static String TAG = MarkHeader.class.getName();
|
||||
private boolean oldFormat = false;
|
||||
|
||||
public MarkHeader(BaseBlock bb){
|
||||
super(bb);
|
||||
}
|
||||
public boolean isValid(){
|
||||
if(!(getHeadCRC() == 0x6152)){
|
||||
return false;
|
||||
}
|
||||
if(!(getHeaderType() == UnrarHeadertype.MarkHeader)){
|
||||
return false;
|
||||
}
|
||||
if(!(getFlags() == 0x1a21)){
|
||||
return false;
|
||||
}
|
||||
if(!(getHeaderSize() == BaseBlockSize)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isSignature() {
|
||||
boolean valid=false;
|
||||
byte[] d = new byte[BaseBlock.BaseBlockSize];
|
||||
Raw.writeShortLittleEndian(d, 0, headCRC);
|
||||
d[2] = headerType;
|
||||
Raw.writeShortLittleEndian(d, 3, flags);
|
||||
Raw.writeShortLittleEndian(d, 5, headerSize);
|
||||
|
||||
if (d[0] == 0x52) {
|
||||
if (d[1]==0x45 && d[2]==0x7e && d[3]==0x5e) {
|
||||
oldFormat=true;
|
||||
valid=true;
|
||||
}
|
||||
else if (d[1]==0x61 && d[2]==0x72 && d[3]==0x21 && d[4]==((byte)0x1a) &&
|
||||
d[5]==0x07 && d[6]==0x00) {
|
||||
oldFormat=false;
|
||||
valid=true;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
public boolean isOldFormat() {
|
||||
return oldFormat;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
super.print();
|
||||
Log.i(TAG, "valid: "+isValid());
|
||||
}
|
||||
}
|
89
junrar/src/main/java/junrar/rarfile/NewSubHeaderType.java
Normal file
89
junrar/src/main/java/junrar/rarfile/NewSubHeaderType.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 24.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* subheaders new version of the info headers
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class NewSubHeaderType {
|
||||
|
||||
/**
|
||||
* comment subheader
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_CMT = new NewSubHeaderType(new byte[]{'C','M','T'});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_ACL = new NewSubHeaderType(new byte[]{'A','C','L'});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_STREAM = new NewSubHeaderType(new byte[]{'S','T','M'});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_UOWNER = new NewSubHeaderType(new byte[]{'U','O','W'});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_AV = new NewSubHeaderType(new byte[]{'A','V'});
|
||||
/**
|
||||
* recovery record subheader
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_RR = new NewSubHeaderType(new byte[]{'R','R'});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_OS2EA = new NewSubHeaderType(new byte[]{'E','A','2'});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final NewSubHeaderType SUBHEAD_TYPE_BEOSEA = new NewSubHeaderType(new byte[]{'E','A','B','E'});
|
||||
|
||||
private byte[] headerTypes;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
* @param headerTypes
|
||||
*/
|
||||
private NewSubHeaderType(byte[] headerTypes)
|
||||
{
|
||||
this.headerTypes = headerTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param toCompare
|
||||
* @return Returns true if the given byte array matches to the internal byte array of this header.
|
||||
*/
|
||||
public boolean byteEquals(byte[] toCompare)
|
||||
{
|
||||
return Arrays.equals(this.headerTypes, toCompare);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return new String(this.headerTypes);
|
||||
}
|
||||
}
|
71
junrar/src/main/java/junrar/rarfile/ProtectHeader.java
Normal file
71
junrar/src/main/java/junrar/rarfile/ProtectHeader.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 24.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* recovery header
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class ProtectHeader extends BlockHeader {
|
||||
|
||||
/**
|
||||
* the header size
|
||||
*/
|
||||
public static final int protectHeaderSize = 8;
|
||||
|
||||
private byte version;
|
||||
private short recSectors;
|
||||
private int totalBlocks;
|
||||
private byte mark;
|
||||
|
||||
|
||||
public ProtectHeader(BlockHeader bh, byte[] protectHeader){
|
||||
super(bh);
|
||||
|
||||
int pos = 0;
|
||||
version |= protectHeader[pos]&0xff;
|
||||
|
||||
recSectors = Raw.readShortLittleEndian(protectHeader, pos);
|
||||
pos += 2;
|
||||
totalBlocks = Raw.readIntLittleEndian(protectHeader, pos);
|
||||
pos += 4;
|
||||
mark |= protectHeader[pos]&0xff;
|
||||
}
|
||||
|
||||
|
||||
public byte getMark() {
|
||||
return mark;
|
||||
}
|
||||
|
||||
public short getRecSectors() {
|
||||
return recSectors;
|
||||
}
|
||||
|
||||
public int getTotalBlocks() {
|
||||
return totalBlocks;
|
||||
}
|
||||
|
||||
public byte getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
60
junrar/src/main/java/junrar/rarfile/SignHeader.java
Normal file
60
junrar/src/main/java/junrar/rarfile/SignHeader.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 24.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* sign header
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class SignHeader extends BaseBlock {
|
||||
|
||||
public static final short signHeaderSize = 8;
|
||||
|
||||
private int creationTime=0;
|
||||
private short arcNameSize=0;
|
||||
private short userNameSize=0;
|
||||
|
||||
|
||||
public SignHeader(BaseBlock bb, byte[] signHeader){
|
||||
super(bb);
|
||||
|
||||
int pos = 0;
|
||||
creationTime = Raw.readIntLittleEndian(signHeader, pos);
|
||||
pos +=4;
|
||||
arcNameSize = Raw.readShortLittleEndian(signHeader, pos);
|
||||
pos+=2;
|
||||
userNameSize = Raw.readShortLittleEndian(signHeader, pos);
|
||||
}
|
||||
|
||||
public short getArcNameSize() {
|
||||
return arcNameSize;
|
||||
}
|
||||
|
||||
public int getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
public short getUserNameSize() {
|
||||
return userNameSize;
|
||||
}
|
||||
}
|
72
junrar/src/main/java/junrar/rarfile/SubBlockHeader.java
Normal file
72
junrar/src/main/java/junrar/rarfile/SubBlockHeader.java
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 21.11.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
public class SubBlockHeader
|
||||
extends BlockHeader
|
||||
{
|
||||
private static String TAG = SubBlockHeader.class.getName();
|
||||
|
||||
public static final short SubBlockHeaderSize = 3;
|
||||
|
||||
private short subType;
|
||||
private byte level;
|
||||
|
||||
public SubBlockHeader(SubBlockHeader sb)
|
||||
{
|
||||
super(sb);
|
||||
subType = sb.getSubType().getSubblocktype();
|
||||
level = sb.getLevel();
|
||||
}
|
||||
|
||||
public SubBlockHeader(BlockHeader bh, byte[] subblock)
|
||||
{
|
||||
super(bh);
|
||||
int position = 0;
|
||||
subType = Raw.readShortLittleEndian(subblock, position);
|
||||
position +=2;
|
||||
level |= subblock[position]&0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public SubBlockHeaderType getSubType() {
|
||||
return SubBlockHeaderType.findSubblockHeaderType(subType);
|
||||
}
|
||||
|
||||
public void print()
|
||||
{
|
||||
super.print();
|
||||
Log.i(TAG, "subtype: "+getSubType());
|
||||
Log.i(TAG, "level: "+level);
|
||||
}
|
||||
}
|
77
junrar/src/main/java/junrar/rarfile/SubBlockHeaderType.java
Normal file
77
junrar/src/main/java/junrar/rarfile/SubBlockHeaderType.java
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 20.11.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
|
||||
package junrar.rarfile;
|
||||
|
||||
public enum SubBlockHeaderType
|
||||
{
|
||||
EA_HEAD ((short)0x100),
|
||||
UO_HEAD ((short)0x101),
|
||||
MAC_HEAD ((short)0x102),
|
||||
BEEA_HEAD ((short)0x103),
|
||||
NTACL_HEAD ((short)0x104),
|
||||
STREAM_HEAD ((short)0x105);
|
||||
|
||||
private short subblocktype;
|
||||
|
||||
private SubBlockHeaderType(short subblocktype)
|
||||
{
|
||||
this.subblocktype = subblocktype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given value is equal to the enum's value
|
||||
* @param subblocktype
|
||||
* @return true if the given value is equal to the enum's value
|
||||
*/
|
||||
public boolean equals(short subblocktype)
|
||||
{
|
||||
return this.subblocktype == subblocktype;
|
||||
}
|
||||
|
||||
/**
|
||||
* find the header type for the given short value
|
||||
* @param SubType the short value
|
||||
* @return the correspo nding enum or null
|
||||
*/
|
||||
public static SubBlockHeaderType findSubblockHeaderType(short subType)
|
||||
{
|
||||
if(EA_HEAD.equals(subType)){
|
||||
return EA_HEAD;
|
||||
}else if(UO_HEAD.equals(subType)){
|
||||
return UO_HEAD;
|
||||
}else if(MAC_HEAD.equals(subType)){
|
||||
return MAC_HEAD;
|
||||
}else if(BEEA_HEAD.equals(subType)){
|
||||
return BEEA_HEAD;
|
||||
}else if(NTACL_HEAD.equals(subType)){
|
||||
return NTACL_HEAD;
|
||||
}else if(STREAM_HEAD.equals(subType)){
|
||||
return STREAM_HEAD;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the short representation of this enum
|
||||
*/
|
||||
public short getSubblocktype() {
|
||||
return subblocktype;
|
||||
}
|
||||
}
|
96
junrar/src/main/java/junrar/rarfile/UnixOwnersHeader.java
Normal file
96
junrar/src/main/java/junrar/rarfile/UnixOwnersHeader.java
Normal file
@ -0,0 +1,96 @@
|
||||
package junrar.rarfile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
public class UnixOwnersHeader
|
||||
extends SubBlockHeader
|
||||
{
|
||||
private static String TAG = UnixOwnersHeader.class.getName();
|
||||
|
||||
private int ownerNameSize;
|
||||
private int groupNameSize;
|
||||
private String owner;
|
||||
private String group;
|
||||
|
||||
public UnixOwnersHeader(SubBlockHeader sb, byte[] uoHeader) {
|
||||
super(sb);
|
||||
int pos = 0;
|
||||
ownerNameSize = Raw.readShortLittleEndian(uoHeader, pos)&0xFFFF;
|
||||
pos+=2;
|
||||
groupNameSize = Raw.readShortLittleEndian(uoHeader, pos)&0xFFFF;
|
||||
pos+=2;
|
||||
if(pos+ownerNameSize<uoHeader.length){
|
||||
byte[] ownerBuffer = new byte[ownerNameSize];
|
||||
System.arraycopy(uoHeader, pos, ownerBuffer, 0, ownerNameSize);
|
||||
owner = new String(ownerBuffer);
|
||||
}
|
||||
pos+=ownerNameSize;
|
||||
if(pos+groupNameSize<uoHeader.length){
|
||||
byte[] groupBuffer = new byte[groupNameSize];
|
||||
System.arraycopy(uoHeader, pos, groupBuffer, 0, groupNameSize);
|
||||
group = new String(groupBuffer);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return the group
|
||||
*/
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
/**
|
||||
* @param group the group to set
|
||||
*/
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
/**
|
||||
* @return the groupNameSize
|
||||
*/
|
||||
public int getGroupNameSize() {
|
||||
return groupNameSize;
|
||||
}
|
||||
/**
|
||||
* @param groupNameSize the groupNameSize to set
|
||||
*/
|
||||
public void setGroupNameSize(int groupNameSize) {
|
||||
this.groupNameSize = groupNameSize;
|
||||
}
|
||||
/**
|
||||
* @return the owner
|
||||
*/
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
/**
|
||||
* @param owner the owner to set
|
||||
*/
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
/**
|
||||
* @return the ownerNameSize
|
||||
*/
|
||||
public int getOwnerNameSize() {
|
||||
return ownerNameSize;
|
||||
}
|
||||
/**
|
||||
* @param ownerNameSize the ownerNameSize to set
|
||||
*/
|
||||
public void setOwnerNameSize(int ownerNameSize) {
|
||||
this.ownerNameSize = ownerNameSize;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see de.innosystec.unrar.rarfile.SubBlockHeader#print()
|
||||
*/
|
||||
public void print(){
|
||||
super.print();
|
||||
Log.i(TAG, "ownerNameSize: "+ownerNameSize);
|
||||
Log.i(TAG, "owner: "+owner);
|
||||
Log.i(TAG, "groupNameSize: "+groupNameSize);
|
||||
Log.i(TAG, "group: "+group);
|
||||
}
|
||||
}
|
164
junrar/src/main/java/junrar/rarfile/UnrarHeadertype.java
Normal file
164
junrar/src/main/java/junrar/rarfile/UnrarHeadertype.java
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.rarfile;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum UnrarHeadertype {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MainHeader ((byte)0x73),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MarkHeader ((byte)0x72),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
FileHeader ((byte) 0x74),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CommHeader ((byte) 0x75),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
AvHeader ((byte) 0x76),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
SubHeader ((byte) 0x77),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
ProtectHeader ((byte) 0x78),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
SignHeader ((byte) 0x79),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
NewSubHeader ((byte) 0x7a),
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
EndArcHeader ((byte) 0x7b);
|
||||
|
||||
/**
|
||||
* Returns the enum according to the given byte or null
|
||||
* @param headerType the headerbyte
|
||||
* @return the enum or null
|
||||
*/
|
||||
public static UnrarHeadertype findType(byte headerType)
|
||||
{
|
||||
if(UnrarHeadertype.MarkHeader.equals(headerType)){
|
||||
return UnrarHeadertype.MarkHeader;
|
||||
}
|
||||
if(UnrarHeadertype.MainHeader.equals(headerType)){
|
||||
return UnrarHeadertype.MainHeader;
|
||||
}
|
||||
if(UnrarHeadertype.FileHeader.equals(headerType)){
|
||||
return UnrarHeadertype.FileHeader;
|
||||
}
|
||||
if(UnrarHeadertype.EndArcHeader.equals(headerType)){
|
||||
return UnrarHeadertype.EndArcHeader;
|
||||
}
|
||||
if(UnrarHeadertype.NewSubHeader.equals(headerType)){
|
||||
return UnrarHeadertype.NewSubHeader;
|
||||
}
|
||||
if(UnrarHeadertype.SubHeader.equals(headerType)){
|
||||
return UnrarHeadertype.SubHeader;
|
||||
}
|
||||
if(UnrarHeadertype.SignHeader.equals(headerType)){
|
||||
return UnrarHeadertype.SignHeader;
|
||||
}
|
||||
if(UnrarHeadertype.ProtectHeader.equals(headerType)){
|
||||
return UnrarHeadertype.ProtectHeader;
|
||||
}
|
||||
if(UnrarHeadertype.MarkHeader.equals(headerType)){
|
||||
return UnrarHeadertype.MarkHeader;
|
||||
}
|
||||
if(UnrarHeadertype.MainHeader.equals(headerType)){
|
||||
return UnrarHeadertype.MainHeader;
|
||||
}
|
||||
if(UnrarHeadertype.FileHeader.equals(headerType)){
|
||||
return UnrarHeadertype.FileHeader;
|
||||
}
|
||||
if(UnrarHeadertype.EndArcHeader.equals(headerType)){
|
||||
return UnrarHeadertype.EndArcHeader;
|
||||
}
|
||||
if(UnrarHeadertype.CommHeader.equals(headerType)){
|
||||
return UnrarHeadertype.CommHeader;
|
||||
}
|
||||
if(UnrarHeadertype.AvHeader.equals(headerType)){
|
||||
return UnrarHeadertype.AvHeader;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private byte headerByte;
|
||||
|
||||
private UnrarHeadertype(byte headerByte)
|
||||
{
|
||||
this.headerByte = headerByte;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the given byte is equal to the enum's byte
|
||||
* @param header
|
||||
* @return true if the given byte is equal to the enum's byte
|
||||
*/
|
||||
public boolean equals(byte header)
|
||||
{
|
||||
return headerByte == header;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* the header byte of this enum
|
||||
* @return the header byte of this enum
|
||||
*/
|
||||
public byte getHeaderByte() {
|
||||
return headerByte;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
356
junrar/src/main/java/junrar/unpack/ComprDataIO.java
Normal file
356
junrar/src/main/java/junrar/unpack/ComprDataIO.java
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import junrar.Archive;
|
||||
import junrar.UnrarCallback;
|
||||
import junrar.Volume;
|
||||
import junrar.crc.RarCRC;
|
||||
import junrar.exception.RarException;
|
||||
import junrar.exception.RarException.RarExceptionType;
|
||||
import junrar.io.ReadOnlyAccessInputStream;
|
||||
import junrar.rarfile.FileHeader;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class ComprDataIO {
|
||||
|
||||
private final Archive archive;
|
||||
|
||||
private long unpPackedSize;
|
||||
|
||||
private boolean testMode;
|
||||
|
||||
private boolean skipUnpCRC;
|
||||
|
||||
private InputStream inputStream;
|
||||
|
||||
private OutputStream outputStream;
|
||||
|
||||
private FileHeader subHead;
|
||||
|
||||
// cryptData Crypt;
|
||||
// cryptData Decrypt;
|
||||
private boolean packVolume;
|
||||
|
||||
private boolean unpVolume;
|
||||
|
||||
private boolean nextVolumeMissing;
|
||||
|
||||
private long totalPackRead;
|
||||
|
||||
private long unpArcSize;
|
||||
|
||||
private long curPackRead, curPackWrite, curUnpRead, curUnpWrite;
|
||||
|
||||
private long processedArcSize, totalArcSize;
|
||||
|
||||
private long packFileCRC, unpFileCRC, packedCRC;
|
||||
|
||||
private int encryption;
|
||||
|
||||
private int decryption;
|
||||
|
||||
|
||||
public ComprDataIO(Archive arc) {
|
||||
this.archive = arc;
|
||||
}
|
||||
|
||||
public void init(OutputStream outputStream) {
|
||||
this.outputStream = outputStream;
|
||||
unpPackedSize = 0;
|
||||
testMode = false;
|
||||
skipUnpCRC = false;
|
||||
packVolume = false;
|
||||
unpVolume = false;
|
||||
nextVolumeMissing = false;
|
||||
// command = null;
|
||||
encryption = 0;
|
||||
decryption = 0;
|
||||
totalPackRead = 0;
|
||||
curPackRead = curPackWrite = curUnpRead = curUnpWrite = 0;
|
||||
packFileCRC = unpFileCRC = packedCRC = 0xffffffff;
|
||||
subHead = null;
|
||||
processedArcSize = totalArcSize = 0;
|
||||
}
|
||||
|
||||
public void init(FileHeader hd) throws IOException {
|
||||
long startPos = hd.getPositionInFile() + hd.getHeaderSize();
|
||||
unpPackedSize = hd.getFullPackSize();
|
||||
inputStream = new ReadOnlyAccessInputStream(archive.getRof(), startPos,
|
||||
startPos + unpPackedSize);
|
||||
subHead = hd;
|
||||
curUnpRead = 0;
|
||||
curPackWrite = 0;
|
||||
packedCRC = 0xFFffFFff;
|
||||
}
|
||||
|
||||
public int unpRead(byte[] addr, int offset, int count) throws IOException,
|
||||
RarException {
|
||||
int retCode = 0, totalRead = 0;
|
||||
while (count > 0) {
|
||||
int readSize = (count > unpPackedSize) ? (int) unpPackedSize
|
||||
: count;
|
||||
retCode = inputStream.read(addr, offset, readSize);
|
||||
if (retCode < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
if (subHead.isSplitAfter()) {
|
||||
packedCRC = RarCRC.checkCrc((int) packedCRC, addr, offset,
|
||||
retCode);
|
||||
}
|
||||
|
||||
curUnpRead += retCode;
|
||||
totalRead += retCode;
|
||||
offset += retCode;
|
||||
count -= retCode;
|
||||
unpPackedSize -= retCode;
|
||||
archive.bytesReadRead(retCode);
|
||||
if (unpPackedSize == 0 && subHead.isSplitAfter()) {
|
||||
Volume nextVolume = archive.getVolumeManager().nextArchive(
|
||||
archive, archive.getVolume());
|
||||
if (nextVolume == null) {
|
||||
nextVolumeMissing = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FileHeader hd = this.getSubHeader();
|
||||
if (hd.getUnpVersion() >= 20 && hd.getFileCRC() != 0xffffffff
|
||||
&& this.getPackedCRC() != ~hd.getFileCRC()) {
|
||||
throw new RarException(RarExceptionType.crcError);
|
||||
}
|
||||
UnrarCallback callback = archive.getUnrarCallback();
|
||||
if ((callback != null)
|
||||
&& !callback.isNextVolumeReady(nextVolume)) {
|
||||
return -1;
|
||||
}
|
||||
archive.setVolume(nextVolume);
|
||||
hd = archive.nextFileHeader();
|
||||
if (hd == null) {
|
||||
return -1;
|
||||
}
|
||||
this.init(hd);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (retCode != -1) {
|
||||
retCode = totalRead;
|
||||
}
|
||||
return retCode;
|
||||
|
||||
}
|
||||
|
||||
public void unpWrite(byte[] addr, int offset, int count) throws IOException {
|
||||
if (!testMode) {
|
||||
// DestFile->Write(Addr,Count);
|
||||
outputStream.write(addr, offset, count);
|
||||
}
|
||||
|
||||
curUnpWrite += count;
|
||||
|
||||
if (!skipUnpCRC) {
|
||||
if (archive.isOldFormat()) {
|
||||
unpFileCRC = RarCRC
|
||||
.checkOldCrc((short) unpFileCRC, addr, count);
|
||||
} else {
|
||||
unpFileCRC = RarCRC.checkCrc((int) unpFileCRC, addr, offset,
|
||||
count);
|
||||
}
|
||||
}
|
||||
// if (!skipArcCRC) {
|
||||
// archive.updateDataCRC(Addr, offset, ReadSize);
|
||||
// }
|
||||
}
|
||||
|
||||
public void setPackedSizeToRead(long size) {
|
||||
unpPackedSize = size;
|
||||
}
|
||||
|
||||
public void setTestMode(boolean mode) {
|
||||
testMode = mode;
|
||||
}
|
||||
|
||||
public void setSkipUnpCRC(boolean skip) {
|
||||
skipUnpCRC = skip;
|
||||
}
|
||||
|
||||
public void setSubHeader(FileHeader hd) {
|
||||
subHead = hd;
|
||||
|
||||
}
|
||||
|
||||
public long getCurPackRead() {
|
||||
return curPackRead;
|
||||
}
|
||||
|
||||
public void setCurPackRead(long curPackRead) {
|
||||
this.curPackRead = curPackRead;
|
||||
}
|
||||
|
||||
public long getCurPackWrite() {
|
||||
return curPackWrite;
|
||||
}
|
||||
|
||||
public void setCurPackWrite(long curPackWrite) {
|
||||
this.curPackWrite = curPackWrite;
|
||||
}
|
||||
|
||||
public long getCurUnpRead() {
|
||||
return curUnpRead;
|
||||
}
|
||||
|
||||
public void setCurUnpRead(long curUnpRead) {
|
||||
this.curUnpRead = curUnpRead;
|
||||
}
|
||||
|
||||
public long getCurUnpWrite() {
|
||||
return curUnpWrite;
|
||||
}
|
||||
|
||||
public void setCurUnpWrite(long curUnpWrite) {
|
||||
this.curUnpWrite = curUnpWrite;
|
||||
}
|
||||
|
||||
public int getDecryption() {
|
||||
return decryption;
|
||||
}
|
||||
|
||||
public void setDecryption(int decryption) {
|
||||
this.decryption = decryption;
|
||||
}
|
||||
|
||||
public int getEncryption() {
|
||||
return encryption;
|
||||
}
|
||||
|
||||
public void setEncryption(int encryption) {
|
||||
this.encryption = encryption;
|
||||
}
|
||||
|
||||
public boolean isNextVolumeMissing() {
|
||||
return nextVolumeMissing;
|
||||
}
|
||||
|
||||
public void setNextVolumeMissing(boolean nextVolumeMissing) {
|
||||
this.nextVolumeMissing = nextVolumeMissing;
|
||||
}
|
||||
|
||||
public long getPackedCRC() {
|
||||
return packedCRC;
|
||||
}
|
||||
|
||||
public void setPackedCRC(long packedCRC) {
|
||||
this.packedCRC = packedCRC;
|
||||
}
|
||||
|
||||
public long getPackFileCRC() {
|
||||
return packFileCRC;
|
||||
}
|
||||
|
||||
public void setPackFileCRC(long packFileCRC) {
|
||||
this.packFileCRC = packFileCRC;
|
||||
}
|
||||
|
||||
public boolean isPackVolume() {
|
||||
return packVolume;
|
||||
}
|
||||
|
||||
public void setPackVolume(boolean packVolume) {
|
||||
this.packVolume = packVolume;
|
||||
}
|
||||
|
||||
public long getProcessedArcSize() {
|
||||
return processedArcSize;
|
||||
}
|
||||
|
||||
public void setProcessedArcSize(long processedArcSize) {
|
||||
this.processedArcSize = processedArcSize;
|
||||
}
|
||||
|
||||
public long getTotalArcSize() {
|
||||
return totalArcSize;
|
||||
}
|
||||
|
||||
public void setTotalArcSize(long totalArcSize) {
|
||||
this.totalArcSize = totalArcSize;
|
||||
}
|
||||
|
||||
public long getTotalPackRead() {
|
||||
return totalPackRead;
|
||||
}
|
||||
|
||||
public void setTotalPackRead(long totalPackRead) {
|
||||
this.totalPackRead = totalPackRead;
|
||||
}
|
||||
|
||||
public long getUnpArcSize() {
|
||||
return unpArcSize;
|
||||
}
|
||||
|
||||
public void setUnpArcSize(long unpArcSize) {
|
||||
this.unpArcSize = unpArcSize;
|
||||
}
|
||||
|
||||
public long getUnpFileCRC() {
|
||||
return unpFileCRC;
|
||||
}
|
||||
|
||||
public void setUnpFileCRC(long unpFileCRC) {
|
||||
this.unpFileCRC = unpFileCRC;
|
||||
}
|
||||
|
||||
public boolean isUnpVolume() {
|
||||
return unpVolume;
|
||||
}
|
||||
|
||||
public void setUnpVolume(boolean unpVolume) {
|
||||
this.unpVolume = unpVolume;
|
||||
}
|
||||
|
||||
public FileHeader getSubHeader() {
|
||||
return subHead;
|
||||
}
|
||||
|
||||
// public void setEncryption(int method, char[] Password, byte[] Salt,
|
||||
// boolean encrypt, boolean handsOffHash)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void setAV15Encryption()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void setCmt13Encryption()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
}
|
1047
junrar/src/main/java/junrar/unpack/Unpack.java
Normal file
1047
junrar/src/main/java/junrar/unpack/Unpack.java
Normal file
File diff suppressed because it is too large
Load Diff
620
junrar/src/main/java/junrar/unpack/Unpack15.java
Normal file
620
junrar/src/main/java/junrar/unpack/Unpack15.java
Normal file
@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 21.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junrar.exception.RarException;
|
||||
import junrar.unpack.decode.Compress;
|
||||
import junrar.unpack.vm.BitInput;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public abstract class Unpack15 extends BitInput
|
||||
{
|
||||
|
||||
protected int readBorder;
|
||||
|
||||
protected boolean suspended;
|
||||
|
||||
protected boolean unpAllBuf;
|
||||
|
||||
protected ComprDataIO unpIO;
|
||||
|
||||
protected boolean unpSomeRead;
|
||||
|
||||
protected int readTop;
|
||||
|
||||
protected long destUnpSize;
|
||||
|
||||
protected byte[] window;
|
||||
|
||||
protected int[] oldDist = new int[4];
|
||||
|
||||
protected int unpPtr, wrPtr;
|
||||
|
||||
protected int oldDistPtr;
|
||||
|
||||
protected int[] ChSet = new int[256], ChSetA = new int[256],
|
||||
ChSetB = new int[256], ChSetC = new int[256];
|
||||
|
||||
protected int[] Place = new int[256], PlaceA = new int[256],
|
||||
PlaceB = new int[256], PlaceC = new int[256];
|
||||
|
||||
protected int[] NToPl = new int[256], NToPlB = new int[256],
|
||||
NToPlC = new int[256];
|
||||
|
||||
protected int FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
|
||||
|
||||
protected int Buf60, NumHuf, StMode, LCount, FlagsCnt;
|
||||
|
||||
protected int Nhfb, Nlzb, MaxDist3;
|
||||
|
||||
protected int lastDist, lastLength;
|
||||
|
||||
private static final int STARTL1 = 2;
|
||||
|
||||
private static int DecL1[] = { 0x8000, 0xa000, 0xc000, 0xd000, 0xe000,
|
||||
0xea00, 0xee00, 0xf000, 0xf200, 0xf200, 0xffff };
|
||||
|
||||
private static int PosL1[] = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };
|
||||
|
||||
private static final int STARTL2 = 3;
|
||||
|
||||
private static int DecL2[] = { 0xa000, 0xc000, 0xd000, 0xe000, 0xea00,
|
||||
0xee00, 0xf000, 0xf200, 0xf240, 0xffff };
|
||||
|
||||
private static int PosL2[] = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };
|
||||
|
||||
private static final int STARTHF0 = 4;
|
||||
|
||||
private static int DecHf0[] = { 0x8000, 0xc000, 0xe000, 0xf200, 0xf200,
|
||||
0xf200, 0xf200, 0xf200, 0xffff };
|
||||
|
||||
private static int PosHf0[] = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33,
|
||||
33 };
|
||||
|
||||
private static final int STARTHF1 = 5;
|
||||
|
||||
private static int DecHf1[] = { 0x2000, 0xc000, 0xe000, 0xf000, 0xf200,
|
||||
0xf200, 0xf7e0, 0xffff };
|
||||
|
||||
private static int PosHf1[] = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80,
|
||||
127 };
|
||||
|
||||
private static final int STARTHF2 = 5;
|
||||
|
||||
private static int DecHf2[] = { 0x1000, 0x2400, 0x8000, 0xc000, 0xfa00,
|
||||
0xffff, 0xffff, 0xffff };
|
||||
|
||||
private static int PosHf2[] = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };
|
||||
|
||||
private static final int STARTHF3 = 6;
|
||||
|
||||
private static int DecHf3[] = { 0x800, 0x2400, 0xee00, 0xfe80, 0xffff,
|
||||
0xffff, 0xffff };
|
||||
|
||||
private static int PosHf3[] = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };
|
||||
|
||||
private static final int STARTHF4 = 8;
|
||||
|
||||
private static int DecHf4[] = { 0xff00, 0xffff, 0xffff, 0xffff, 0xffff,
|
||||
0xffff };
|
||||
|
||||
private static int PosHf4[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0 };
|
||||
|
||||
static int ShortLen1[] = { 1, 3, 4, 4, 5, 6, 7, 8, 8, 4, 4, 5, 6, 6, 4, 0 };
|
||||
|
||||
static int ShortXor1[] = { 0, 0xa0, 0xd0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe,
|
||||
0xff, 0xc0, 0x80, 0x90, 0x98, 0x9c, 0xb0 };
|
||||
|
||||
static int ShortLen2[] = { 2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0 };
|
||||
|
||||
static int ShortXor2[] = { 0, 0x40, 0x60, 0xa0, 0xd0, 0xe0, 0xf0, 0xf8,
|
||||
0xfc, 0xc0, 0x80, 0x90, 0x98, 0x9c, 0xb0 };
|
||||
|
||||
protected abstract void unpInitData(boolean solid);
|
||||
|
||||
protected void unpack15(boolean solid) throws IOException, RarException
|
||||
{
|
||||
if (suspended) {
|
||||
unpPtr = wrPtr;
|
||||
} else {
|
||||
unpInitData(solid);
|
||||
oldUnpInitData(solid);
|
||||
unpReadBuf();
|
||||
if (!solid) {
|
||||
initHuff();
|
||||
unpPtr = 0;
|
||||
} else {
|
||||
unpPtr = wrPtr;
|
||||
}
|
||||
--destUnpSize;
|
||||
}
|
||||
if (destUnpSize >= 0) {
|
||||
getFlagsBuf();
|
||||
FlagsCnt = 8;
|
||||
}
|
||||
|
||||
while (destUnpSize >= 0) {
|
||||
unpPtr &= Compress.MAXWINMASK;
|
||||
|
||||
if (inAddr > readTop - 30 && !unpReadBuf()) {
|
||||
break;
|
||||
}
|
||||
if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270
|
||||
&& wrPtr != unpPtr) {
|
||||
oldUnpWriteBuf();
|
||||
if (suspended) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (StMode != 0) {
|
||||
huffDecode();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (--FlagsCnt < 0) {
|
||||
getFlagsBuf();
|
||||
FlagsCnt = 7;
|
||||
}
|
||||
|
||||
if ((FlagBuf & 0x80) != 0) {
|
||||
FlagBuf <<= 1;
|
||||
if (Nlzb > Nhfb) {
|
||||
longLZ();
|
||||
} else {
|
||||
huffDecode();
|
||||
}
|
||||
} else {
|
||||
FlagBuf <<= 1;
|
||||
if (--FlagsCnt < 0) {
|
||||
getFlagsBuf();
|
||||
FlagsCnt = 7;
|
||||
}
|
||||
if ((FlagBuf & 0x80) != 0) {
|
||||
FlagBuf <<= 1;
|
||||
if (Nlzb > Nhfb) {
|
||||
huffDecode();
|
||||
} else {
|
||||
longLZ();
|
||||
}
|
||||
} else {
|
||||
FlagBuf <<= 1;
|
||||
shortLZ();
|
||||
}
|
||||
}
|
||||
}
|
||||
oldUnpWriteBuf();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected boolean unpReadBuf() throws IOException, RarException
|
||||
{
|
||||
int dataSize=readTop-inAddr;
|
||||
if (dataSize<0){
|
||||
return(false);
|
||||
}
|
||||
if (inAddr>BitInput.MAX_SIZE/2) {
|
||||
if (dataSize>0){
|
||||
//memmove(InBuf,InBuf+InAddr,DataSize);
|
||||
// for (int i = 0; i < dataSize; i++) {
|
||||
// inBuf[i] = inBuf[inAddr + i];
|
||||
// }
|
||||
System.arraycopy(inBuf, inAddr, inBuf, 0, dataSize);
|
||||
}
|
||||
inAddr=0;
|
||||
readTop=dataSize;
|
||||
}
|
||||
else{
|
||||
dataSize=readTop;
|
||||
}
|
||||
//int readCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
|
||||
int readCode=unpIO.unpRead(inBuf, dataSize, (BitInput.MAX_SIZE-dataSize)&~0xf);
|
||||
if (readCode>0){
|
||||
readTop+=readCode;
|
||||
}
|
||||
readBorder=readTop-30;
|
||||
return(readCode!=-1);
|
||||
}
|
||||
|
||||
private int getShortLen1(int pos)
|
||||
{
|
||||
return pos == 1 ? Buf60 + 3 : ShortLen1[pos];
|
||||
}
|
||||
|
||||
private int getShortLen2(int pos)
|
||||
{
|
||||
return pos == 3 ? Buf60 + 3 : ShortLen2[pos];
|
||||
}
|
||||
|
||||
protected void shortLZ()
|
||||
{
|
||||
int Length, SaveLength;
|
||||
int LastDistance;
|
||||
int Distance;
|
||||
int DistancePlace;
|
||||
NumHuf = 0;
|
||||
|
||||
int BitField = fgetbits();
|
||||
if (LCount == 2) {
|
||||
faddbits(1);
|
||||
if (BitField >= 0x8000) {
|
||||
oldCopyString(lastDist, lastLength);
|
||||
return;
|
||||
}
|
||||
BitField <<= 1;
|
||||
LCount = 0;
|
||||
}
|
||||
BitField >>>= 8;
|
||||
if (AvrLn1 < 37) {
|
||||
for (Length = 0;; Length++) {
|
||||
if (((BitField ^ ShortXor1[Length]) & (~(0xff >>> getShortLen1(Length)))) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
faddbits(getShortLen1(Length));
|
||||
} else {
|
||||
for (Length = 0;; Length++) {
|
||||
if (((BitField ^ ShortXor2[Length]) & (~(0xff >> getShortLen2(Length)))) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
faddbits(getShortLen2(Length));
|
||||
}
|
||||
|
||||
if (Length >= 9) {
|
||||
if (Length == 9) {
|
||||
LCount++;
|
||||
oldCopyString(lastDist, lastLength);
|
||||
return;
|
||||
}
|
||||
if (Length == 14) {
|
||||
LCount = 0;
|
||||
Length = decodeNum(fgetbits(), STARTL2, DecL2, PosL2) + 5;
|
||||
Distance = (fgetbits() >> 1) | 0x8000;
|
||||
faddbits(15);
|
||||
lastLength = Length;
|
||||
lastDist = Distance;
|
||||
oldCopyString(Distance, Length);
|
||||
return;
|
||||
}
|
||||
|
||||
LCount = 0;
|
||||
SaveLength = Length;
|
||||
Distance = oldDist[(oldDistPtr - (Length - 9)) & 3];
|
||||
Length = decodeNum(fgetbits(), STARTL1, DecL1, PosL1) + 2;
|
||||
if (Length == 0x101 && SaveLength == 10) {
|
||||
Buf60 ^= 1;
|
||||
return;
|
||||
}
|
||||
if (Distance > 256)
|
||||
Length++;
|
||||
if (Distance >= MaxDist3)
|
||||
Length++;
|
||||
|
||||
oldDist[oldDistPtr++] = Distance;
|
||||
oldDistPtr = oldDistPtr & 3;
|
||||
lastLength = Length;
|
||||
lastDist = Distance;
|
||||
oldCopyString(Distance, Length);
|
||||
return;
|
||||
}
|
||||
|
||||
LCount = 0;
|
||||
AvrLn1 += Length;
|
||||
AvrLn1 -= AvrLn1 >> 4;
|
||||
|
||||
DistancePlace = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2) & 0xff;
|
||||
Distance = ChSetA[DistancePlace];
|
||||
if (--DistancePlace != -1) {
|
||||
PlaceA[Distance]--;
|
||||
LastDistance = ChSetA[DistancePlace];
|
||||
PlaceA[LastDistance]++;
|
||||
ChSetA[DistancePlace + 1] = LastDistance;
|
||||
ChSetA[DistancePlace] = Distance;
|
||||
}
|
||||
Length += 2;
|
||||
oldDist[oldDistPtr++] = ++Distance;
|
||||
oldDistPtr = oldDistPtr & 3;
|
||||
lastLength = Length;
|
||||
lastDist = Distance;
|
||||
oldCopyString(Distance, Length);
|
||||
}
|
||||
|
||||
protected void longLZ()
|
||||
{
|
||||
int Length;
|
||||
int Distance;
|
||||
int DistancePlace, NewDistancePlace;
|
||||
int OldAvr2, OldAvr3;
|
||||
|
||||
NumHuf = 0;
|
||||
Nlzb += 16;
|
||||
if (Nlzb > 0xff) {
|
||||
Nlzb = 0x90;
|
||||
Nhfb >>>= 1;
|
||||
}
|
||||
OldAvr2 = AvrLn2;
|
||||
|
||||
int BitField = fgetbits();
|
||||
if (AvrLn2 >= 122) {
|
||||
Length = decodeNum(BitField, STARTL2, DecL2, PosL2);
|
||||
} else {
|
||||
if (AvrLn2 >= 64) {
|
||||
Length = decodeNum(BitField, STARTL1, DecL1, PosL1);
|
||||
} else {
|
||||
if (BitField < 0x100) {
|
||||
Length = BitField;
|
||||
faddbits(16);
|
||||
} else {
|
||||
for (Length = 0; ((BitField << Length) & 0x8000) == 0; Length++) {
|
||||
;
|
||||
}
|
||||
faddbits(Length + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
AvrLn2 += Length;
|
||||
AvrLn2 -= AvrLn2 >>> 5;
|
||||
|
||||
BitField = fgetbits();
|
||||
if (AvrPlcB > 0x28ff) {
|
||||
DistancePlace = decodeNum(BitField, STARTHF2, DecHf2, PosHf2);
|
||||
} else {
|
||||
if (AvrPlcB > 0x6ff) {
|
||||
DistancePlace = decodeNum(BitField, STARTHF1, DecHf1, PosHf1);
|
||||
} else {
|
||||
DistancePlace = decodeNum(BitField, STARTHF0, DecHf0, PosHf0);
|
||||
}
|
||||
}
|
||||
AvrPlcB += DistancePlace;
|
||||
AvrPlcB -= AvrPlcB >> 8;
|
||||
while (true) {
|
||||
Distance = ChSetB[DistancePlace & 0xff];
|
||||
NewDistancePlace = NToPlB[Distance++ & 0xff]++;
|
||||
if ((Distance & 0xff) == 0) {
|
||||
corrHuff(ChSetB, NToPlB);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChSetB[DistancePlace] = ChSetB[NewDistancePlace];
|
||||
ChSetB[NewDistancePlace] = Distance;
|
||||
|
||||
Distance = ((Distance & 0xff00) | (fgetbits() >>> 8)) >>> 1;
|
||||
faddbits(7);
|
||||
|
||||
OldAvr3 = AvrLn3;
|
||||
if (Length != 1 && Length != 4) {
|
||||
if (Length == 0 && Distance <= MaxDist3) {
|
||||
AvrLn3++;
|
||||
AvrLn3 -= AvrLn3 >> 8;
|
||||
} else {
|
||||
if (AvrLn3 > 0) {
|
||||
AvrLn3--;
|
||||
}
|
||||
}
|
||||
}
|
||||
Length += 3;
|
||||
if (Distance >= MaxDist3) {
|
||||
Length++;
|
||||
}
|
||||
if (Distance <= 256) {
|
||||
Length += 8;
|
||||
}
|
||||
if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40) {
|
||||
MaxDist3 = 0x7f00;
|
||||
} else {
|
||||
MaxDist3 = 0x2001;
|
||||
}
|
||||
oldDist[oldDistPtr++] = Distance;
|
||||
oldDistPtr = oldDistPtr & 3;
|
||||
lastLength = Length;
|
||||
lastDist = Distance;
|
||||
oldCopyString(Distance, Length);
|
||||
}
|
||||
|
||||
protected void huffDecode()
|
||||
{
|
||||
int CurByte, NewBytePlace;
|
||||
int Length;
|
||||
int Distance;
|
||||
int BytePlace;
|
||||
|
||||
int BitField = fgetbits();
|
||||
|
||||
if (AvrPlc > 0x75ff) {
|
||||
BytePlace = decodeNum(BitField, STARTHF4, DecHf4, PosHf4);
|
||||
} else {
|
||||
if (AvrPlc > 0x5dff) {
|
||||
BytePlace = decodeNum(BitField, STARTHF3, DecHf3, PosHf3);
|
||||
} else {
|
||||
if (AvrPlc > 0x35ff) {
|
||||
BytePlace = decodeNum(BitField, STARTHF2, DecHf2, PosHf2);
|
||||
} else {
|
||||
if (AvrPlc > 0x0dff) {
|
||||
BytePlace = decodeNum(BitField, STARTHF1, DecHf1,
|
||||
PosHf1);
|
||||
} else {
|
||||
BytePlace = decodeNum(BitField, STARTHF0, DecHf0,
|
||||
PosHf0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BytePlace &= 0xff;
|
||||
if (StMode != 0) {
|
||||
if (BytePlace == 0 && BitField > 0xfff) {
|
||||
BytePlace = 0x100;
|
||||
}
|
||||
if (--BytePlace == -1) {
|
||||
BitField = fgetbits();
|
||||
faddbits(1);
|
||||
if ((BitField & 0x8000) != 0) {
|
||||
NumHuf = StMode = 0;
|
||||
return;
|
||||
} else {
|
||||
Length = (BitField & 0x4000) != 0 ? 4 : 3;
|
||||
faddbits(1);
|
||||
Distance = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2);
|
||||
Distance = (Distance << 5) | (fgetbits() >>> 11);
|
||||
faddbits(5);
|
||||
oldCopyString(Distance, Length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (NumHuf++ >= 16 && FlagsCnt == 0) {
|
||||
StMode = 1;
|
||||
}
|
||||
}
|
||||
AvrPlc += BytePlace;
|
||||
AvrPlc -= AvrPlc >>> 8;
|
||||
Nhfb += 16;
|
||||
if (Nhfb > 0xff) {
|
||||
Nhfb = 0x90;
|
||||
Nlzb >>>= 1;
|
||||
}
|
||||
|
||||
window[unpPtr++] = (byte) (ChSet[BytePlace] >>> 8);
|
||||
--destUnpSize;
|
||||
|
||||
while (true) {
|
||||
CurByte = ChSet[BytePlace];
|
||||
NewBytePlace = NToPl[CurByte++ & 0xff]++;
|
||||
if ((CurByte & 0xff) > 0xa1) {
|
||||
corrHuff(ChSet, NToPl);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChSet[BytePlace] = ChSet[NewBytePlace];
|
||||
ChSet[NewBytePlace] = CurByte;
|
||||
}
|
||||
|
||||
protected void getFlagsBuf()
|
||||
{
|
||||
int Flags, NewFlagsPlace;
|
||||
int FlagsPlace = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2);
|
||||
|
||||
while (true) {
|
||||
Flags = ChSetC[FlagsPlace];
|
||||
FlagBuf = Flags >>> 8;
|
||||
NewFlagsPlace = NToPlC[Flags++ & 0xff]++;
|
||||
if ((Flags & 0xff) != 0) {
|
||||
break;
|
||||
}
|
||||
corrHuff(ChSetC, NToPlC);
|
||||
}
|
||||
|
||||
ChSetC[FlagsPlace] = ChSetC[NewFlagsPlace];
|
||||
ChSetC[NewFlagsPlace] = Flags;
|
||||
}
|
||||
|
||||
protected void oldUnpInitData(boolean Solid)
|
||||
{
|
||||
if (!Solid ) {
|
||||
AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
|
||||
AvrPlc = 0x3500;
|
||||
MaxDist3 = 0x2001;
|
||||
Nhfb = Nlzb = 0x80;
|
||||
}
|
||||
FlagsCnt = 0;
|
||||
FlagBuf = 0;
|
||||
StMode = 0;
|
||||
LCount = 0;
|
||||
readTop = 0;
|
||||
}
|
||||
|
||||
protected void initHuff()
|
||||
{
|
||||
for (int I = 0; I < 256; I++) {
|
||||
Place[I] = PlaceA[I] = PlaceB[I] = I;
|
||||
PlaceC[I] = (~I + 1) & 0xff;
|
||||
ChSet[I] = ChSetB[I] = I << 8;
|
||||
ChSetA[I] = I;
|
||||
ChSetC[I] = ((~I + 1) & 0xff) << 8;
|
||||
}
|
||||
|
||||
Arrays.fill(NToPl, 0);// memset(NToPl,0,sizeof(NToPl));
|
||||
Arrays.fill(NToPlB, 0); // memset(NToPlB,0,sizeof(NToPlB));
|
||||
Arrays.fill(NToPlC, 0); // memset(NToPlC,0,sizeof(NToPlC));
|
||||
corrHuff(ChSetB, NToPlB);
|
||||
}
|
||||
|
||||
protected void corrHuff(int[] CharSet, int[] NumToPlace)
|
||||
{
|
||||
int I, J, pos = 0;
|
||||
for (I = 7; I >= 0; I--) {
|
||||
for (J = 0; J < 32; J++, pos++) {
|
||||
CharSet[pos] = ((CharSet[pos] & ~0xff) | I);// *CharSet=(*CharSet
|
||||
// & ~0xff) | I;
|
||||
}
|
||||
}
|
||||
Arrays.fill(NumToPlace, 0);// memset(NumToPlace,0,sizeof(NToPl));
|
||||
for (I = 6; I >= 0; I--) {
|
||||
NumToPlace[I] = (7 - I) * 32;
|
||||
}
|
||||
}
|
||||
|
||||
protected void oldCopyString(int Distance, int Length)
|
||||
{
|
||||
destUnpSize -= Length;
|
||||
while ((Length--) != 0) {
|
||||
window[unpPtr] = window[(unpPtr - Distance) & Compress.MAXWINMASK];
|
||||
unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
|
||||
}
|
||||
}
|
||||
|
||||
protected int decodeNum(int Num, int StartPos, int[] DecTab, int[] PosTab)
|
||||
{
|
||||
int I;
|
||||
for (Num &= 0xfff0, I = 0; DecTab[I] <= Num; I++) {
|
||||
StartPos++;
|
||||
}
|
||||
faddbits(StartPos);
|
||||
return (((Num - (I != 0 ? DecTab[I - 1] : 0)) >>> (16 - StartPos)) + PosTab[StartPos]);
|
||||
}
|
||||
|
||||
protected void oldUnpWriteBuf() throws IOException
|
||||
{
|
||||
if (unpPtr != wrPtr) {
|
||||
unpSomeRead = true;
|
||||
}
|
||||
if (unpPtr < wrPtr) {
|
||||
unpIO.unpWrite(window, wrPtr, -wrPtr & Compress.MAXWINMASK);
|
||||
unpIO.unpWrite(window, 0, unpPtr);
|
||||
unpAllBuf = true;
|
||||
} else {
|
||||
unpIO.unpWrite(window, wrPtr, unpPtr - wrPtr);
|
||||
}
|
||||
wrPtr = unpPtr;
|
||||
}
|
||||
|
||||
|
||||
}
|
597
junrar/src/main/java/junrar/unpack/Unpack20.java
Normal file
597
junrar/src/main/java/junrar/unpack/Unpack20.java
Normal file
@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 21.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junrar.exception.RarException;
|
||||
import junrar.unpack.decode.AudioVariables;
|
||||
import junrar.unpack.decode.BitDecode;
|
||||
import junrar.unpack.decode.Compress;
|
||||
import junrar.unpack.decode.Decode;
|
||||
import junrar.unpack.decode.DistDecode;
|
||||
import junrar.unpack.decode.LitDecode;
|
||||
import junrar.unpack.decode.LowDistDecode;
|
||||
import junrar.unpack.decode.MultDecode;
|
||||
import junrar.unpack.decode.RepDecode;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public abstract class Unpack20 extends Unpack15
|
||||
{
|
||||
|
||||
protected MultDecode[] MD = new MultDecode[4];
|
||||
|
||||
protected byte[] UnpOldTable20 = new byte[Compress.MC20 * 4];
|
||||
|
||||
protected int UnpAudioBlock, UnpChannels, UnpCurChannel, UnpChannelDelta;
|
||||
|
||||
protected AudioVariables[] AudV = new AudioVariables[4];
|
||||
|
||||
protected LitDecode LD = new LitDecode();
|
||||
|
||||
protected DistDecode DD = new DistDecode();
|
||||
|
||||
protected LowDistDecode LDD = new LowDistDecode();
|
||||
|
||||
protected RepDecode RD = new RepDecode();
|
||||
|
||||
protected BitDecode BD = new BitDecode();
|
||||
|
||||
public static final int[] LDecode = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12,
|
||||
14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192,
|
||||
224 };
|
||||
|
||||
public static final byte[] LBits = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
|
||||
2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
|
||||
|
||||
public static final int[] DDecode = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32,
|
||||
48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072,
|
||||
4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304,
|
||||
131072, 196608, 262144, 327680, 393216, 458752, 524288, 589824,
|
||||
655360, 720896, 786432, 851968, 917504, 983040 };
|
||||
|
||||
public static final int[] DBits = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
|
||||
5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
||||
15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
|
||||
|
||||
public static final int[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
|
||||
|
||||
public static final int[] SDBits = { 2, 2, 3, 4, 5, 6, 6, 6 };
|
||||
|
||||
protected void unpack20(boolean solid) throws IOException, RarException
|
||||
{
|
||||
|
||||
int Bits;
|
||||
|
||||
if (suspended) {
|
||||
unpPtr = wrPtr;
|
||||
} else {
|
||||
unpInitData(solid);
|
||||
if (!unpReadBuf()) {
|
||||
return;
|
||||
}
|
||||
if (!solid) {
|
||||
if (!ReadTables20()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
--destUnpSize;
|
||||
}
|
||||
|
||||
while (destUnpSize >= 0) {
|
||||
unpPtr &= Compress.MAXWINMASK;
|
||||
|
||||
if (inAddr > readTop - 30)
|
||||
if (!unpReadBuf())
|
||||
break;
|
||||
if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270
|
||||
&& wrPtr != unpPtr) {
|
||||
oldUnpWriteBuf();
|
||||
if (suspended)
|
||||
return;
|
||||
}
|
||||
if (UnpAudioBlock != 0) {
|
||||
int AudioNumber = decodeNumber(MD[UnpCurChannel]);
|
||||
|
||||
if (AudioNumber == 256) {
|
||||
if (!ReadTables20())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
window[unpPtr++] = DecodeAudio(AudioNumber);
|
||||
if (++UnpCurChannel == UnpChannels)
|
||||
UnpCurChannel = 0;
|
||||
--destUnpSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
int Number = decodeNumber(LD);
|
||||
if (Number < 256) {
|
||||
window[unpPtr++] = (byte) Number;
|
||||
--destUnpSize;
|
||||
continue;
|
||||
}
|
||||
if (Number > 269) {
|
||||
int Length = LDecode[Number -= 270] + 3;
|
||||
if ((Bits = LBits[Number]) > 0) {
|
||||
Length += getbits() >>> (16 - Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
int DistNumber = decodeNumber(DD);
|
||||
int Distance = DDecode[DistNumber] + 1;
|
||||
if ((Bits = DBits[DistNumber]) > 0) {
|
||||
Distance += getbits() >>> (16 - Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
if (Distance >= 0x2000) {
|
||||
Length++;
|
||||
if (Distance >= 0x40000L)
|
||||
Length++;
|
||||
}
|
||||
|
||||
CopyString20(Length, Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number == 269) {
|
||||
if (!ReadTables20())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (Number == 256) {
|
||||
CopyString20(lastLength, lastDist);
|
||||
continue;
|
||||
}
|
||||
if (Number < 261) {
|
||||
int Distance = oldDist[(oldDistPtr - (Number - 256)) & 3];
|
||||
int LengthNumber = decodeNumber(RD);
|
||||
int Length = LDecode[LengthNumber] + 2;
|
||||
if ((Bits = LBits[LengthNumber]) > 0) {
|
||||
Length += getbits() >>> (16 - Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
if (Distance >= 0x101) {
|
||||
Length++;
|
||||
if (Distance >= 0x2000) {
|
||||
Length++;
|
||||
if (Distance >= 0x40000)
|
||||
Length++;
|
||||
}
|
||||
}
|
||||
CopyString20(Length, Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number < 270) {
|
||||
int Distance = SDDecode[Number -= 261] + 1;
|
||||
if ((Bits = SDBits[Number]) > 0) {
|
||||
Distance += getbits() >>> (16 - Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
CopyString20(2, Distance);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ReadLastTables();
|
||||
oldUnpWriteBuf();
|
||||
|
||||
}
|
||||
|
||||
protected void CopyString20(int Length, int Distance)
|
||||
{
|
||||
lastDist = oldDist[oldDistPtr++ & 3] = Distance;
|
||||
lastLength = Length;
|
||||
destUnpSize -= Length;
|
||||
|
||||
int DestPtr = unpPtr - Distance;
|
||||
if (DestPtr < Compress.MAXWINSIZE - 300
|
||||
&& unpPtr < Compress.MAXWINSIZE - 300) {
|
||||
window[unpPtr++] = window[DestPtr++];
|
||||
window[unpPtr++] = window[DestPtr++];
|
||||
while (Length > 2) {
|
||||
Length--;
|
||||
window[unpPtr++] = window[DestPtr++];
|
||||
}
|
||||
} else {
|
||||
while ((Length--) != 0) {
|
||||
window[unpPtr] = window[DestPtr++ & Compress.MAXWINMASK];
|
||||
unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void makeDecodeTables(byte[] lenTab, int offset, Decode dec,
|
||||
int size)
|
||||
{
|
||||
int[] lenCount = new int[16];
|
||||
int[] tmpPos = new int[16];
|
||||
int i;
|
||||
long M, N;
|
||||
|
||||
Arrays.fill(lenCount, 0);// memset(LenCount,0,sizeof(LenCount));
|
||||
|
||||
Arrays.fill(dec.getDecodeNum(), 0);// memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
lenCount[(int) (lenTab[offset + i] & 0xF)]++;
|
||||
}
|
||||
lenCount[0] = 0;
|
||||
for (tmpPos[0] = 0, dec.getDecodePos()[0] = 0, dec.getDecodeLen()[0] = 0, N = 0, i = 1; i < 16; i++) {
|
||||
N = 2 * (N + lenCount[i]);
|
||||
M = N << (15 - i);
|
||||
if (M > 0xFFFF) {
|
||||
M = 0xFFFF;
|
||||
}
|
||||
dec.getDecodeLen()[i] = (int) M;
|
||||
tmpPos[i] = dec.getDecodePos()[i] = dec.getDecodePos()[i - 1]
|
||||
+ lenCount[i - 1];
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (lenTab[offset + i] != 0) {
|
||||
dec.getDecodeNum()[tmpPos[lenTab[offset + i] & 0xF]++] = i;
|
||||
}
|
||||
}
|
||||
dec.setMaxNum(size);
|
||||
}
|
||||
|
||||
protected int decodeNumber(Decode dec)
|
||||
{
|
||||
int bits;
|
||||
long bitField = getbits() & 0xfffe;
|
||||
// if (bitField < dec.getDecodeLen()[8]) {
|
||||
// if (bitField < dec.getDecodeLen()[4]) {
|
||||
// if (bitField < dec.getDecodeLen()[2]) {
|
||||
// if (bitField < dec.getDecodeLen()[1]) {
|
||||
// bits = 1;
|
||||
// } else {
|
||||
// bits = 2;
|
||||
// }
|
||||
// } else {
|
||||
// if (bitField < dec.getDecodeLen()[3]) {
|
||||
// bits = 3;
|
||||
// } else {
|
||||
// bits = 4;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (bitField < dec.getDecodeLen()[6]) {
|
||||
// if (bitField < dec.getDecodeLen()[5])
|
||||
// bits = 5;
|
||||
// else
|
||||
// bits = 6;
|
||||
// } else {
|
||||
// if (bitField < dec.getDecodeLen()[7]) {
|
||||
// bits = 7;
|
||||
// } else {
|
||||
// bits = 8;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (bitField < dec.getDecodeLen()[12]) {
|
||||
// if (bitField < dec.getDecodeLen()[10])
|
||||
// if (bitField < dec.getDecodeLen()[9])
|
||||
// bits = 9;
|
||||
// else
|
||||
// bits = 10;
|
||||
// else if (bitField < dec.getDecodeLen()[11])
|
||||
// bits = 11;
|
||||
// else
|
||||
// bits = 12;
|
||||
// } else {
|
||||
// if (bitField < dec.getDecodeLen()[14]) {
|
||||
// if (bitField < dec.getDecodeLen()[13]) {
|
||||
// bits = 13;
|
||||
// } else {
|
||||
// bits = 14;
|
||||
// }
|
||||
// } else {
|
||||
// bits = 15;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// addbits(bits);
|
||||
// int N = dec.getDecodePos()[bits]
|
||||
// + (((int) bitField - dec.getDecodeLen()[bits - 1]) >>> (16 - bits));
|
||||
// if (N >= dec.getMaxNum()) {
|
||||
// N = 0;
|
||||
// }
|
||||
// return (dec.getDecodeNum()[N]);
|
||||
int[] decodeLen = dec.getDecodeLen();
|
||||
if (bitField < decodeLen[8]) {
|
||||
if (bitField < decodeLen[4]) {
|
||||
if (bitField < decodeLen[2]) {
|
||||
if (bitField < decodeLen[1]) {
|
||||
bits = 1;
|
||||
} else {
|
||||
bits = 2;
|
||||
}
|
||||
} else {
|
||||
if (bitField < decodeLen[3]) {
|
||||
bits = 3;
|
||||
} else {
|
||||
bits = 4;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bitField < decodeLen[6]) {
|
||||
if (bitField < decodeLen[5])
|
||||
bits = 5;
|
||||
else
|
||||
bits = 6;
|
||||
} else {
|
||||
if (bitField < decodeLen[7]) {
|
||||
bits = 7;
|
||||
} else {
|
||||
bits = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bitField < decodeLen[12]) {
|
||||
if (bitField < decodeLen[10])
|
||||
if (bitField < decodeLen[9])
|
||||
bits = 9;
|
||||
else
|
||||
bits = 10;
|
||||
else if (bitField < decodeLen[11])
|
||||
bits = 11;
|
||||
else
|
||||
bits = 12;
|
||||
} else {
|
||||
if (bitField < decodeLen[14]) {
|
||||
if (bitField < decodeLen[13]) {
|
||||
bits = 13;
|
||||
} else {
|
||||
bits = 14;
|
||||
}
|
||||
} else {
|
||||
bits = 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
addbits(bits);
|
||||
int N = dec.getDecodePos()[bits]
|
||||
+ (((int) bitField - decodeLen[bits - 1]) >>> (16 - bits));
|
||||
if (N >= dec.getMaxNum()) {
|
||||
N = 0;
|
||||
}
|
||||
return (dec.getDecodeNum()[N]);
|
||||
}
|
||||
|
||||
protected boolean ReadTables20() throws IOException, RarException
|
||||
{
|
||||
byte[] BitLength = new byte[Compress.BC20];
|
||||
byte[] Table = new byte[Compress.MC20 * 4];
|
||||
int TableSize, N, I;
|
||||
if (inAddr > readTop - 25) {
|
||||
if (!unpReadBuf()) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
int BitField = getbits();
|
||||
UnpAudioBlock = (BitField & 0x8000);
|
||||
|
||||
if (0 == (BitField & 0x4000)) {
|
||||
// memset(UnpOldTable20,0,sizeof(UnpOldTable20));
|
||||
Arrays.fill(UnpOldTable20, (byte) 0);
|
||||
}
|
||||
addbits(2);
|
||||
|
||||
if (UnpAudioBlock != 0) {
|
||||
UnpChannels = ((BitField >>> 12) & 3) + 1;
|
||||
if (UnpCurChannel >= UnpChannels) {
|
||||
UnpCurChannel = 0;
|
||||
}
|
||||
addbits(2);
|
||||
TableSize = Compress.MC20 * UnpChannels;
|
||||
} else {
|
||||
TableSize = Compress.NC20 + Compress.DC20 + Compress.RC20;
|
||||
}
|
||||
for (I = 0; I < Compress.BC20; I++) {
|
||||
BitLength[I] = (byte) (getbits() >>> 12);
|
||||
addbits(4);
|
||||
}
|
||||
makeDecodeTables(BitLength, 0, BD, Compress.BC20);
|
||||
I = 0;
|
||||
while (I < TableSize) {
|
||||
if (inAddr > readTop - 5) {
|
||||
if (!unpReadBuf()) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
int Number = decodeNumber(BD);
|
||||
if (Number < 16) {
|
||||
Table[I] = (byte) ((Number + UnpOldTable20[I]) & 0xf);
|
||||
I++;
|
||||
} else if (Number == 16) {
|
||||
N = (getbits() >>> 14) + 3;
|
||||
addbits(2);
|
||||
while (N-- > 0 && I < TableSize) {
|
||||
Table[I] = Table[I - 1];
|
||||
I++;
|
||||
}
|
||||
} else {
|
||||
if (Number == 17) {
|
||||
N = (getbits() >>> 13) + 3;
|
||||
addbits(3);
|
||||
} else {
|
||||
N = (getbits() >>> 9) + 11;
|
||||
addbits(7);
|
||||
}
|
||||
while (N-- > 0 && I < TableSize)
|
||||
Table[I++] = 0;
|
||||
}
|
||||
}
|
||||
if (inAddr > readTop) {
|
||||
return (true);
|
||||
}
|
||||
if (UnpAudioBlock != 0)
|
||||
for (I = 0; I < UnpChannels; I++)
|
||||
makeDecodeTables(Table, I * Compress.MC20, MD[I], Compress.MC20);
|
||||
else {
|
||||
makeDecodeTables(Table, 0, LD, Compress.NC20);
|
||||
makeDecodeTables(Table, Compress.NC20, DD, Compress.DC20);
|
||||
makeDecodeTables(Table, Compress.NC20 + Compress.DC20, RD,
|
||||
Compress.RC20);
|
||||
}
|
||||
// memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
|
||||
for (int i = 0; i < UnpOldTable20.length; i++) {
|
||||
UnpOldTable20[i] = Table[i];
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
protected void unpInitData20(boolean Solid)
|
||||
{
|
||||
if (!Solid) {
|
||||
UnpChannelDelta = UnpCurChannel = 0;
|
||||
UnpChannels = 1;
|
||||
// memset(AudV,0,sizeof(AudV));
|
||||
Arrays.fill(AudV, new AudioVariables());
|
||||
// memset(UnpOldTable20,0,sizeof(UnpOldTable20));
|
||||
Arrays.fill(UnpOldTable20, (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ReadLastTables() throws IOException, RarException
|
||||
{
|
||||
if (readTop >= inAddr + 5) {
|
||||
if (UnpAudioBlock != 0) {
|
||||
if (decodeNumber(MD[UnpCurChannel]) == 256) {
|
||||
ReadTables20();
|
||||
}
|
||||
} else {
|
||||
if (decodeNumber(LD) == 269) {
|
||||
ReadTables20();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected byte DecodeAudio(int Delta)
|
||||
{
|
||||
AudioVariables v = AudV[UnpCurChannel];
|
||||
v.setByteCount(v.getByteCount() + 1);
|
||||
v.setD4(v.getD3());
|
||||
v.setD3(v.getD2());// ->D3=V->D2;
|
||||
v.setD2(v.getLastDelta() - v.getD1());// ->D2=V->LastDelta-V->D1;
|
||||
v.setD1(v.getLastDelta());// V->D1=V->LastDelta;
|
||||
// int PCh=8*V->LastChar+V->K1*V->D1 +V->K2*V->D2 +V->K3*V->D3
|
||||
// +V->K4*V->D4+ V->K5*UnpChannelDelta;
|
||||
int PCh = 8 * v.getLastChar() + v.getK1() * v.getD1();
|
||||
PCh += v.getK2() * v.getD2() + v.getK3() * v.getD3();
|
||||
PCh += v.getK4() * v.getD4() + v.getK5() * UnpChannelDelta;
|
||||
PCh = (PCh >>> 3) & 0xFF;
|
||||
|
||||
int Ch = PCh - Delta;
|
||||
|
||||
int D = ((byte) Delta) << 3;
|
||||
|
||||
v.getDif()[0] += Math.abs(D);// V->Dif[0]+=abs(D);
|
||||
v.getDif()[1] += Math.abs(D - v.getD1());// V->Dif[1]+=abs(D-V->D1);
|
||||
v.getDif()[2] += Math.abs(D + v.getD1());// V->Dif[2]+=abs(D+V->D1);
|
||||
v.getDif()[3] += Math.abs(D - v.getD2());// V->Dif[3]+=abs(D-V->D2);
|
||||
v.getDif()[4] += Math.abs(D + v.getD2());// V->Dif[4]+=abs(D+V->D2);
|
||||
v.getDif()[5] += Math.abs(D - v.getD3());// V->Dif[5]+=abs(D-V->D3);
|
||||
v.getDif()[6] += Math.abs(D + v.getD3());// V->Dif[6]+=abs(D+V->D3);
|
||||
v.getDif()[7] += Math.abs(D - v.getD4());// V->Dif[7]+=abs(D-V->D4);
|
||||
v.getDif()[8] += Math.abs(D + v.getD4());// V->Dif[8]+=abs(D+V->D4);
|
||||
v.getDif()[9] += Math.abs(D - UnpChannelDelta);// V->Dif[9]+=abs(D-UnpChannelDelta);
|
||||
v.getDif()[10] += Math.abs(D + UnpChannelDelta);// V->Dif[10]+=abs(D+UnpChannelDelta);
|
||||
|
||||
v.setLastDelta((byte) (Ch - v.getLastChar()));
|
||||
UnpChannelDelta = v.getLastDelta();
|
||||
v.setLastChar(Ch);// V->LastChar=Ch;
|
||||
|
||||
if ((v.getByteCount() & 0x1F) == 0) {
|
||||
int MinDif = v.getDif()[0], NumMinDif = 0;
|
||||
v.getDif()[0] = 0;// ->Dif[0]=0;
|
||||
for (int I = 1; I < v.getDif().length; I++) {
|
||||
if (v.getDif()[I] < MinDif) {
|
||||
MinDif = v.getDif()[I];
|
||||
NumMinDif = I;
|
||||
}
|
||||
v.getDif()[I] = 0;
|
||||
}
|
||||
switch (NumMinDif) {
|
||||
case 1:
|
||||
if (v.getK1() >= -16) {
|
||||
v.setK1(v.getK1() - 1);// V->K1--;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (v.getK1() < 16) {
|
||||
v.setK1(v.getK1() + 1);// V->K1++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (v.getK2() >= -16) {
|
||||
v.setK2(v.getK2() - 1);// V->K2--;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (v.getK2() < 16) {
|
||||
v.setK2(v.getK2() + 1);// V->K2++;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (v.getK3() >= -16) {
|
||||
v.setK3(v.getK3() - 1);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (v.getK3() < 16) {
|
||||
v.setK3(v.getK3() + 1);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (v.getK4() >= -16) {
|
||||
v.setK4(v.getK4() - 1);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (v.getK4() < 16) {
|
||||
v.setK4(v.getK4() + 1);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (v.getK5() >= -16) {
|
||||
v.setK5(v.getK5() - 1);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (v.getK5() < 16) {
|
||||
v.setK5(v.getK5() + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ((byte) Ch);
|
||||
}
|
||||
|
||||
}
|
94
junrar/src/main/java/junrar/unpack/UnpackFilter.java
Normal file
94
junrar/src/main/java/junrar/unpack/UnpackFilter.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack;
|
||||
|
||||
import junrar.unpack.vm.VMPreparedProgram;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class UnpackFilter {
|
||||
|
||||
private int BlockStart;
|
||||
|
||||
private int BlockLength;
|
||||
|
||||
private int ExecCount;
|
||||
|
||||
private boolean NextWindow;
|
||||
|
||||
// position of parent filter in Filters array used as prototype for filter
|
||||
// in PrgStack array. Not defined for filters in Filters array.
|
||||
private int ParentFilter;
|
||||
|
||||
private VMPreparedProgram Prg = new VMPreparedProgram();
|
||||
|
||||
public int getBlockLength() {
|
||||
return BlockLength;
|
||||
}
|
||||
|
||||
public void setBlockLength(int blockLength) {
|
||||
BlockLength = blockLength;
|
||||
}
|
||||
|
||||
public int getBlockStart() {
|
||||
return BlockStart;
|
||||
}
|
||||
|
||||
public void setBlockStart(int blockStart) {
|
||||
BlockStart = blockStart;
|
||||
}
|
||||
|
||||
public int getExecCount() {
|
||||
return ExecCount;
|
||||
}
|
||||
|
||||
public void setExecCount(int execCount) {
|
||||
ExecCount = execCount;
|
||||
}
|
||||
|
||||
public boolean isNextWindow() {
|
||||
return NextWindow;
|
||||
}
|
||||
|
||||
public void setNextWindow(boolean nextWindow) {
|
||||
NextWindow = nextWindow;
|
||||
}
|
||||
|
||||
public int getParentFilter() {
|
||||
return ParentFilter;
|
||||
}
|
||||
|
||||
public void setParentFilter(int parentFilter) {
|
||||
ParentFilter = parentFilter;
|
||||
}
|
||||
|
||||
public VMPreparedProgram getPrg() {
|
||||
return Prg;
|
||||
}
|
||||
|
||||
public void setPrg(VMPreparedProgram prg) {
|
||||
Prg = prg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
144
junrar/src/main/java/junrar/unpack/decode/AudioVariables.java
Normal file
144
junrar/src/main/java/junrar/unpack/decode/AudioVariables.java
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class AudioVariables {
|
||||
int k1, k2, k3, k4, k5;
|
||||
|
||||
int d1, d2, d3, d4;
|
||||
|
||||
int lastDelta;
|
||||
|
||||
int dif[] = new int[11];
|
||||
|
||||
int byteCount;
|
||||
|
||||
int lastChar;
|
||||
|
||||
public int getByteCount() {
|
||||
return byteCount;
|
||||
}
|
||||
|
||||
public void setByteCount(int byteCount) {
|
||||
this.byteCount = byteCount;
|
||||
}
|
||||
|
||||
public int getD1() {
|
||||
return d1;
|
||||
}
|
||||
|
||||
public void setD1(int d1) {
|
||||
this.d1 = d1;
|
||||
}
|
||||
|
||||
public int getD2() {
|
||||
return d2;
|
||||
}
|
||||
|
||||
public void setD2(int d2) {
|
||||
this.d2 = d2;
|
||||
}
|
||||
|
||||
public int getD3() {
|
||||
return d3;
|
||||
}
|
||||
|
||||
public void setD3(int d3) {
|
||||
this.d3 = d3;
|
||||
}
|
||||
|
||||
public int getD4() {
|
||||
return d4;
|
||||
}
|
||||
|
||||
public void setD4(int d4) {
|
||||
this.d4 = d4;
|
||||
}
|
||||
|
||||
public int[] getDif() {
|
||||
return dif;
|
||||
}
|
||||
|
||||
public void setDif(int[] dif) {
|
||||
this.dif = dif;
|
||||
}
|
||||
|
||||
public int getK1() {
|
||||
return k1;
|
||||
}
|
||||
|
||||
public void setK1(int k1) {
|
||||
this.k1 = k1;
|
||||
}
|
||||
|
||||
public int getK2() {
|
||||
return k2;
|
||||
}
|
||||
|
||||
public void setK2(int k2) {
|
||||
this.k2 = k2;
|
||||
}
|
||||
|
||||
public int getK3() {
|
||||
return k3;
|
||||
}
|
||||
|
||||
public void setK3(int k3) {
|
||||
this.k3 = k3;
|
||||
}
|
||||
|
||||
public int getK4() {
|
||||
return k4;
|
||||
}
|
||||
|
||||
public void setK4(int k4) {
|
||||
this.k4 = k4;
|
||||
}
|
||||
|
||||
public int getK5() {
|
||||
return k5;
|
||||
}
|
||||
|
||||
public void setK5(int k5) {
|
||||
this.k5 = k5;
|
||||
}
|
||||
|
||||
public int getLastChar() {
|
||||
return lastChar;
|
||||
}
|
||||
|
||||
public void setLastChar(int lastChar) {
|
||||
this.lastChar = lastChar;
|
||||
}
|
||||
|
||||
public int getLastDelta() {
|
||||
return lastDelta;
|
||||
}
|
||||
|
||||
public void setLastDelta(int lastDelta) {
|
||||
this.lastDelta = lastDelta;
|
||||
}
|
||||
|
||||
|
||||
}
|
35
junrar/src/main/java/junrar/unpack/decode/BitDecode.java
Normal file
35
junrar/src/main/java/junrar/unpack/decode/BitDecode.java
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class BitDecode extends Decode
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public BitDecode()
|
||||
{
|
||||
decodeNum = new int[Compress.BC];
|
||||
}
|
||||
}
|
29
junrar/src/main/java/junrar/unpack/decode/CodeType.java
Normal file
29
junrar/src/main/java/junrar/unpack/decode/CodeType.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.2007
|
||||
*
|
||||
* Source: $HeadURL$
|
||||
* Last changed: $LastChangedDate$
|
||||
*
|
||||
* Here some html entities which can be used for escaping javadoc tags:
|
||||
* "&": "&" or "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum CodeType {
|
||||
CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,
|
||||
CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA;
|
||||
}
|
45
junrar/src/main/java/junrar/unpack/decode/Compress.java
Normal file
45
junrar/src/main/java/junrar/unpack/decode/Compress.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class Compress {
|
||||
public static final int CODEBUFSIZE = 0x4000;
|
||||
public static final int MAXWINSIZE = 0x400000;
|
||||
public static final int MAXWINMASK = (MAXWINSIZE-1);
|
||||
|
||||
public static final int LOW_DIST_REP_COUNT = 16;
|
||||
|
||||
public static final int NC = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public static final int DC = 60;
|
||||
public static final int LDC = 17;
|
||||
public static final int RC = 28;
|
||||
public static final int HUFF_TABLE_SIZE = (NC+DC+RC+LDC);
|
||||
public static final int BC = 20;
|
||||
|
||||
public static final int NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public static final int DC20 = 48;
|
||||
public static final int RC20 = 28;
|
||||
public static final int BC20 = 19;
|
||||
public static final int MC20 = 257;
|
||||
}
|
81
junrar/src/main/java/junrar/unpack/decode/Decode.java
Normal file
81
junrar/src/main/java/junrar/unpack/decode/Decode.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* Used to store information for lz decoding
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class Decode
|
||||
{
|
||||
private int maxNum;
|
||||
|
||||
private final int[] decodeLen = new int[16];
|
||||
|
||||
private final int[] decodePos = new int[16];
|
||||
|
||||
protected int[] decodeNum = new int[2];
|
||||
|
||||
/**
|
||||
* returns the decode Length array
|
||||
* @return decodeLength
|
||||
*/
|
||||
public int[] getDecodeLen()
|
||||
{
|
||||
return decodeLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the decode num array
|
||||
* @return decodeNum
|
||||
*/
|
||||
public int[] getDecodeNum()
|
||||
{
|
||||
return decodeNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the decodePos array
|
||||
* @return decodePos
|
||||
*/
|
||||
public int[] getDecodePos()
|
||||
{
|
||||
return decodePos;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the max num
|
||||
* @return maxNum
|
||||
*/
|
||||
public int getMaxNum()
|
||||
{
|
||||
return maxNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the max num
|
||||
* @param maxNum to be set to maxNum
|
||||
*/
|
||||
public void setMaxNum(int maxNum)
|
||||
{
|
||||
this.maxNum = maxNum;
|
||||
}
|
||||
|
||||
}
|
37
junrar/src/main/java/junrar/unpack/decode/DistDecode.java
Normal file
37
junrar/src/main/java/junrar/unpack/decode/DistDecode.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class DistDecode extends Decode
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public DistDecode()
|
||||
{
|
||||
decodeNum = new int[Compress.DC];
|
||||
}
|
||||
|
||||
}
|
30
junrar/src/main/java/junrar/unpack/decode/FilterType.java
Normal file
30
junrar/src/main/java/junrar/unpack/decode/FilterType.java
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum FilterType {
|
||||
FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,
|
||||
FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
|
||||
FILTER_ITANIUM, FILTER_E8E9V2;
|
||||
}
|
36
junrar/src/main/java/junrar/unpack/decode/LitDecode.java
Normal file
36
junrar/src/main/java/junrar/unpack/decode/LitDecode.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class LitDecode extends Decode
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public LitDecode()
|
||||
{
|
||||
decodeNum = new int[Compress.NC];
|
||||
}
|
||||
|
||||
}
|
37
junrar/src/main/java/junrar/unpack/decode/LowDistDecode.java
Normal file
37
junrar/src/main/java/junrar/unpack/decode/LowDistDecode.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class LowDistDecode extends Decode
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public LowDistDecode()
|
||||
{
|
||||
decodeNum = new int[Compress.LDC];
|
||||
}
|
||||
|
||||
}
|
37
junrar/src/main/java/junrar/unpack/decode/MultDecode.java
Normal file
37
junrar/src/main/java/junrar/unpack/decode/MultDecode.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class MultDecode extends Decode
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public MultDecode()
|
||||
{
|
||||
decodeNum = new int[Compress.MC20];
|
||||
}
|
||||
|
||||
}
|
36
junrar/src/main/java/junrar/unpack/decode/RepDecode.java
Normal file
36
junrar/src/main/java/junrar/unpack/decode/RepDecode.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.decode;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class RepDecode extends Decode
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public RepDecode()
|
||||
{
|
||||
decodeNum = new int[Compress.RC];
|
||||
}
|
||||
|
||||
}
|
94
junrar/src/main/java/junrar/unpack/ppm/AnalyzeHeapDump.java
Normal file
94
junrar/src/main/java/junrar/unpack/ppm/AnalyzeHeapDump.java
Normal file
@ -0,0 +1,94 @@
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* For debugging purposes only.
|
||||
*
|
||||
* @author alban
|
||||
*/
|
||||
public class AnalyzeHeapDump {
|
||||
|
||||
/** Creates a new instance of AnalyzeHeapDump */
|
||||
public AnalyzeHeapDump() {
|
||||
}
|
||||
|
||||
public static void main(String[] argv) {
|
||||
File cfile = new File("P:\\test\\heapdumpc");
|
||||
File jfile = new File("P:\\test\\heapdumpj");
|
||||
if (!cfile.exists()) {
|
||||
System.err.println("File not found: " + cfile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
if (!jfile.exists()) {
|
||||
System.err.println("File not found: " + jfile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
long clen = cfile.length();
|
||||
long jlen = jfile.length();
|
||||
if (clen != jlen) {
|
||||
System.out.println("File size mismatch");
|
||||
System.out.println("clen = " + clen);
|
||||
System.out.println("jlen = " + jlen);
|
||||
}
|
||||
// Do byte comparison
|
||||
long len = Math.min(clen, jlen);
|
||||
InputStream cin = null;
|
||||
InputStream jin = null;
|
||||
int bufferLen = 256*1024;
|
||||
try {
|
||||
cin = new BufferedInputStream(
|
||||
new FileInputStream(cfile), bufferLen);
|
||||
jin = new BufferedInputStream(
|
||||
new FileInputStream(jfile), bufferLen);
|
||||
boolean matching = true;
|
||||
boolean mismatchFound = false;
|
||||
long startOff = 0L;
|
||||
long off = 0L;
|
||||
while (off < len) {
|
||||
if (cin.read() != jin.read()) {
|
||||
if (matching) {
|
||||
startOff = off;
|
||||
matching = false;
|
||||
mismatchFound = true;
|
||||
}
|
||||
}
|
||||
else { // match
|
||||
if (!matching) {
|
||||
printMismatch(startOff, off);
|
||||
matching = true;
|
||||
}
|
||||
}
|
||||
off++;
|
||||
}
|
||||
if (!matching) {
|
||||
printMismatch(startOff, off);
|
||||
}
|
||||
if (!mismatchFound) {
|
||||
System.out.println("Files are identical");
|
||||
}
|
||||
System.out.println("Done");
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
cin.close();
|
||||
jin.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printMismatch(long startOff, long bytesRead) {
|
||||
System.out.println("Mismatch: off=" + startOff +
|
||||
"(0x" + Long.toHexString(startOff) +
|
||||
"), len=" + (bytesRead - startOff));
|
||||
}
|
||||
}
|
58
junrar/src/main/java/junrar/unpack/ppm/BlockTypes.java
Normal file
58
junrar/src/main/java/junrar/unpack/ppm/BlockTypes.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum BlockTypes
|
||||
{
|
||||
BLOCK_LZ(0), BLOCK_PPM(1);
|
||||
|
||||
private int blockType;
|
||||
|
||||
private BlockTypes(int blockType)
|
||||
{
|
||||
this.blockType = blockType;
|
||||
}
|
||||
|
||||
public int getBlockType()
|
||||
{
|
||||
return blockType;
|
||||
}
|
||||
|
||||
public boolean equals(int blockType)
|
||||
{
|
||||
return this.blockType == blockType;
|
||||
}
|
||||
|
||||
public static BlockTypes findBlockType(int blockType)
|
||||
{
|
||||
if (BLOCK_LZ.equals(blockType)) {
|
||||
return BLOCK_LZ;
|
||||
}
|
||||
if (BLOCK_PPM.equals(blockType)) {
|
||||
return BLOCK_PPM;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
87
junrar/src/main/java/junrar/unpack/ppm/FreqData.java
Normal file
87
junrar/src/main/java/junrar/unpack/ppm/FreqData.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 04.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class FreqData extends Pointer{
|
||||
|
||||
public static final int size = 6;
|
||||
|
||||
// struct FreqData
|
||||
// {
|
||||
// ushort SummFreq;
|
||||
// STATE _PACK_ATTR * Stats;
|
||||
// };
|
||||
|
||||
public FreqData(byte[]mem){
|
||||
super(mem);
|
||||
}
|
||||
|
||||
public FreqData init(byte[] mem) {
|
||||
this.mem = mem;
|
||||
pos = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSummFreq() {
|
||||
return Raw.readShortLittleEndian(mem, pos)&0xffff;
|
||||
}
|
||||
|
||||
public void setSummFreq(int summFreq) {
|
||||
Raw.writeShortLittleEndian(mem, pos, (short)summFreq);
|
||||
}
|
||||
|
||||
public void incSummFreq(int dSummFreq) {
|
||||
Raw.incShortLittleEndian(mem, pos, dSummFreq);
|
||||
}
|
||||
|
||||
public int getStats() {
|
||||
return Raw.readIntLittleEndian(mem, pos+2);
|
||||
}
|
||||
|
||||
public void setStats(State state) {
|
||||
setStats(state.getAddress());
|
||||
}
|
||||
|
||||
public void setStats(int state) {
|
||||
Raw.writeIntLittleEndian(mem, pos+2, state);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("FreqData[");
|
||||
buffer.append("\n pos=");
|
||||
buffer.append(pos);
|
||||
buffer.append("\n size=");
|
||||
buffer.append(size);
|
||||
buffer.append("\n summFreq=");
|
||||
buffer.append(getSummFreq());
|
||||
buffer.append("\n stats=");
|
||||
buffer.append(getStats());
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
698
junrar/src/main/java/junrar/unpack/ppm/ModelPPM.java
Normal file
698
junrar/src/main/java/junrar/unpack/ppm/ModelPPM.java
Normal file
@ -0,0 +1,698 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junrar.exception.RarException;
|
||||
import junrar.unpack.Unpack;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class ModelPPM
|
||||
{
|
||||
public static final int MAX_O = 64; /* maximum allowed model order */
|
||||
|
||||
public static final int INT_BITS = 7;
|
||||
|
||||
public static final int PERIOD_BITS = 7;
|
||||
|
||||
public static final int TOT_BITS = INT_BITS + PERIOD_BITS;
|
||||
|
||||
public static final int INTERVAL = 1 << INT_BITS;
|
||||
|
||||
public static final int BIN_SCALE = 1 << TOT_BITS;
|
||||
|
||||
public static final int MAX_FREQ = 124;
|
||||
|
||||
private SEE2Context[][] SEE2Cont = new SEE2Context[25][16];
|
||||
|
||||
private SEE2Context dummySEE2Cont;
|
||||
|
||||
private PPMContext minContext, maxContext;
|
||||
|
||||
private State foundState; // found next state transition
|
||||
|
||||
private int numMasked, initEsc, orderFall, maxOrder, runLength, initRL;
|
||||
|
||||
private int[] charMask = new int[256];
|
||||
|
||||
private int[] NS2Indx = new int[256];
|
||||
|
||||
private int[] NS2BSIndx = new int[256];
|
||||
|
||||
private int[] HB2Flag = new int[256];
|
||||
|
||||
// byte EscCount, PrevSuccess, HiBitsFlag;
|
||||
private int escCount, prevSuccess, hiBitsFlag;
|
||||
|
||||
private int[][] binSumm = new int[128][64]; // binary SEE-contexts
|
||||
|
||||
private RangeCoder coder = new RangeCoder();
|
||||
|
||||
private SubAllocator subAlloc = new SubAllocator();
|
||||
|
||||
private static int InitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3,
|
||||
0x64A1, 0x5ABC, 0x6632, 0x6051 };
|
||||
|
||||
// Temp fields
|
||||
private final State tempState1 = new State(null);
|
||||
private final State tempState2 = new State(null);
|
||||
private final State tempState3 = new State(null);
|
||||
private final State tempState4 = new State(null);
|
||||
private final StateRef tempStateRef1 = new StateRef();
|
||||
private final StateRef tempStateRef2 = new StateRef();
|
||||
private final PPMContext tempPPMContext1 = new PPMContext(null);
|
||||
private final PPMContext tempPPMContext2 = new PPMContext(null);
|
||||
private final PPMContext tempPPMContext3 = new PPMContext(null);
|
||||
private final PPMContext tempPPMContext4 = new PPMContext(null);
|
||||
private final int[] ps = new int[MAX_O];
|
||||
|
||||
public ModelPPM()
|
||||
{
|
||||
minContext = null;
|
||||
maxContext = null;
|
||||
}
|
||||
|
||||
public SubAllocator getSubAlloc()
|
||||
{
|
||||
return subAlloc;
|
||||
}
|
||||
|
||||
private void restartModelRare()
|
||||
{
|
||||
Arrays.fill(charMask, 0);
|
||||
subAlloc.initSubAllocator();
|
||||
initRL = -(maxOrder < 12 ? maxOrder : 12) - 1;
|
||||
int addr = subAlloc.allocContext();
|
||||
minContext.setAddress(addr);
|
||||
maxContext.setAddress(addr);
|
||||
minContext.setSuffix(0);
|
||||
orderFall = maxOrder;
|
||||
minContext.setNumStats(256);
|
||||
minContext.getFreqData().setSummFreq(minContext.getNumStats()+1);
|
||||
|
||||
addr = subAlloc.allocUnits(256 / 2);
|
||||
foundState.setAddress(addr);
|
||||
minContext.getFreqData().setStats(addr);
|
||||
|
||||
State state = new State(subAlloc.getHeap());
|
||||
addr = minContext.getFreqData().getStats();
|
||||
runLength = initRL;
|
||||
prevSuccess = 0;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
state.setAddress(addr + i * State.size);
|
||||
state.setSymbol(i);
|
||||
state.setFreq(1);
|
||||
state.setSuccessor(0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
for (int k = 0; k < 8; k++) {
|
||||
for (int m = 0; m < 64; m += 8) {
|
||||
binSumm[i][k + m] = BIN_SCALE - InitBinEsc[k] / (i + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 25; i++) {
|
||||
for (int k = 0; k < 16; k++) {
|
||||
SEE2Cont[i][k].init(5 * i + 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startModelRare(int MaxOrder)
|
||||
{
|
||||
int i, k, m, Step;
|
||||
escCount = 1;
|
||||
this.maxOrder = MaxOrder;
|
||||
restartModelRare();
|
||||
// Bug Fixed
|
||||
NS2BSIndx[0] = 0;
|
||||
NS2BSIndx[1] = 2;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
NS2BSIndx[2 + j] = 4;
|
||||
}
|
||||
for (int j = 0; j < 256 - 11; j++) {
|
||||
NS2BSIndx[11 + j] = 6;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
NS2Indx[i] = i;
|
||||
}
|
||||
for (m = i, k = 1, Step = 1; i < 256; i++) {
|
||||
NS2Indx[i] = m;
|
||||
if ((--k) == 0) {
|
||||
k = ++Step;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 0x40; j++) {
|
||||
HB2Flag[j] = 0;
|
||||
}
|
||||
for (int j = 0; j < 0x100 - 0x40; j++) {
|
||||
HB2Flag[0x40 + j] = 0x08;
|
||||
}
|
||||
dummySEE2Cont.setShift(PERIOD_BITS);
|
||||
|
||||
}
|
||||
|
||||
private void clearMask()
|
||||
{
|
||||
escCount = 1;
|
||||
Arrays.fill(charMask, 0);
|
||||
}
|
||||
|
||||
public boolean decodeInit(Unpack unpackRead, int escChar/* ref */)
|
||||
throws IOException, RarException
|
||||
{
|
||||
|
||||
int MaxOrder = unpackRead.getChar() & 0xff;
|
||||
boolean reset = ((MaxOrder & 0x20) != 0);
|
||||
|
||||
int MaxMB = 0;
|
||||
if (reset) {
|
||||
MaxMB = unpackRead.getChar();
|
||||
// Workaround: http://stackoverflow.com/questions/14109455/outofmemoryerror-when-i-decompress-rar-file-on-android
|
||||
if (MaxMB > 1) {
|
||||
MaxMB = 1;
|
||||
}
|
||||
} else {
|
||||
if (subAlloc.GetAllocatedMemory() == 0) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
if ((MaxOrder & 0x40) != 0) {
|
||||
escChar = unpackRead.getChar();
|
||||
unpackRead.setPpmEscChar(escChar);
|
||||
}
|
||||
coder.initDecoder(unpackRead);
|
||||
if (reset) {
|
||||
MaxOrder = (MaxOrder & 0x1f) + 1;
|
||||
if (MaxOrder > 16) {
|
||||
MaxOrder = 16 + (MaxOrder - 16) * 3;
|
||||
}
|
||||
if (MaxOrder == 1) {
|
||||
subAlloc.stopSubAllocator();
|
||||
return (false);
|
||||
}
|
||||
subAlloc.startSubAllocator(MaxMB + 1);
|
||||
minContext = new PPMContext(getHeap());
|
||||
maxContext = new PPMContext(getHeap());
|
||||
foundState = new State(getHeap());
|
||||
dummySEE2Cont = new SEE2Context();
|
||||
for (int i = 0; i < 25; i++) {
|
||||
for (int j = 0; j < 16; j++) {
|
||||
SEE2Cont[i][j] = new SEE2Context();
|
||||
}
|
||||
}
|
||||
startModelRare(MaxOrder);
|
||||
}
|
||||
return (minContext.getAddress() != 0);
|
||||
}
|
||||
|
||||
public int decodeChar() throws IOException, RarException
|
||||
{
|
||||
// Debug
|
||||
//subAlloc.dumpHeap();
|
||||
|
||||
if (minContext.getAddress() <= subAlloc.getPText()
|
||||
|| minContext.getAddress() > subAlloc.getHeapEnd()) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (minContext.getNumStats() != 1) {
|
||||
if (minContext.getFreqData().getStats() <= subAlloc.getPText()
|
||||
|| minContext.getFreqData().getStats() > subAlloc.getHeapEnd()) {
|
||||
return (-1);
|
||||
}
|
||||
if (!minContext.decodeSymbol1(this)) {
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
minContext.decodeBinSymbol(this);
|
||||
}
|
||||
coder.decode();
|
||||
while (foundState.getAddress() == 0) {
|
||||
coder.ariDecNormalize();
|
||||
do {
|
||||
orderFall++;
|
||||
minContext.setAddress(minContext.getSuffix());// =MinContext->Suffix;
|
||||
if (minContext.getAddress() <= subAlloc.getPText()
|
||||
|| minContext.getAddress() > subAlloc.getHeapEnd()) {
|
||||
return (-1);
|
||||
}
|
||||
} while (minContext.getNumStats() == numMasked);
|
||||
if (!minContext.decodeSymbol2(this)) {
|
||||
return (-1);
|
||||
}
|
||||
coder.decode();
|
||||
}
|
||||
int Symbol = foundState.getSymbol();
|
||||
if ((orderFall == 0) && foundState.getSuccessor() > subAlloc.getPText()) {
|
||||
// MinContext=MaxContext=FoundState->Successor;
|
||||
int addr = foundState.getSuccessor();
|
||||
minContext.setAddress(addr);
|
||||
maxContext.setAddress(addr);
|
||||
} else {
|
||||
updateModel();
|
||||
//this.foundState.setAddress(foundState.getAddress());//TODO just 4 debugging
|
||||
if (escCount == 0) {
|
||||
clearMask();
|
||||
}
|
||||
}
|
||||
coder.ariDecNormalize();// ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||
return (Symbol);
|
||||
}
|
||||
|
||||
public SEE2Context[][] getSEE2Cont()
|
||||
{
|
||||
return SEE2Cont;
|
||||
}
|
||||
|
||||
public SEE2Context getDummySEE2Cont()
|
||||
{
|
||||
return dummySEE2Cont;
|
||||
}
|
||||
|
||||
public int getInitRL()
|
||||
{
|
||||
return initRL;
|
||||
}
|
||||
|
||||
public void setEscCount(int escCount)
|
||||
{
|
||||
this.escCount = escCount&0xff;
|
||||
}
|
||||
|
||||
public int getEscCount()
|
||||
{
|
||||
return escCount;
|
||||
}
|
||||
|
||||
public void incEscCount(int dEscCount) {
|
||||
setEscCount(getEscCount() + dEscCount);
|
||||
}
|
||||
|
||||
public int[] getCharMask()
|
||||
{
|
||||
return charMask;
|
||||
}
|
||||
|
||||
public int getNumMasked()
|
||||
{
|
||||
return numMasked;
|
||||
}
|
||||
|
||||
public void setNumMasked(int numMasked)
|
||||
{
|
||||
this.numMasked = numMasked;
|
||||
}
|
||||
|
||||
public void setPrevSuccess(int prevSuccess)
|
||||
{
|
||||
this.prevSuccess = prevSuccess&0xff;
|
||||
}
|
||||
|
||||
public int getInitEsc()
|
||||
{
|
||||
return initEsc;
|
||||
}
|
||||
|
||||
public void setInitEsc(int initEsc)
|
||||
{
|
||||
this.initEsc = initEsc;
|
||||
}
|
||||
|
||||
public void setRunLength(int runLength)
|
||||
{
|
||||
this.runLength = runLength;
|
||||
}
|
||||
|
||||
public int getRunLength()
|
||||
{
|
||||
return runLength;
|
||||
}
|
||||
|
||||
public void incRunLength(int dRunLength) {
|
||||
setRunLength(getRunLength() + dRunLength);
|
||||
}
|
||||
|
||||
public int getPrevSuccess()
|
||||
{
|
||||
return prevSuccess;
|
||||
}
|
||||
|
||||
public int getHiBitsFlag()
|
||||
{
|
||||
return hiBitsFlag;
|
||||
}
|
||||
|
||||
public void setHiBitsFlag(int hiBitsFlag)
|
||||
{
|
||||
this.hiBitsFlag = hiBitsFlag&0xff;
|
||||
}
|
||||
|
||||
public int[][] getBinSumm()
|
||||
{
|
||||
return binSumm;
|
||||
}
|
||||
|
||||
public RangeCoder getCoder()
|
||||
{
|
||||
return coder;
|
||||
}
|
||||
|
||||
public int[] getHB2Flag()
|
||||
{
|
||||
return HB2Flag;
|
||||
}
|
||||
|
||||
public int[] getNS2BSIndx()
|
||||
{
|
||||
return NS2BSIndx;
|
||||
}
|
||||
|
||||
public int[] getNS2Indx()
|
||||
{
|
||||
return NS2Indx;
|
||||
}
|
||||
|
||||
public State getFoundState()
|
||||
{
|
||||
return foundState;
|
||||
}
|
||||
|
||||
public byte[] getHeap()
|
||||
{
|
||||
return subAlloc.getHeap();
|
||||
}
|
||||
|
||||
public int getOrderFall()
|
||||
{
|
||||
return orderFall;
|
||||
}
|
||||
|
||||
private int /* ppmcontext ptr */createSuccessors(boolean Skip,
|
||||
State p1 /* state ptr */) {
|
||||
//State upState = tempState1.init(null);
|
||||
StateRef upState = tempStateRef2;
|
||||
State tempState = tempState1.init(getHeap());
|
||||
|
||||
// PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
|
||||
PPMContext pc = tempPPMContext1.init(getHeap());
|
||||
pc.setAddress(minContext.getAddress());
|
||||
PPMContext upBranch = tempPPMContext2.init(getHeap());
|
||||
upBranch.setAddress(foundState.getSuccessor());
|
||||
|
||||
// STATE * p, * ps[MAX_O], ** pps=ps;
|
||||
State p = tempState2.init(getHeap());
|
||||
int pps = 0;
|
||||
|
||||
boolean noLoop = false;
|
||||
|
||||
if (!Skip) {
|
||||
ps[pps++] = foundState.getAddress();// *pps++ = FoundState;
|
||||
if (pc.getSuffix() == 0) {
|
||||
noLoop = true;
|
||||
}
|
||||
}
|
||||
if (!noLoop) {
|
||||
boolean loopEntry = false;
|
||||
if (p1.getAddress() != 0) {
|
||||
p.setAddress(p1.getAddress());
|
||||
pc.setAddress(pc.getSuffix());// =pc->Suffix;
|
||||
loopEntry = true;
|
||||
}
|
||||
do {
|
||||
if (!loopEntry) {
|
||||
pc.setAddress(pc.getSuffix());// pc=pc->Suffix;
|
||||
if (pc.getNumStats() != 1) {
|
||||
p.setAddress(pc.getFreqData().getStats());// p=pc->U.Stats
|
||||
if (p.getSymbol() != foundState.getSymbol()) {
|
||||
do {
|
||||
p.incAddress();
|
||||
} while (p.getSymbol() != foundState.getSymbol());
|
||||
}
|
||||
} else {
|
||||
p.setAddress(pc.getOneState().getAddress());// p=&(pc->OneState);
|
||||
}
|
||||
}// LOOP_ENTRY:
|
||||
loopEntry = false;
|
||||
if (p.getSuccessor() != upBranch.getAddress()) {
|
||||
pc.setAddress(p.getSuccessor());// =p->Successor;
|
||||
break;
|
||||
}
|
||||
ps[pps++] = p.getAddress();
|
||||
} while (pc.getSuffix() != 0);
|
||||
|
||||
} // NO_LOOP:
|
||||
if (pps == 0) {
|
||||
return pc.getAddress();
|
||||
}
|
||||
upState.setSymbol(getHeap()[upBranch.getAddress()]);// UpState.Symbol=*(byte*)
|
||||
// UpBranch;
|
||||
// UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
|
||||
upState.setSuccessor(upBranch.getAddress() + 1); //TODO check if +1 necessary
|
||||
if (pc.getNumStats() != 1) {
|
||||
if (pc.getAddress() <= subAlloc.getPText()) {
|
||||
return (0);
|
||||
}
|
||||
p.setAddress(pc.getFreqData().getStats());
|
||||
if (p.getSymbol() != upState.getSymbol()) {
|
||||
do {
|
||||
p.incAddress();
|
||||
} while (p.getSymbol() != upState.getSymbol());
|
||||
}
|
||||
int cf = p.getFreq() - 1;
|
||||
int s0 = pc.getFreqData().getSummFreq() - pc.getNumStats() - cf;
|
||||
// UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
|
||||
upState.setFreq(1 + ((2 * cf <= s0) ? (5 * cf > s0 ? 1 : 0) :
|
||||
((2 * cf + 3 * s0 - 1) / (2 * s0))));
|
||||
} else {
|
||||
upState.setFreq(pc.getOneState().getFreq());// UpState.Freq=pc->OneState.Freq;
|
||||
}
|
||||
do {
|
||||
// pc = pc->createChild(this,*--pps,UpState);
|
||||
tempState.setAddress(ps[--pps]);
|
||||
pc.setAddress(pc.createChild(this, tempState, upState));
|
||||
if (pc.getAddress() == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (pps != 0);
|
||||
return pc.getAddress();
|
||||
}
|
||||
|
||||
private void updateModelRestart()
|
||||
{
|
||||
restartModelRare();
|
||||
escCount = 0;
|
||||
}
|
||||
|
||||
private void updateModel()
|
||||
{
|
||||
//System.out.println("ModelPPM.updateModel()");
|
||||
// STATE fs = *FoundState, *p = NULL;
|
||||
StateRef fs = tempStateRef1;
|
||||
fs.setValues(foundState);
|
||||
State p = tempState3.init(getHeap());
|
||||
State tempState = tempState4.init(getHeap());
|
||||
|
||||
PPMContext pc = tempPPMContext3.init(getHeap());
|
||||
PPMContext successor = tempPPMContext4.init(getHeap());
|
||||
|
||||
int ns1, ns, cf, sf, s0;
|
||||
pc.setAddress(minContext.getSuffix());
|
||||
if (fs.getFreq() < MAX_FREQ / 4 && pc.getAddress() != 0) {
|
||||
if (pc.getNumStats() != 1) {
|
||||
p.setAddress(pc.getFreqData().getStats());
|
||||
if (p.getSymbol() != fs.getSymbol()) {
|
||||
do {
|
||||
p.incAddress();
|
||||
} while (p.getSymbol() != fs.getSymbol());
|
||||
tempState.setAddress(p.getAddress() - State.size);
|
||||
if (p.getFreq() >= tempState.getFreq()) {
|
||||
State.ppmdSwap(p, tempState);
|
||||
p.decAddress();
|
||||
}
|
||||
}
|
||||
if (p.getFreq() < MAX_FREQ - 9) {
|
||||
p.incFreq(2);
|
||||
pc.getFreqData().incSummFreq(2);
|
||||
}
|
||||
} else {
|
||||
p.setAddress(pc.getOneState().getAddress());
|
||||
if (p.getFreq() < 32) {
|
||||
p.incFreq(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (orderFall == 0) {
|
||||
foundState.setSuccessor(createSuccessors(true, p));
|
||||
minContext.setAddress(foundState.getSuccessor());
|
||||
maxContext.setAddress(foundState.getSuccessor());
|
||||
if (minContext.getAddress() == 0) {
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
subAlloc.getHeap()[subAlloc.getPText()] = (byte)fs.getSymbol();
|
||||
subAlloc.incPText();
|
||||
successor.setAddress(subAlloc.getPText());
|
||||
if (subAlloc.getPText() >= subAlloc.getFakeUnitsStart()) {
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
// // Debug
|
||||
// subAlloc.dumpHeap();
|
||||
if (fs.getSuccessor() != 0) {
|
||||
if (fs.getSuccessor() <= subAlloc.getPText()) {
|
||||
fs.setSuccessor(createSuccessors(false, p));
|
||||
if (fs.getSuccessor() == 0) {
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (--orderFall == 0) {
|
||||
successor.setAddress(fs.getSuccessor());
|
||||
if (maxContext.getAddress() != minContext.getAddress()) {
|
||||
subAlloc.decPText(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foundState.setSuccessor(successor.getAddress());
|
||||
fs.setSuccessor(minContext);
|
||||
}
|
||||
// // Debug
|
||||
// subAlloc.dumpHeap();
|
||||
ns = minContext.getNumStats();
|
||||
s0 = minContext.getFreqData().getSummFreq() - (ns) - (fs.getFreq() - 1);
|
||||
for (pc.setAddress(maxContext.getAddress());
|
||||
pc.getAddress() != minContext.getAddress();
|
||||
pc.setAddress(pc.getSuffix())) {
|
||||
if ((ns1 = pc.getNumStats()) != 1) {
|
||||
if ((ns1 & 1) == 0) {
|
||||
//System.out.println(ns1);
|
||||
pc.getFreqData().setStats(
|
||||
subAlloc.expandUnits(pc.getFreqData().getStats(),
|
||||
ns1 >>> 1));
|
||||
if (pc.getFreqData().getStats() == 0) {
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// bug fixed
|
||||
// int sum = ((2 * ns1 < ns) ? 1 : 0) +
|
||||
// 2 * ((4 * ((ns1 <= ns) ? 1 : 0)) & ((pc.getFreqData()
|
||||
// .getSummFreq() <= 8 * ns1) ? 1 : 0));
|
||||
int sum = ((2 * ns1 < ns) ? 1 : 0) + 2 * (
|
||||
((4 * ns1 <= ns) ? 1 : 0) &
|
||||
((pc.getFreqData().getSummFreq() <= 8 * ns1) ? 1 : 0)
|
||||
);
|
||||
pc.getFreqData().incSummFreq(sum);
|
||||
}
|
||||
else {
|
||||
p.setAddress(subAlloc.allocUnits(1));
|
||||
if (p.getAddress() == 0) {
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
p.setValues(pc.getOneState());
|
||||
pc.getFreqData().setStats(p);
|
||||
if (p.getFreq() < MAX_FREQ / 4 - 1) {
|
||||
p.incFreq(p.getFreq());
|
||||
}
|
||||
else {
|
||||
p.setFreq(MAX_FREQ - 4);
|
||||
}
|
||||
pc.getFreqData().setSummFreq(
|
||||
(p.getFreq() + initEsc + (ns > 3 ? 1 : 0)));
|
||||
}
|
||||
cf = 2 * fs.getFreq() * (pc.getFreqData().getSummFreq() + 6);
|
||||
sf = s0 + pc.getFreqData().getSummFreq();
|
||||
if (cf < 6 * sf) {
|
||||
cf = 1 + (cf > sf ? 1 : 0) + (cf >= 4 * sf ? 1 : 0);
|
||||
pc.getFreqData().incSummFreq(3);
|
||||
}
|
||||
else {
|
||||
cf = 4 + (cf >= 9 * sf ? 1 : 0) + (cf >= 12 * sf ? 1 : 0) +
|
||||
(cf >= 15 * sf ? 1 : 0);
|
||||
pc.getFreqData().incSummFreq(cf);
|
||||
}
|
||||
p.setAddress(pc.getFreqData().getStats() + ns1*State.size);
|
||||
p.setSuccessor(successor);
|
||||
p.setSymbol(fs.getSymbol());
|
||||
p.setFreq(cf);
|
||||
pc.setNumStats(++ns1);
|
||||
}
|
||||
|
||||
int address = fs.getSuccessor();
|
||||
maxContext.setAddress(address);
|
||||
minContext.setAddress(address);
|
||||
//TODO-----debug
|
||||
// int pos = minContext.getFreqData().getStats();
|
||||
// State a = new State(getHeap());
|
||||
// a.setAddress(pos);
|
||||
// pos+=State.size;
|
||||
// a.setAddress(pos);
|
||||
//--dbg end
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("ModelPPM[");
|
||||
buffer.append("\n numMasked=");
|
||||
buffer.append(numMasked);
|
||||
buffer.append("\n initEsc=");
|
||||
buffer.append(initEsc);
|
||||
buffer.append("\n orderFall=");
|
||||
buffer.append(orderFall);
|
||||
buffer.append("\n maxOrder=");
|
||||
buffer.append(maxOrder);
|
||||
buffer.append("\n runLength=");
|
||||
buffer.append(runLength);
|
||||
buffer.append("\n initRL=");
|
||||
buffer.append(initRL);
|
||||
buffer.append("\n escCount=");
|
||||
buffer.append(escCount);
|
||||
buffer.append("\n prevSuccess=");
|
||||
buffer.append(prevSuccess);
|
||||
buffer.append("\n foundState=");
|
||||
buffer.append(foundState);
|
||||
buffer.append("\n coder=");
|
||||
buffer.append(coder);
|
||||
buffer.append("\n subAlloc=");
|
||||
buffer.append(subAlloc);
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
// Debug
|
||||
// public void dumpHeap() {
|
||||
// subAlloc.dumpHeap();
|
||||
// }
|
||||
}
|
477
junrar/src/main/java/junrar/unpack/ppm/PPMContext.java
Normal file
477
junrar/src/main/java/junrar/unpack/ppm/PPMContext.java
Normal file
@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class PPMContext extends Pointer
|
||||
{
|
||||
|
||||
private static final int unionSize = Math.max(FreqData.size, State.size);
|
||||
|
||||
public static final int size = 2 + unionSize + 4; // 12
|
||||
|
||||
// ushort NumStats;
|
||||
private int numStats; // determines if feqData or onstate is used
|
||||
|
||||
// (1==onestate)
|
||||
|
||||
private final FreqData freqData; // -\
|
||||
|
||||
// |-> union
|
||||
private final State oneState; // -/
|
||||
|
||||
private int suffix; // pointer ppmcontext
|
||||
|
||||
public final static int[] ExpEscape =
|
||||
{ 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
|
||||
// Temp fields
|
||||
private final State tempState1 = new State(null);
|
||||
private final State tempState2 = new State(null);
|
||||
private final State tempState3 = new State(null);
|
||||
private final State tempState4 = new State(null);
|
||||
private final State tempState5 = new State(null);
|
||||
private PPMContext tempPPMContext = null;
|
||||
private final int[] ps = new int[256];
|
||||
|
||||
public PPMContext(byte[] mem)
|
||||
{
|
||||
super(mem);
|
||||
oneState = new State(mem);
|
||||
freqData = new FreqData(mem);
|
||||
}
|
||||
|
||||
public PPMContext init(byte[] mem) {
|
||||
this.mem = mem;
|
||||
pos = 0;
|
||||
oneState.init(mem);
|
||||
freqData.init(mem);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FreqData getFreqData()
|
||||
{
|
||||
return freqData;
|
||||
}
|
||||
|
||||
public void setFreqData(FreqData freqData)
|
||||
{
|
||||
this.freqData.setSummFreq(freqData.getSummFreq());
|
||||
this.freqData.setStats(freqData.getStats());
|
||||
}
|
||||
|
||||
public final int getNumStats()
|
||||
{
|
||||
if (mem!=null){
|
||||
numStats = Raw.readShortLittleEndian(mem, pos)&0xffff;
|
||||
}
|
||||
return numStats;
|
||||
}
|
||||
|
||||
public final void setNumStats(int numStats)
|
||||
{
|
||||
this.numStats = numStats&0xffff;
|
||||
if (mem != null) {
|
||||
Raw.writeShortLittleEndian(mem, pos, (short)numStats);
|
||||
}
|
||||
}
|
||||
|
||||
public State getOneState()
|
||||
{
|
||||
return oneState;
|
||||
}
|
||||
|
||||
public void setOneState(StateRef oneState)
|
||||
{
|
||||
this.oneState.setValues(oneState);
|
||||
}
|
||||
|
||||
public int getSuffix()
|
||||
{
|
||||
if(mem!=null){
|
||||
suffix = Raw.readIntLittleEndian(mem, pos+8);
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(PPMContext suffix)
|
||||
{
|
||||
setSuffix(suffix.getAddress());
|
||||
}
|
||||
|
||||
public void setSuffix(int suffix)
|
||||
{
|
||||
this.suffix = suffix;
|
||||
if (mem != null) {
|
||||
Raw.writeIntLittleEndian(mem, pos + 8, suffix);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddress(int pos)
|
||||
{
|
||||
super.setAddress(pos);
|
||||
oneState.setAddress(pos+2);
|
||||
freqData.setAddress(pos+2);
|
||||
}
|
||||
|
||||
private PPMContext getTempPPMContext(byte[] mem) {
|
||||
if (tempPPMContext == null) {
|
||||
tempPPMContext = new PPMContext(null);
|
||||
}
|
||||
return tempPPMContext.init(mem);
|
||||
}
|
||||
|
||||
public int createChild(ModelPPM model, State pStats/* ptr */,
|
||||
StateRef firstState /* ref */)
|
||||
{
|
||||
PPMContext pc = getTempPPMContext(model.getSubAlloc().getHeap());
|
||||
pc.setAddress(model.getSubAlloc().allocContext());
|
||||
if (pc != null) {
|
||||
pc.setNumStats(1);
|
||||
pc.setOneState(firstState);
|
||||
pc.setSuffix(this);
|
||||
pStats.setSuccessor(pc);
|
||||
}
|
||||
return pc.getAddress();
|
||||
}
|
||||
|
||||
public void rescale(ModelPPM model)
|
||||
{
|
||||
int OldNS = getNumStats(), i = getNumStats() - 1, Adder, EscFreq;
|
||||
// STATE* p1, * p;
|
||||
State p1 = new State(model.getHeap());
|
||||
State p = new State(model.getHeap());
|
||||
State temp = new State(model.getHeap());
|
||||
|
||||
for (p.setAddress(model.getFoundState().getAddress());
|
||||
p.getAddress() != freqData.getStats();
|
||||
p.decAddress()) {
|
||||
temp.setAddress(p.getAddress() - State.size);
|
||||
State.ppmdSwap(p, temp);
|
||||
}
|
||||
temp.setAddress(freqData.getStats());
|
||||
temp.incFreq(4);
|
||||
freqData.incSummFreq(4);
|
||||
EscFreq = freqData.getSummFreq() - p.getFreq();
|
||||
Adder = (model.getOrderFall() != 0) ? 1 : 0;
|
||||
p.setFreq((p.getFreq() + Adder) >>> 1);
|
||||
freqData.setSummFreq(p.getFreq());
|
||||
do {
|
||||
p.incAddress();
|
||||
EscFreq -= p.getFreq();
|
||||
p.setFreq((p.getFreq() + Adder) >>> 1);
|
||||
freqData.incSummFreq(p.getFreq());
|
||||
temp.setAddress(p.getAddress() - State.size);
|
||||
if (p.getFreq() > temp.getFreq()) {
|
||||
p1.setAddress(p.getAddress());
|
||||
StateRef tmp = new StateRef();
|
||||
tmp.setValues(p1);
|
||||
State temp2 = new State(model.getHeap());
|
||||
State temp3 = new State(model.getHeap());
|
||||
do {
|
||||
// p1[0]=p1[-1];
|
||||
temp2.setAddress(p1.getAddress() - State.size);
|
||||
p1.setValues(temp2);
|
||||
p1.decAddress();
|
||||
temp3.setAddress(p1.getAddress() - State.size);
|
||||
} while (p1.getAddress() != freqData.getStats() && tmp.getFreq() > temp3.getFreq());
|
||||
p1.setValues(tmp);
|
||||
}
|
||||
} while (--i != 0);
|
||||
if (p.getFreq() == 0) {
|
||||
do {
|
||||
i++;
|
||||
p.decAddress();
|
||||
} while (p.getFreq() == 0);
|
||||
EscFreq += i;
|
||||
setNumStats(getNumStats() - i);
|
||||
if (getNumStats() == 1) {
|
||||
StateRef tmp = new StateRef();
|
||||
temp.setAddress(freqData.getStats());
|
||||
tmp.setValues(temp);
|
||||
// STATE tmp=*U.Stats;
|
||||
do {
|
||||
// tmp.Freq-=(tmp.Freq >> 1)
|
||||
tmp.decFreq(tmp.getFreq() >>> 1);
|
||||
EscFreq >>>= 1;
|
||||
} while (EscFreq > 1);
|
||||
model.getSubAlloc().freeUnits(freqData.getStats(),(OldNS + 1) >>> 1);
|
||||
oneState.setValues(tmp);
|
||||
model.getFoundState().setAddress(oneState.getAddress());
|
||||
return;
|
||||
}
|
||||
}
|
||||
EscFreq -= EscFreq >>> 1;
|
||||
freqData.incSummFreq(EscFreq);
|
||||
int n0 = (OldNS + 1) >>> 1, n1 = (getNumStats() + 1) >>> 1;
|
||||
if (n0 != n1) {
|
||||
freqData.setStats(model.getSubAlloc().shrinkUnits(freqData.getStats(), n0, n1));
|
||||
}
|
||||
model.getFoundState().setAddress(freqData.getStats());
|
||||
}
|
||||
|
||||
private int getArrayIndex(ModelPPM Model, State rs)
|
||||
{
|
||||
PPMContext tempSuffix = getTempPPMContext(Model.getSubAlloc().getHeap());
|
||||
tempSuffix.setAddress(getSuffix());
|
||||
int ret = 0;
|
||||
ret += Model.getPrevSuccess();
|
||||
ret += Model.getNS2BSIndx()[tempSuffix.getNumStats() - 1];
|
||||
ret += Model.getHiBitsFlag() + 2* Model.getHB2Flag()[rs.getSymbol()];
|
||||
ret += ((Model.getRunLength() >>> 26) & 0x20);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getMean(int summ, int shift, int round)
|
||||
{
|
||||
return ( (summ + (1 << (shift - round) ) ) >>> (shift) );
|
||||
}
|
||||
|
||||
public void decodeBinSymbol(ModelPPM model)
|
||||
{
|
||||
State rs = tempState1.init(model.getHeap());
|
||||
rs.setAddress(oneState.getAddress());// State&
|
||||
model.setHiBitsFlag(model.getHB2Flag()[model.getFoundState().getSymbol()]);
|
||||
int off1 = rs.getFreq() - 1;
|
||||
int off2 = getArrayIndex(model, rs);
|
||||
int bs = model.getBinSumm()[off1][off2];
|
||||
if (model.getCoder().getCurrentShiftCount(ModelPPM.TOT_BITS) < bs) {
|
||||
model.getFoundState().setAddress(rs.getAddress());
|
||||
rs.incFreq((rs.getFreq() < 128) ? 1 : 0);
|
||||
model.getCoder().getSubRange().setLowCount(0);
|
||||
model.getCoder().getSubRange().setHighCount(bs);
|
||||
bs = ((bs + ModelPPM.INTERVAL - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xffff);
|
||||
model.getBinSumm()[off1][off2] = bs;
|
||||
model.setPrevSuccess(1);
|
||||
model.incRunLength(1);
|
||||
} else {
|
||||
model.getCoder().getSubRange().setLowCount(bs);
|
||||
bs = (bs - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xFFFF;
|
||||
model.getBinSumm()[off1][off2] = bs;
|
||||
model.getCoder().getSubRange().setHighCount(ModelPPM.BIN_SCALE);
|
||||
model.setInitEsc(ExpEscape[bs >>> 10]);
|
||||
model.setNumMasked(1);
|
||||
model.getCharMask()[rs.getSymbol()] = model.getEscCount();
|
||||
model.setPrevSuccess(0);
|
||||
model.getFoundState().setAddress(0);
|
||||
}
|
||||
//int a = 0;//TODO just 4 debugging
|
||||
}
|
||||
|
||||
// public static void ppmdSwap(ModelPPM model, StatePtr state1, StatePtr state2)
|
||||
// {
|
||||
// byte[] bytes = model.getSubAlloc().getHeap();
|
||||
// int p1 = state1.getAddress();
|
||||
// int p2 = state2.getAddress();
|
||||
//
|
||||
// for (int i = 0; i < StatePtr.size; i++) {
|
||||
// byte temp = bytes[p1+i];
|
||||
// bytes[p1+i] = bytes[p2+i];
|
||||
// bytes[p2+i] = temp;
|
||||
// }
|
||||
// state1.setAddress(p1);
|
||||
// state2.setAddress(p2);
|
||||
// }
|
||||
|
||||
public void update1(ModelPPM model, int p/* ptr */)
|
||||
{
|
||||
model.getFoundState().setAddress(p);
|
||||
model.getFoundState().incFreq(4);
|
||||
freqData.incSummFreq(4);
|
||||
State p0 = tempState3.init(model.getHeap());
|
||||
State p1 = tempState4.init(model.getHeap());
|
||||
p0.setAddress(p);
|
||||
p1.setAddress(p - State.size);
|
||||
if (p0.getFreq() > p1.getFreq()) {
|
||||
State.ppmdSwap(p0, p1);
|
||||
model.getFoundState().setAddress(p1.getAddress());
|
||||
if (p1.getFreq() > ModelPPM.MAX_FREQ)
|
||||
rescale(model);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean decodeSymbol2(ModelPPM model)
|
||||
{
|
||||
long count;
|
||||
int hiCnt, i = getNumStats() - model.getNumMasked();
|
||||
SEE2Context psee2c = makeEscFreq2(model, i);
|
||||
RangeCoder coder = model.getCoder();
|
||||
// STATE* ps[256], ** pps=ps, * p=U.Stats-1;
|
||||
State p = tempState1.init(model.getHeap());
|
||||
State temp = tempState2.init(model.getHeap());
|
||||
p.setAddress(freqData.getStats() - State.size);
|
||||
int pps = 0;
|
||||
hiCnt = 0;
|
||||
|
||||
do {
|
||||
do {
|
||||
p.incAddress();// p++;
|
||||
} while (model.getCharMask()[p.getSymbol()] == model.getEscCount());
|
||||
hiCnt += p.getFreq();
|
||||
ps[pps++] = p.getAddress();
|
||||
} while (--i != 0);
|
||||
coder.getSubRange().incScale(hiCnt);
|
||||
count = coder.getCurrentCount();
|
||||
if (count >= coder.getSubRange().getScale()) {
|
||||
return false;
|
||||
}
|
||||
pps = 0;
|
||||
p.setAddress(ps[pps]);
|
||||
if (count < hiCnt) {
|
||||
hiCnt = 0;
|
||||
while ((hiCnt += p.getFreq()) <= count) {
|
||||
p.setAddress(ps[++pps]);// p=*++pps;
|
||||
}
|
||||
coder.getSubRange().setHighCount(hiCnt);
|
||||
coder.getSubRange().setLowCount(hiCnt - p.getFreq());
|
||||
psee2c.update();
|
||||
update2(model, p.getAddress());
|
||||
} else {
|
||||
coder.getSubRange().setLowCount(hiCnt);
|
||||
coder.getSubRange().setHighCount(coder.getSubRange().getScale());
|
||||
i = getNumStats() - model.getNumMasked();// ->NumMasked;
|
||||
pps--;
|
||||
do {
|
||||
temp.setAddress(ps[++pps]);// (*++pps)
|
||||
model.getCharMask()[temp.getSymbol()] = model.getEscCount();
|
||||
} while (--i != 0);
|
||||
psee2c.incSumm((int)coder.getSubRange().getScale());
|
||||
model.setNumMasked(getNumStats());
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
public void update2(ModelPPM model, int p/* state ptr */)
|
||||
{
|
||||
State temp = tempState5.init(model.getHeap());
|
||||
temp.setAddress(p);
|
||||
model.getFoundState().setAddress(p);
|
||||
model.getFoundState().incFreq(4);
|
||||
freqData.incSummFreq(4);
|
||||
if (temp.getFreq() > ModelPPM.MAX_FREQ) {
|
||||
rescale(model);
|
||||
}
|
||||
model.incEscCount(1);
|
||||
model.setRunLength(model.getInitRL());
|
||||
}
|
||||
|
||||
private SEE2Context makeEscFreq2(ModelPPM model, int Diff)
|
||||
{
|
||||
SEE2Context psee2c;
|
||||
int numStats = getNumStats();
|
||||
if (numStats != 256) {
|
||||
PPMContext suff = getTempPPMContext(model.getHeap());
|
||||
suff.setAddress(getSuffix());
|
||||
int idx1 = model.getNS2Indx()[Diff - 1];
|
||||
int idx2 = 0;
|
||||
idx2 += (Diff < suff.getNumStats() - numStats) ? 1 : 0;
|
||||
idx2 += 2 * ((freqData.getSummFreq() < 11 * numStats) ? 1 : 0);
|
||||
idx2 += 4 * ((model.getNumMasked() > Diff) ? 1 : 0);
|
||||
idx2 += model.getHiBitsFlag();
|
||||
psee2c = model.getSEE2Cont()[idx1][idx2];
|
||||
model.getCoder().getSubRange().setScale(psee2c.getMean());
|
||||
} else {
|
||||
psee2c = model.getDummySEE2Cont();
|
||||
model.getCoder().getSubRange().setScale(1);
|
||||
}
|
||||
return psee2c;
|
||||
}
|
||||
|
||||
public boolean decodeSymbol1(ModelPPM model)
|
||||
{
|
||||
|
||||
RangeCoder coder = model.getCoder();
|
||||
coder.getSubRange().setScale(freqData.getSummFreq());
|
||||
State p = new State(model.getHeap());
|
||||
p.setAddress(freqData.getStats());
|
||||
int i, HiCnt;
|
||||
long count = coder.getCurrentCount();
|
||||
if (count >= coder.getSubRange().getScale()) {
|
||||
return false;
|
||||
}
|
||||
if (count < (HiCnt = p.getFreq())) {
|
||||
coder.getSubRange().setHighCount(HiCnt);
|
||||
model.setPrevSuccess((2 * HiCnt > coder.getSubRange().getScale()) ? 1 : 0);
|
||||
model.incRunLength(model.getPrevSuccess());
|
||||
HiCnt += 4;
|
||||
model.getFoundState().setAddress(p.getAddress());
|
||||
model.getFoundState().setFreq(HiCnt);
|
||||
freqData.incSummFreq(4);
|
||||
if (HiCnt > ModelPPM.MAX_FREQ) {
|
||||
rescale(model);
|
||||
}
|
||||
coder.getSubRange().setLowCount(0);
|
||||
return true;
|
||||
} else {
|
||||
if (model.getFoundState().getAddress() == 0) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
model.setPrevSuccess(0);
|
||||
int numStats = getNumStats();
|
||||
i = numStats - 1;
|
||||
while ((HiCnt += p.incAddress().getFreq()) <= count)
|
||||
{
|
||||
if (--i == 0) {
|
||||
model.setHiBitsFlag(model.getHB2Flag()[model.getFoundState().getSymbol()]);
|
||||
coder.getSubRange().setLowCount(HiCnt);
|
||||
model.getCharMask()[p.getSymbol()] = model.getEscCount();
|
||||
model.setNumMasked(numStats);
|
||||
i = numStats - 1;
|
||||
model.getFoundState().setAddress(0);
|
||||
do {
|
||||
model.getCharMask()[p.decAddress().getSymbol()] = model.getEscCount();
|
||||
} while (--i != 0);
|
||||
coder.getSubRange().setHighCount(coder.getSubRange().getScale());
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
coder.getSubRange().setLowCount(HiCnt-p.getFreq());
|
||||
coder.getSubRange().setHighCount(HiCnt);
|
||||
update1(model, p.getAddress());
|
||||
return (true);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("PPMContext[");
|
||||
buffer.append("\n pos=");
|
||||
buffer.append(pos);
|
||||
buffer.append("\n size=");
|
||||
buffer.append(size);
|
||||
buffer.append("\n numStats=");
|
||||
buffer.append(getNumStats());
|
||||
buffer.append("\n Suffix=");
|
||||
buffer.append(getSuffix());
|
||||
buffer.append("\n freqData=");
|
||||
buffer.append(freqData);
|
||||
buffer.append("\n oneState=");
|
||||
buffer.append(oneState);
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
59
junrar/src/main/java/junrar/unpack/ppm/Pointer.java
Normal file
59
junrar/src/main/java/junrar/unpack/ppm/Pointer.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 14.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
/**
|
||||
* Simulates Pointers on a single mem block as a byte[]
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public abstract class Pointer
|
||||
{
|
||||
protected byte[] mem;
|
||||
protected int pos;
|
||||
|
||||
/**
|
||||
* Initialize the object with the array (may be null)
|
||||
* @param mem the byte array
|
||||
*/
|
||||
public Pointer(byte[] mem){
|
||||
this.mem = mem;
|
||||
}
|
||||
/**
|
||||
* returns the position of this object in the byte[]
|
||||
* @return the address of this object
|
||||
*/
|
||||
public int getAddress(){
|
||||
assert (mem != null);
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* needs to set the fields of this object to the values in the byte[]
|
||||
* at the given position.
|
||||
* be aware of the byte order
|
||||
* @param pos the position this object should point to
|
||||
* @return true if the address could be set
|
||||
*/
|
||||
public void setAddress(int pos) {
|
||||
assert (mem != null);
|
||||
assert (pos >= 0) && (pos < mem.length) : pos;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
177
junrar/src/main/java/junrar/unpack/ppm/RangeCoder.java
Normal file
177
junrar/src/main/java/junrar/unpack/ppm/RangeCoder.java
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import junrar.exception.RarException;
|
||||
import junrar.unpack.Unpack;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class RangeCoder
|
||||
{
|
||||
public static final int TOP = 1 << 24;
|
||||
|
||||
public static final int BOT = 1 << 15;
|
||||
|
||||
private static final long uintMask = 0xFFFFffffL;
|
||||
|
||||
// uint low, code, range;
|
||||
private long low, code, range;
|
||||
|
||||
private final SubRange subRange = new SubRange();
|
||||
|
||||
private Unpack unpackRead;
|
||||
|
||||
public SubRange getSubRange()
|
||||
{
|
||||
return subRange;
|
||||
}
|
||||
|
||||
public void initDecoder(Unpack unpackRead) throws IOException, RarException
|
||||
{
|
||||
this.unpackRead = unpackRead;
|
||||
|
||||
low = code = 0L;
|
||||
range = 0xFFFFffffL;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
code = ((code << 8) | getChar())&uintMask;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentCount()
|
||||
{
|
||||
range = (range / subRange.getScale())&uintMask;
|
||||
return (int)((code - low) / (range));
|
||||
}
|
||||
|
||||
public long getCurrentShiftCount(int SHIFT)
|
||||
{
|
||||
range = range >>>SHIFT;
|
||||
return ((code - low) / (range))&uintMask;
|
||||
}
|
||||
|
||||
public void decode()
|
||||
{
|
||||
low = (low + (range * subRange.getLowCount()))&uintMask;
|
||||
range = (range * (subRange.getHighCount() - subRange.getLowCount()))&uintMask;
|
||||
}
|
||||
|
||||
private int getChar() throws IOException, RarException
|
||||
{
|
||||
return (unpackRead.getChar());
|
||||
}
|
||||
|
||||
public void ariDecNormalize() throws IOException, RarException
|
||||
{
|
||||
// while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true))
|
||||
// {
|
||||
// code = ((code << 8) | unpackRead.getChar()&0xff)&uintMask;
|
||||
// range = (range << 8)&uintMask;
|
||||
// low = (low << 8)&uintMask;
|
||||
// }
|
||||
|
||||
// Rewrote for clarity
|
||||
boolean c2 = false;
|
||||
while ((low ^ (low + range)) < TOP || (c2 = range < BOT)) {
|
||||
if (c2) {
|
||||
range = (-low & (BOT - 1))&uintMask;
|
||||
c2 = false;
|
||||
}
|
||||
code = ((code << 8) | getChar())&uintMask;
|
||||
range = (range << 8)&uintMask;
|
||||
low = (low << 8)&uintMask;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("RangeCoder[");
|
||||
buffer.append("\n low=");
|
||||
buffer.append(low);
|
||||
buffer.append("\n code=");
|
||||
buffer.append(code);
|
||||
buffer.append("\n range=");
|
||||
buffer.append(range);
|
||||
buffer.append("\n subrange=");
|
||||
buffer.append(subRange);
|
||||
buffer.append("]");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static class SubRange
|
||||
{
|
||||
// uint LowCount, HighCount, scale;
|
||||
private long lowCount, highCount, scale;
|
||||
|
||||
public long getHighCount()
|
||||
{
|
||||
return highCount;
|
||||
}
|
||||
|
||||
public void setHighCount(long highCount)
|
||||
{
|
||||
this.highCount = highCount&uintMask;
|
||||
}
|
||||
|
||||
public long getLowCount()
|
||||
{
|
||||
return lowCount&uintMask;
|
||||
}
|
||||
|
||||
public void setLowCount(long lowCount)
|
||||
{
|
||||
this.lowCount = lowCount&uintMask;
|
||||
}
|
||||
|
||||
public long getScale()
|
||||
{
|
||||
return scale;
|
||||
}
|
||||
|
||||
public void setScale(long scale)
|
||||
{
|
||||
this.scale = scale&uintMask;
|
||||
}
|
||||
|
||||
public void incScale(int dScale) {
|
||||
setScale(getScale() + dScale);
|
||||
}
|
||||
|
||||
// Debug
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("SubRange[");
|
||||
buffer.append("\n lowCount=");
|
||||
buffer.append(lowCount);
|
||||
buffer.append("\n highCount=");
|
||||
buffer.append(highCount);
|
||||
buffer.append("\n scale=");
|
||||
buffer.append(scale);
|
||||
buffer.append("]");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
}
|
139
junrar/src/main/java/junrar/unpack/ppm/RarMemBlock.java
Normal file
139
junrar/src/main/java/junrar/unpack/ppm/RarMemBlock.java
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 05.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class RarMemBlock extends Pointer
|
||||
{
|
||||
|
||||
public static final int size = 12;
|
||||
|
||||
private int stamp, NU;
|
||||
|
||||
private int next, prev; // Pointer RarMemBlock
|
||||
|
||||
public RarMemBlock(byte[] mem)
|
||||
{
|
||||
super(mem);
|
||||
}
|
||||
|
||||
public void insertAt(RarMemBlock p)
|
||||
{
|
||||
RarMemBlock temp = new RarMemBlock(mem);
|
||||
setPrev(p.getAddress());
|
||||
temp.setAddress(getPrev());
|
||||
setNext(temp.getNext());// prev.getNext();
|
||||
temp.setNext(this);// prev.setNext(this);
|
||||
temp.setAddress(getNext());
|
||||
temp.setPrev(this);// next.setPrev(this);
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
RarMemBlock temp = new RarMemBlock(mem);
|
||||
temp.setAddress(getPrev());
|
||||
temp.setNext(getNext());// prev.setNext(next);
|
||||
temp.setAddress(getNext());
|
||||
temp.setPrev(getPrev());// next.setPrev(prev);
|
||||
// next = -1;
|
||||
// prev = -1;
|
||||
}
|
||||
|
||||
public int getNext()
|
||||
{
|
||||
if(mem!=null){
|
||||
next = Raw.readIntLittleEndian(mem, pos+4);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(RarMemBlock next)
|
||||
{
|
||||
setNext(next.getAddress());
|
||||
}
|
||||
|
||||
public void setNext(int next)
|
||||
{
|
||||
this.next = next;
|
||||
if (mem != null) {
|
||||
Raw.writeIntLittleEndian(mem, pos + 4, next);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNU()
|
||||
{
|
||||
if(mem!=null){
|
||||
NU = Raw.readShortLittleEndian(mem, pos+2)&0xffff;
|
||||
}
|
||||
return NU;
|
||||
}
|
||||
|
||||
public void setNU(int nu)
|
||||
{
|
||||
NU = nu&0xffff;
|
||||
if (mem != null) {
|
||||
Raw.writeShortLittleEndian(mem, pos + 2, (short)nu);
|
||||
}
|
||||
}
|
||||
|
||||
public int getPrev()
|
||||
{
|
||||
if(mem!=null){
|
||||
prev = Raw.readIntLittleEndian(mem, pos+8);
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
public void setPrev(RarMemBlock prev)
|
||||
{
|
||||
setPrev(prev.getAddress());
|
||||
}
|
||||
|
||||
public void setPrev(int prev)
|
||||
{
|
||||
this.prev = prev;
|
||||
if (mem != null) {
|
||||
Raw.writeIntLittleEndian(mem, pos + 8, prev);
|
||||
}
|
||||
}
|
||||
|
||||
public int getStamp()
|
||||
{
|
||||
if(mem!=null){
|
||||
stamp = Raw.readShortLittleEndian(mem, pos)&0xffff;
|
||||
}
|
||||
return stamp;
|
||||
}
|
||||
|
||||
public void setStamp(int stamp)
|
||||
{
|
||||
this.stamp = stamp;
|
||||
if (mem != null) {
|
||||
Raw.writeShortLittleEndian(mem, pos, (short)stamp);
|
||||
}
|
||||
}
|
||||
}
|
69
junrar/src/main/java/junrar/unpack/ppm/RarNode.java
Normal file
69
junrar/src/main/java/junrar/unpack/ppm/RarNode.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 05.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class RarNode extends Pointer{
|
||||
private int next; //rarnode pointer
|
||||
|
||||
public static final int size = 4;
|
||||
|
||||
public RarNode(byte[] mem){
|
||||
super(mem);
|
||||
}
|
||||
|
||||
public int getNext() {
|
||||
if(mem!=null){
|
||||
next = Raw.readIntLittleEndian(mem, pos);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(RarNode next) {
|
||||
setNext(next.getAddress());
|
||||
}
|
||||
|
||||
public void setNext(int next) {
|
||||
this.next = next;
|
||||
if(mem!=null){
|
||||
Raw.writeIntLittleEndian(mem, pos, next);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("State[");
|
||||
buffer.append("\n pos=");
|
||||
buffer.append(pos);
|
||||
buffer.append("\n size=");
|
||||
buffer.append(size);
|
||||
buffer.append("\n next=");
|
||||
buffer.append(getNext());
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
102
junrar/src/main/java/junrar/unpack/ppm/SEE2Context.java
Normal file
102
junrar/src/main/java/junrar/unpack/ppm/SEE2Context.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class SEE2Context {
|
||||
public static final int size = 4;
|
||||
|
||||
// ushort Summ;
|
||||
private int summ;
|
||||
|
||||
// byte Shift;
|
||||
private int shift;
|
||||
|
||||
// byte Count;
|
||||
private int count;
|
||||
|
||||
public void init(int initVal) {
|
||||
shift = (ModelPPM.PERIOD_BITS - 4)&0xff;
|
||||
summ = (initVal << shift)&0xffff;
|
||||
count = 4;
|
||||
}
|
||||
|
||||
public int getMean() {
|
||||
int retVal = summ >>> shift;
|
||||
summ -= retVal;
|
||||
return retVal + ((retVal == 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (shift < ModelPPM.PERIOD_BITS && --count == 0) {
|
||||
summ += summ;
|
||||
count = (3 << shift++);
|
||||
}
|
||||
summ &= 0xffff;
|
||||
count &= 0xff;
|
||||
shift &= 0xff;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count&0xff;
|
||||
}
|
||||
|
||||
public int getShift() {
|
||||
return shift;
|
||||
}
|
||||
|
||||
public void setShift(int shift) {
|
||||
this.shift = shift&0xff;
|
||||
}
|
||||
|
||||
public int getSumm() {
|
||||
return summ;
|
||||
}
|
||||
|
||||
public void setSumm(int summ) {
|
||||
this.summ = summ&0xffff;
|
||||
}
|
||||
|
||||
public void incSumm(int dSumm) {
|
||||
setSumm(getSumm() + dSumm);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("SEE2Context[");
|
||||
buffer.append("\n size=");
|
||||
buffer.append(size);
|
||||
buffer.append("\n summ=");
|
||||
buffer.append(summ);
|
||||
buffer.append("\n shift=");
|
||||
buffer.append(shift);
|
||||
buffer.append("\n count=");
|
||||
buffer.append(count);
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
119
junrar/src/main/java/junrar/unpack/ppm/State.java
Normal file
119
junrar/src/main/java/junrar/unpack/ppm/State.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import junrar.io.Raw;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class State extends Pointer {
|
||||
|
||||
public static final int size = 6;
|
||||
|
||||
public State(byte[] mem) {
|
||||
super(mem);
|
||||
}
|
||||
|
||||
public State init(byte[] mem) {
|
||||
this.mem = mem;
|
||||
pos = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSymbol() {
|
||||
return mem[pos]&0xff;
|
||||
}
|
||||
|
||||
public void setSymbol(int symbol) {
|
||||
mem[pos] = (byte)symbol;
|
||||
}
|
||||
|
||||
public int getFreq() {
|
||||
return mem[pos+1]&0xff;
|
||||
}
|
||||
|
||||
public void setFreq(int freq) {
|
||||
mem[pos + 1] = (byte)freq;
|
||||
}
|
||||
|
||||
public void incFreq(int dFreq) {
|
||||
mem[pos + 1] += dFreq;
|
||||
}
|
||||
|
||||
public int getSuccessor() {
|
||||
return Raw.readIntLittleEndian(mem, pos+2);
|
||||
}
|
||||
|
||||
public void setSuccessor(PPMContext successor) {
|
||||
setSuccessor(successor.getAddress());
|
||||
}
|
||||
|
||||
public void setSuccessor(int successor) {
|
||||
Raw.writeIntLittleEndian(mem, pos + 2, successor);
|
||||
}
|
||||
|
||||
public void setValues(StateRef state){
|
||||
setSymbol(state.getSymbol());
|
||||
setFreq(state.getFreq());
|
||||
setSuccessor(state.getSuccessor());
|
||||
}
|
||||
|
||||
public void setValues(State ptr){
|
||||
System.arraycopy(ptr.mem, ptr.pos, mem, pos, size);
|
||||
}
|
||||
|
||||
public State decAddress(){
|
||||
setAddress(pos-size);
|
||||
return this;
|
||||
}
|
||||
|
||||
public State incAddress(){
|
||||
setAddress(pos+size);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static void ppmdSwap(State ptr1, State ptr2) {
|
||||
byte[] mem1=ptr1.mem, mem2=ptr2.mem;
|
||||
for (int i=0, pos1=ptr1.pos, pos2=ptr2.pos; i < size; i++, pos1++, pos2++) {
|
||||
byte temp = mem1[pos1];
|
||||
mem1[pos1] = mem2[pos2];
|
||||
mem2[pos2] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("State[");
|
||||
buffer.append("\n pos=");
|
||||
buffer.append(pos);
|
||||
buffer.append("\n size=");
|
||||
buffer.append(size);
|
||||
buffer.append("\n symbol=");
|
||||
buffer.append(getSymbol());
|
||||
buffer.append("\n freq=");
|
||||
buffer.append(getFreq());
|
||||
buffer.append("\n successor=");
|
||||
buffer.append(getSuccessor());
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
92
junrar/src/main/java/junrar/unpack/ppm/StateRef.java
Normal file
92
junrar/src/main/java/junrar/unpack/ppm/StateRef.java
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class StateRef {
|
||||
|
||||
private int symbol;
|
||||
|
||||
private int freq;
|
||||
|
||||
private int successor; // pointer ppmcontext
|
||||
|
||||
public StateRef() {
|
||||
}
|
||||
|
||||
public int getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(int symbol) {
|
||||
this.symbol = symbol&0xff;
|
||||
}
|
||||
|
||||
public int getFreq() {
|
||||
return freq;
|
||||
}
|
||||
|
||||
public void setFreq(int freq) {
|
||||
this.freq = freq&0xff;
|
||||
}
|
||||
|
||||
public void incFreq(int dFreq) {
|
||||
freq = (freq + dFreq)&0xff;
|
||||
}
|
||||
|
||||
public void decFreq(int dFreq) {
|
||||
freq = (freq - dFreq)&0xff;
|
||||
}
|
||||
|
||||
public void setValues(State statePtr){
|
||||
setFreq(statePtr.getFreq());
|
||||
setSuccessor(statePtr.getSuccessor());
|
||||
setSymbol(statePtr.getSymbol());
|
||||
}
|
||||
|
||||
public int getSuccessor() {
|
||||
return successor;
|
||||
}
|
||||
|
||||
public void setSuccessor(PPMContext successor) {
|
||||
setSuccessor(successor.getAddress());
|
||||
}
|
||||
|
||||
public void setSuccessor(int successor) {
|
||||
this.successor = successor;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("State[");
|
||||
buffer.append("\n symbol=");
|
||||
buffer.append(getSymbol());
|
||||
buffer.append("\n freq=");
|
||||
buffer.append(getFreq());
|
||||
buffer.append("\n successor=");
|
||||
buffer.append(getSuccessor());
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
427
junrar/src/main/java/junrar/unpack/ppm/SubAllocator.java
Normal file
427
junrar/src/main/java/junrar/unpack/ppm/SubAllocator.java
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.ppm;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class SubAllocator {
|
||||
public static final int N1 = 4, N2 = 4, N3 = 4, N4 = (128 + 3 - 1 * N1 - 2
|
||||
* N2 - 3 * N3) / 4;
|
||||
|
||||
public static final int N_INDEXES = N1 + N2 + N3 + N4;
|
||||
|
||||
public static final int UNIT_SIZE = Math.max(PPMContext.size,
|
||||
RarMemBlock.size);
|
||||
|
||||
public static final int FIXED_UNIT_SIZE = 12;
|
||||
|
||||
private int subAllocatorSize;
|
||||
|
||||
// byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
|
||||
private int[] indx2Units = new int[N_INDEXES];
|
||||
private int[] units2Indx = new int[128];
|
||||
private int glueCount;
|
||||
|
||||
// byte *HeapStart,*LoUnit, *HiUnit;
|
||||
private int heapStart, loUnit, hiUnit;
|
||||
|
||||
private final RarNode[] freeList = new RarNode[N_INDEXES];
|
||||
|
||||
// byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;
|
||||
private int pText, unitsStart, heapEnd, fakeUnitsStart;
|
||||
|
||||
private byte[] heap;
|
||||
|
||||
private int freeListPos;
|
||||
|
||||
private int tempMemBlockPos;
|
||||
|
||||
// Temp fields
|
||||
private RarNode tempRarNode = null;
|
||||
private RarMemBlock tempRarMemBlock1 = null;
|
||||
private RarMemBlock tempRarMemBlock2 = null;
|
||||
private RarMemBlock tempRarMemBlock3 = null;
|
||||
|
||||
public SubAllocator() {
|
||||
clean();
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
subAllocatorSize = 0;
|
||||
}
|
||||
|
||||
private void insertNode(int p/* rarnode ptr */, int indx) {
|
||||
RarNode temp = tempRarNode;
|
||||
temp.setAddress(p);
|
||||
temp.setNext(freeList[indx].getNext());
|
||||
freeList[indx].setNext(temp);
|
||||
}
|
||||
|
||||
public void incPText() {
|
||||
pText++;
|
||||
}
|
||||
|
||||
private int removeNode(int indx) {
|
||||
int retVal = freeList[indx].getNext();
|
||||
RarNode temp = tempRarNode;
|
||||
temp.setAddress(retVal);
|
||||
freeList[indx].setNext(temp.getNext());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private int U2B(int NU) {
|
||||
return /* 8*NU+4*NU */UNIT_SIZE * NU;
|
||||
}
|
||||
|
||||
/* memblockptr */
|
||||
private int MBPtr(int BasePtr, int Items) {
|
||||
return (BasePtr + U2B(Items));
|
||||
}
|
||||
|
||||
private void splitBlock(int pv/* ptr */, int oldIndx, int newIndx) {
|
||||
int i, uDiff = indx2Units[oldIndx] - indx2Units[newIndx];
|
||||
int p = pv + U2B(indx2Units[newIndx]);
|
||||
if (indx2Units[i = units2Indx[uDiff - 1]] != uDiff) {
|
||||
insertNode(p, --i);
|
||||
p += U2B(i = indx2Units[i]);
|
||||
uDiff -= i;
|
||||
}
|
||||
insertNode(p, units2Indx[uDiff - 1]);
|
||||
}
|
||||
|
||||
public void stopSubAllocator() {
|
||||
if (subAllocatorSize != 0) {
|
||||
subAllocatorSize = 0;
|
||||
heap = null;
|
||||
heapStart = 1;
|
||||
// rarfree(HeapStart);
|
||||
// Free temp fields
|
||||
tempRarNode = null;
|
||||
tempRarMemBlock1 = null;
|
||||
tempRarMemBlock2 = null;
|
||||
tempRarMemBlock3 = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetAllocatedMemory() {
|
||||
return subAllocatorSize;
|
||||
};
|
||||
|
||||
public boolean startSubAllocator(int SASize) {
|
||||
int t = SASize << 20;
|
||||
if (subAllocatorSize == t) {
|
||||
return true;
|
||||
}
|
||||
stopSubAllocator();
|
||||
int allocSize = t / FIXED_UNIT_SIZE * UNIT_SIZE + UNIT_SIZE;
|
||||
|
||||
// adding space for freelist (needed for poiters)
|
||||
// 1+ for null pointer
|
||||
int realAllocSize = 1 + allocSize + 4 * N_INDEXES;
|
||||
// adding space for an additional memblock
|
||||
tempMemBlockPos = realAllocSize;
|
||||
realAllocSize += RarMemBlock.size;
|
||||
|
||||
heap = new byte[realAllocSize];
|
||||
heapStart = 1;
|
||||
heapEnd = heapStart + allocSize - UNIT_SIZE;
|
||||
subAllocatorSize = t;
|
||||
// Bug fixed
|
||||
freeListPos = heapStart + allocSize;
|
||||
assert (realAllocSize - tempMemBlockPos == RarMemBlock.size) : realAllocSize
|
||||
+ " " + tempMemBlockPos + " " + RarMemBlock.size;
|
||||
|
||||
// Init freeList
|
||||
for (int i = 0, pos = freeListPos; i < freeList.length; i++, pos += RarNode.size) {
|
||||
freeList[i] = new RarNode(heap);
|
||||
freeList[i].setAddress(pos);
|
||||
}
|
||||
|
||||
// Init temp fields
|
||||
tempRarNode = new RarNode(heap);
|
||||
tempRarMemBlock1 = new RarMemBlock(heap);
|
||||
tempRarMemBlock2 = new RarMemBlock(heap);
|
||||
tempRarMemBlock3 = new RarMemBlock(heap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void glueFreeBlocks() {
|
||||
RarMemBlock s0 = tempRarMemBlock1;
|
||||
s0.setAddress(tempMemBlockPos);
|
||||
RarMemBlock p = tempRarMemBlock2;
|
||||
RarMemBlock p1 = tempRarMemBlock3;
|
||||
int i, k, sz;
|
||||
if (loUnit != hiUnit) {
|
||||
heap[loUnit] = 0;
|
||||
}
|
||||
for (i = 0, s0.setPrev(s0), s0.setNext(s0); i < N_INDEXES; i++) {
|
||||
while (freeList[i].getNext() != 0) {
|
||||
p.setAddress(removeNode(i));// =(RAR_MEM_BLK*)RemoveNode(i);
|
||||
p.insertAt(s0);// p->insertAt(&s0);
|
||||
p.setStamp(0xFFFF);// p->Stamp=0xFFFF;
|
||||
p.setNU(indx2Units[i]);// p->NU=Indx2Units[i];
|
||||
}
|
||||
}
|
||||
for (p.setAddress(s0.getNext()); p.getAddress() != s0.getAddress(); p
|
||||
.setAddress(p.getNext())) {
|
||||
// while ((p1=MBPtr(p,p->NU))->Stamp == 0xFFFF && int(p->NU)+p1->NU
|
||||
// < 0x10000)
|
||||
// Bug fixed
|
||||
p1.setAddress(MBPtr(p.getAddress(), p.getNU()));
|
||||
while (p1.getStamp() == 0xFFFF && p.getNU() + p1.getNU() < 0x10000) {
|
||||
p1.remove();
|
||||
p.setNU(p.getNU() + p1.getNU());// ->NU += p1->NU;
|
||||
p1.setAddress(MBPtr(p.getAddress(), p.getNU()));
|
||||
}
|
||||
}
|
||||
// while ((p=s0.next) != &s0)
|
||||
// Bug fixed
|
||||
p.setAddress(s0.getNext());
|
||||
while (p.getAddress() != s0.getAddress()) {
|
||||
for (p.remove(), sz = p.getNU(); sz > 128; sz -= 128, p
|
||||
.setAddress(MBPtr(p.getAddress(), 128))) {
|
||||
insertNode(p.getAddress(), N_INDEXES - 1);
|
||||
}
|
||||
if (indx2Units[i = units2Indx[sz - 1]] != sz) {
|
||||
k = sz - indx2Units[--i];
|
||||
insertNode(MBPtr(p.getAddress(), sz - k), k - 1);
|
||||
}
|
||||
insertNode(p.getAddress(), i);
|
||||
p.setAddress(s0.getNext());
|
||||
}
|
||||
}
|
||||
|
||||
private int allocUnitsRare(int indx) {
|
||||
if (glueCount == 0) {
|
||||
glueCount = 255;
|
||||
glueFreeBlocks();
|
||||
if (freeList[indx].getNext() != 0) {
|
||||
return removeNode(indx);
|
||||
}
|
||||
}
|
||||
int i = indx;
|
||||
do {
|
||||
if (++i == N_INDEXES) {
|
||||
glueCount--;
|
||||
i = U2B(indx2Units[indx]);
|
||||
int j = FIXED_UNIT_SIZE * indx2Units[indx];
|
||||
if (fakeUnitsStart - pText > j) {
|
||||
fakeUnitsStart -= j;
|
||||
unitsStart -= i;
|
||||
return unitsStart;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
} while (freeList[i].getNext() == 0);
|
||||
int retVal = removeNode(i);
|
||||
splitBlock(retVal, i, indx);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public int allocUnits(int NU) {
|
||||
int indx = units2Indx[NU - 1];
|
||||
if (freeList[indx].getNext() != 0) {
|
||||
return removeNode(indx);
|
||||
}
|
||||
int retVal = loUnit;
|
||||
loUnit += U2B(indx2Units[indx]);
|
||||
if (loUnit <= hiUnit) {
|
||||
return retVal;
|
||||
}
|
||||
loUnit -= U2B(indx2Units[indx]);
|
||||
return allocUnitsRare(indx);
|
||||
}
|
||||
|
||||
public int allocContext() {
|
||||
if (hiUnit != loUnit)
|
||||
return (hiUnit -= UNIT_SIZE);
|
||||
if (freeList[0].getNext() != 0) {
|
||||
return removeNode(0);
|
||||
}
|
||||
return allocUnitsRare(0);
|
||||
}
|
||||
|
||||
public int expandUnits(int oldPtr, int OldNU) {
|
||||
int i0 = units2Indx[OldNU - 1];
|
||||
int i1 = units2Indx[OldNU - 1 + 1];
|
||||
if (i0 == i1) {
|
||||
return oldPtr;
|
||||
}
|
||||
int ptr = allocUnits(OldNU + 1);
|
||||
if (ptr != 0) {
|
||||
// memcpy(ptr,OldPtr,U2B(OldNU));
|
||||
System.arraycopy(heap, oldPtr, heap, ptr, U2B(OldNU));
|
||||
insertNode(oldPtr, i0);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
public int shrinkUnits(int oldPtr, int oldNU, int newNU) {
|
||||
// System.out.println("SubAllocator.shrinkUnits(" + OldPtr + ", " +
|
||||
// OldNU + ", " + NewNU + ")");
|
||||
int i0 = units2Indx[oldNU - 1];
|
||||
int i1 = units2Indx[newNU - 1];
|
||||
if (i0 == i1) {
|
||||
return oldPtr;
|
||||
}
|
||||
if (freeList[i1].getNext() != 0) {
|
||||
int ptr = removeNode(i1);
|
||||
// memcpy(ptr,OldPtr,U2B(NewNU));
|
||||
// for (int i = 0; i < U2B(NewNU); i++) {
|
||||
// heap[ptr + i] = heap[OldPtr + i];
|
||||
// }
|
||||
System.arraycopy(heap, oldPtr, heap, ptr, U2B(newNU));
|
||||
insertNode(oldPtr, i0);
|
||||
return ptr;
|
||||
} else {
|
||||
splitBlock(oldPtr, i0, i1);
|
||||
return oldPtr;
|
||||
}
|
||||
}
|
||||
|
||||
public void freeUnits(int ptr, int OldNU) {
|
||||
insertNode(ptr, units2Indx[OldNU - 1]);
|
||||
}
|
||||
|
||||
public int getFakeUnitsStart() {
|
||||
return fakeUnitsStart;
|
||||
}
|
||||
|
||||
public void setFakeUnitsStart(int fakeUnitsStart) {
|
||||
this.fakeUnitsStart = fakeUnitsStart;
|
||||
}
|
||||
|
||||
public int getHeapEnd() {
|
||||
return heapEnd;
|
||||
}
|
||||
|
||||
public int getPText() {
|
||||
return pText;
|
||||
}
|
||||
|
||||
public void setPText(int text) {
|
||||
pText = text;
|
||||
}
|
||||
|
||||
public void decPText(int dPText) {
|
||||
setPText(getPText() - dPText);
|
||||
}
|
||||
|
||||
public int getUnitsStart() {
|
||||
return unitsStart;
|
||||
}
|
||||
|
||||
public void setUnitsStart(int unitsStart) {
|
||||
this.unitsStart = unitsStart;
|
||||
}
|
||||
|
||||
public void initSubAllocator() {
|
||||
int i, k;
|
||||
Arrays
|
||||
.fill(heap, freeListPos, freeListPos + sizeOfFreeList(),
|
||||
(byte) 0);
|
||||
|
||||
pText = heapStart;
|
||||
|
||||
int size2 = FIXED_UNIT_SIZE
|
||||
* (subAllocatorSize / 8 / FIXED_UNIT_SIZE * 7);
|
||||
int realSize2 = size2 / FIXED_UNIT_SIZE * UNIT_SIZE;
|
||||
int size1 = subAllocatorSize - size2;
|
||||
int realSize1 = size1 / FIXED_UNIT_SIZE * UNIT_SIZE + size1
|
||||
% FIXED_UNIT_SIZE;
|
||||
hiUnit = heapStart + subAllocatorSize;
|
||||
loUnit = unitsStart = heapStart + realSize1;
|
||||
fakeUnitsStart = heapStart + size1;
|
||||
hiUnit = loUnit + realSize2;
|
||||
|
||||
for (i = 0, k = 1; i < N1; i++, k += 1) {
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
for (k++; i < N1 + N2; i++, k += 2) {
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
for (k++; i < N1 + N2 + N3; i++, k += 3) {
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
for (k++; i < (N1 + N2 + N3 + N4); i++, k += 4) {
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
|
||||
for (glueCount = 0, k = 0, i = 0; k < 128; k++) {
|
||||
i += ((indx2Units[i] < (k + 1)) ? 1 : 0);
|
||||
units2Indx[k] = i & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int sizeOfFreeList() {
|
||||
return freeList.length * RarNode.size;
|
||||
}
|
||||
|
||||
public byte[] getHeap() {
|
||||
return heap;
|
||||
}
|
||||
|
||||
// Debug
|
||||
// public void dumpHeap() {
|
||||
// File file = new File("P:\\test\\heapdumpj");
|
||||
// OutputStream out = null;
|
||||
// try {
|
||||
// out = new FileOutputStream(file);
|
||||
// out.write(heap, heapStart, heapEnd - heapStart);
|
||||
// out.flush();
|
||||
// System.out.println("Heap dumped to " + file.getAbsolutePath());
|
||||
// }
|
||||
// catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// finally {
|
||||
// FileUtil.close(out);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Debug
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("SubAllocator[");
|
||||
buffer.append("\n subAllocatorSize=");
|
||||
buffer.append(subAllocatorSize);
|
||||
buffer.append("\n glueCount=");
|
||||
buffer.append(glueCount);
|
||||
buffer.append("\n heapStart=");
|
||||
buffer.append(heapStart);
|
||||
buffer.append("\n loUnit=");
|
||||
buffer.append(loUnit);
|
||||
buffer.append("\n hiUnit=");
|
||||
buffer.append(hiUnit);
|
||||
buffer.append("\n pText=");
|
||||
buffer.append(pText);
|
||||
buffer.append("\n unitsStart=");
|
||||
buffer.append(unitsStart);
|
||||
buffer.append("\n]");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
108
junrar/src/main/java/junrar/unpack/vm/BitInput.java
Normal file
108
junrar/src/main/java/junrar/unpack/vm/BitInput.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class BitInput {
|
||||
/**
|
||||
* the max size of the input
|
||||
*/
|
||||
public static final int MAX_SIZE = 0x8000;
|
||||
protected int inAddr;
|
||||
protected int inBit;
|
||||
protected byte[] inBuf;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void InitBitInput()
|
||||
{
|
||||
inAddr=0;
|
||||
inBit=0;
|
||||
}
|
||||
/**
|
||||
* @param Bits
|
||||
*/
|
||||
public void addbits(int Bits)
|
||||
{
|
||||
Bits+=inBit;
|
||||
inAddr+=Bits>>3;
|
||||
inBit=Bits&7;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bits (unsigned short)
|
||||
*/
|
||||
public int getbits()
|
||||
{
|
||||
// int BitField=0;
|
||||
// BitField|=(int)(inBuf[inAddr] << 16)&0xFF0000;
|
||||
// BitField|=(int)(inBuf[inAddr+1] << 8)&0xff00;
|
||||
// BitField|=(int)(inBuf[inAddr+2])&0xFF;
|
||||
// BitField >>>= (8-inBit);
|
||||
// return (BitField & 0xffff);
|
||||
return (((((inBuf[inAddr] & 0xff) << 16) +
|
||||
((inBuf[inAddr+1] & 0xff) << 8) +
|
||||
((inBuf[inAddr+2] & 0xff))) >>> (8-inBit)) & 0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public BitInput()
|
||||
{
|
||||
inBuf=new byte[MAX_SIZE];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bits add the bits
|
||||
*/
|
||||
public void faddbits(int Bits)
|
||||
{
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return get the bits
|
||||
*/
|
||||
public int fgetbits()
|
||||
{
|
||||
return(getbits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates an Overfow
|
||||
* @param IncPtr how many bytes to inc
|
||||
* @return true if an Oververflow would occur
|
||||
*/
|
||||
public boolean Overflow(int IncPtr) {
|
||||
return(inAddr+IncPtr>=MAX_SIZE);
|
||||
}
|
||||
public byte[] getInBuf()
|
||||
{
|
||||
return inBuf;
|
||||
}
|
||||
|
||||
|
||||
}
|
1223
junrar/src/main/java/junrar/unpack/vm/RarVM.java
Normal file
1223
junrar/src/main/java/junrar/unpack/vm/RarVM.java
Normal file
File diff suppressed because it is too large
Load Diff
81
junrar/src/main/java/junrar/unpack/vm/VMCmdFlags.java
Normal file
81
junrar/src/main/java/junrar/unpack/vm/VMCmdFlags.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 01.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class VMCmdFlags {
|
||||
public static final byte VMCF_OP0 = 0;
|
||||
public static final byte VMCF_OP1 = 1;
|
||||
public static final byte VMCF_OP2 = 2;
|
||||
public static final byte VMCF_OPMASK = 3;
|
||||
public static final byte VMCF_BYTEMODE = 4;
|
||||
public static final byte VMCF_JUMP = 8;
|
||||
public static final byte VMCF_PROC = 16;
|
||||
public static final byte VMCF_USEFLAGS = 32;
|
||||
public static final byte VMCF_CHFLAGS = 64;
|
||||
|
||||
public static byte VM_CmdFlags[]=
|
||||
{
|
||||
/* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_JMP */ VMCF_OP1 | VMCF_JUMP ,
|
||||
/* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_PUSH */ VMCF_OP1 ,
|
||||
/* VM_POP */ VMCF_OP1 ,
|
||||
/* VM_CALL */ VMCF_OP1 | VMCF_PROC ,
|
||||
/* VM_RET */ VMCF_OP0 | VMCF_PROC ,
|
||||
/* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE ,
|
||||
/* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_PUSHA */ VMCF_OP0 ,
|
||||
/* VM_POPA */ VMCF_OP0 ,
|
||||
/* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS ,
|
||||
/* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS ,
|
||||
/* VM_MOVZX */ VMCF_OP2 ,
|
||||
/* VM_MOVSX */ VMCF_OP2 ,
|
||||
/* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
|
||||
/* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
|
||||
/* VM_PRINT */ VMCF_OP0
|
||||
};
|
||||
|
||||
}
|
226
junrar/src/main/java/junrar/unpack/vm/VMCommands.java
Normal file
226
junrar/src/main/java/junrar/unpack/vm/VMCommands.java
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum VMCommands {
|
||||
VM_MOV(0), VM_CMP(1), VM_ADD(2), VM_SUB(3), VM_JZ(4), VM_JNZ(5), VM_INC(6), VM_DEC(
|
||||
7), VM_JMP(8), VM_XOR(9), VM_AND(10), VM_OR(11), VM_TEST(12), VM_JS(
|
||||
13), VM_JNS(14), VM_JB(15), VM_JBE(16), VM_JA(17), VM_JAE(18), VM_PUSH(
|
||||
19), VM_POP(20), VM_CALL(21), VM_RET(22), VM_NOT(23), VM_SHL(24), VM_SHR(
|
||||
25), VM_SAR(26), VM_NEG(27), VM_PUSHA(28), VM_POPA(29), VM_PUSHF(30), VM_POPF(
|
||||
31), VM_MOVZX(32), VM_MOVSX(33), VM_XCHG(34), VM_MUL(35), VM_DIV(36), VM_ADC(
|
||||
37), VM_SBB(38), VM_PRINT(39),
|
||||
|
||||
// #ifdef VM_OPTIMIZE
|
||||
VM_MOVB(40), VM_MOVD(41), VM_CMPB(42), VM_CMPD(43),
|
||||
|
||||
VM_ADDB(44), VM_ADDD(45), VM_SUBB(46), VM_SUBD(47), VM_INCB(48), VM_INCD(49), VM_DECB(
|
||||
50), VM_DECD(51), VM_NEGB(52), VM_NEGD(53),
|
||||
// #endif*/
|
||||
|
||||
VM_STANDARD(54);
|
||||
|
||||
private int vmCommand;
|
||||
|
||||
private VMCommands(int vmCommand) {
|
||||
this.vmCommand = vmCommand;
|
||||
}
|
||||
|
||||
public int getVMCommand() {
|
||||
return vmCommand;
|
||||
}
|
||||
|
||||
public boolean equals(int vmCommand) {
|
||||
return this.vmCommand == vmCommand;
|
||||
}
|
||||
|
||||
public static VMCommands findVMCommand(int vmCommand) {
|
||||
if (VM_MOV.equals(vmCommand)) {
|
||||
return VM_MOV;
|
||||
}
|
||||
if (VM_CMP.equals(vmCommand)) {
|
||||
return VM_CMP;
|
||||
}
|
||||
if (VM_ADD.equals(vmCommand)) {
|
||||
return VM_ADD;
|
||||
}
|
||||
if (VM_SUB.equals(vmCommand)) {
|
||||
return VM_SUB;
|
||||
}
|
||||
if (VM_JZ.equals(vmCommand)) {
|
||||
return VM_JZ;
|
||||
}
|
||||
if (VM_JNZ.equals(vmCommand)) {
|
||||
return VM_JNZ;
|
||||
}
|
||||
if (VM_INC.equals(vmCommand)) {
|
||||
return VM_INC;
|
||||
}
|
||||
if (VM_DEC.equals(vmCommand)) {
|
||||
return VM_DEC;
|
||||
}
|
||||
if (VM_JMP.equals(vmCommand)) {
|
||||
return VM_JMP;
|
||||
}
|
||||
if (VM_XOR.equals(vmCommand)) {
|
||||
return VM_XOR;
|
||||
}
|
||||
if (VM_AND.equals(vmCommand)) {
|
||||
return VM_AND;
|
||||
}
|
||||
if (VM_OR.equals(vmCommand)) {
|
||||
return VM_OR;
|
||||
}
|
||||
if (VM_TEST.equals(vmCommand)) {
|
||||
return VM_TEST;
|
||||
}
|
||||
if (VM_JS.equals(vmCommand)) {
|
||||
return VM_JS;
|
||||
}
|
||||
if (VM_JNS.equals(vmCommand)) {
|
||||
return VM_JNS;
|
||||
}
|
||||
if (VM_JB.equals(vmCommand)) {
|
||||
return VM_JB;
|
||||
}
|
||||
if (VM_JBE.equals(vmCommand)) {
|
||||
return VM_JBE;
|
||||
}
|
||||
if (VM_JA.equals(vmCommand)) {
|
||||
return VM_JA;
|
||||
}
|
||||
if (VM_JAE.equals(vmCommand)) {
|
||||
return VM_JAE;
|
||||
}
|
||||
if (VM_PUSH.equals(vmCommand)) {
|
||||
return VM_PUSH;
|
||||
}
|
||||
if (VM_POP.equals(vmCommand)) {
|
||||
return VM_POP;
|
||||
}
|
||||
if (VM_CALL.equals(vmCommand)) {
|
||||
return VM_CALL;
|
||||
}
|
||||
if (VM_RET.equals(vmCommand)) {
|
||||
return VM_RET;
|
||||
}
|
||||
if (VM_NOT.equals(vmCommand)) {
|
||||
return VM_NOT;
|
||||
}
|
||||
if (VM_SHL.equals(vmCommand)) {
|
||||
return VM_SHL;
|
||||
}
|
||||
if (VM_SHR.equals(vmCommand)) {
|
||||
return VM_SHR;
|
||||
}
|
||||
if (VM_SAR.equals(vmCommand)) {
|
||||
return VM_SAR;
|
||||
}
|
||||
if (VM_NEG.equals(vmCommand)) {
|
||||
return VM_NEG;
|
||||
}
|
||||
if (VM_PUSHA.equals(vmCommand)) {
|
||||
return VM_PUSHA;
|
||||
}
|
||||
if (VM_POPA.equals(vmCommand)) {
|
||||
return VM_POPA;
|
||||
}
|
||||
if (VM_PUSHF.equals(vmCommand)) {
|
||||
return VM_PUSHF;
|
||||
}
|
||||
if (VM_POPF.equals(vmCommand)) {
|
||||
return VM_POPF;
|
||||
}
|
||||
if (VM_MOVZX.equals(vmCommand)) {
|
||||
return VM_MOVZX;
|
||||
}
|
||||
if (VM_MOVSX.equals(vmCommand)) {
|
||||
return VM_MOVSX;
|
||||
}
|
||||
if (VM_XCHG.equals(vmCommand)) {
|
||||
return VM_XCHG;
|
||||
}
|
||||
if (VM_MUL.equals(vmCommand)) {
|
||||
return VM_MUL;
|
||||
}
|
||||
if (VM_DIV.equals(vmCommand)) {
|
||||
return VM_DIV;
|
||||
}
|
||||
if (VM_ADC.equals(vmCommand)) {
|
||||
return VM_ADC;
|
||||
}
|
||||
if (VM_SBB.equals(vmCommand)) {
|
||||
return VM_SBB;
|
||||
}
|
||||
if (VM_PRINT.equals(vmCommand)) {
|
||||
return VM_PRINT;
|
||||
}
|
||||
if (VM_MOVB.equals(vmCommand)) {
|
||||
return VM_MOVB;
|
||||
}
|
||||
if (VM_MOVD.equals(vmCommand)) {
|
||||
return VM_MOVD;
|
||||
}
|
||||
if (VM_CMPB.equals(vmCommand)) {
|
||||
return VM_CMPB;
|
||||
}
|
||||
if (VM_CMPD.equals(vmCommand)) {
|
||||
return VM_CMPD;
|
||||
}
|
||||
if (VM_ADDB.equals(vmCommand)) {
|
||||
return VM_ADDB;
|
||||
}
|
||||
if (VM_ADDD.equals(vmCommand)) {
|
||||
return VM_ADDD;
|
||||
}
|
||||
if (VM_SUBB.equals(vmCommand)) {
|
||||
return VM_SUBB;
|
||||
}
|
||||
if (VM_SUBD.equals(vmCommand)) {
|
||||
return VM_SUBD;
|
||||
}
|
||||
if (VM_INCB.equals(vmCommand)) {
|
||||
return VM_INCB;
|
||||
}
|
||||
if (VM_INCD.equals(vmCommand)) {
|
||||
return VM_INCD;
|
||||
}
|
||||
if (VM_DECB.equals(vmCommand)) {
|
||||
return VM_DECB;
|
||||
}
|
||||
if (VM_DECD.equals(vmCommand)) {
|
||||
return VM_DECD;
|
||||
}
|
||||
if (VM_NEGB.equals(vmCommand)) {
|
||||
return VM_NEGB;
|
||||
}
|
||||
if (VM_NEGD.equals(vmCommand)) {
|
||||
return VM_NEGD;
|
||||
}
|
||||
if (VM_STANDARD.equals(vmCommand)) {
|
||||
return VM_STANDARD;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
79
junrar/src/main/java/junrar/unpack/vm/VMFlags.java
Normal file
79
junrar/src/main/java/junrar/unpack/vm/VMFlags.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum VMFlags {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
VM_FC (1),
|
||||
/**
|
||||
*
|
||||
*/
|
||||
VM_FZ (2),
|
||||
/**
|
||||
*
|
||||
*/
|
||||
VM_FS (0x80000000);
|
||||
|
||||
private int flag;
|
||||
|
||||
private VMFlags(int flag){
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the VMFlags Type of the given int or null
|
||||
* @param flag as int
|
||||
* @return VMFlag of the int value
|
||||
*/
|
||||
public static VMFlags findFlag(int flag){
|
||||
if(VM_FC.equals(flag)){
|
||||
return VM_FC;
|
||||
}
|
||||
if(VM_FS.equals(flag)){
|
||||
return VM_FS;
|
||||
}
|
||||
if(VM_FZ.equals(flag)){
|
||||
return VM_FZ;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the flag provided as int is equal to the enum
|
||||
* @param flag
|
||||
* @return returns true if the flag is equal to the enum
|
||||
*/
|
||||
public boolean equals(int flag){
|
||||
return this.flag == flag;
|
||||
}
|
||||
/**
|
||||
* @return the flag as int
|
||||
*/
|
||||
public int getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
}
|
66
junrar/src/main/java/junrar/unpack/vm/VMOpType.java
Normal file
66
junrar/src/main/java/junrar/unpack/vm/VMOpType.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum VMOpType {
|
||||
VM_OPREG (0),
|
||||
VM_OPINT (1),
|
||||
VM_OPREGMEM (2),
|
||||
VM_OPNONE (3);
|
||||
|
||||
private int opType;
|
||||
|
||||
private VMOpType(int opType){
|
||||
this.opType=opType;
|
||||
}
|
||||
|
||||
public int getOpType() {
|
||||
return opType;
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(int opType){
|
||||
return this.opType == opType;
|
||||
}
|
||||
public static VMOpType findOpType(int opType){
|
||||
|
||||
if (VM_OPREG.equals(opType)) {
|
||||
return VM_OPREG;
|
||||
}
|
||||
|
||||
|
||||
if (VM_OPINT.equals(opType)) {
|
||||
return VM_OPINT;
|
||||
}
|
||||
|
||||
if (VM_OPREGMEM.equals(opType)) {
|
||||
return VM_OPREGMEM;
|
||||
}
|
||||
|
||||
if (VM_OPNONE.equals(opType)) {
|
||||
return VM_OPNONE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
57
junrar/src/main/java/junrar/unpack/vm/VMPreparedCommand.java
Normal file
57
junrar/src/main/java/junrar/unpack/vm/VMPreparedCommand.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class VMPreparedCommand {
|
||||
private VMCommands OpCode;
|
||||
private boolean ByteMode;
|
||||
private VMPreparedOperand Op1 = new VMPreparedOperand();
|
||||
private VMPreparedOperand Op2 = new VMPreparedOperand();
|
||||
|
||||
public boolean isByteMode() {
|
||||
return ByteMode;
|
||||
}
|
||||
public void setByteMode(boolean byteMode) {
|
||||
ByteMode = byteMode;
|
||||
}
|
||||
public VMPreparedOperand getOp1() {
|
||||
return Op1;
|
||||
}
|
||||
public void setOp1(VMPreparedOperand op1) {
|
||||
Op1 = op1;
|
||||
}
|
||||
public VMPreparedOperand getOp2() {
|
||||
return Op2;
|
||||
}
|
||||
public void setOp2(VMPreparedOperand op2) {
|
||||
Op2 = op2;
|
||||
}
|
||||
public VMCommands getOpCode() {
|
||||
return OpCode;
|
||||
}
|
||||
public void setOpCode(VMCommands opCode) {
|
||||
OpCode = opCode;
|
||||
}
|
||||
|
||||
}
|
58
junrar/src/main/java/junrar/unpack/vm/VMPreparedOperand.java
Normal file
58
junrar/src/main/java/junrar/unpack/vm/VMPreparedOperand.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class VMPreparedOperand {
|
||||
private VMOpType Type;
|
||||
private int Data;
|
||||
private int Base;
|
||||
private int offset;
|
||||
|
||||
|
||||
public int getBase() {
|
||||
return Base;
|
||||
}
|
||||
public void setBase(int base) {
|
||||
Base = base;
|
||||
}
|
||||
public int getData() {
|
||||
return Data;
|
||||
}
|
||||
public void setData(int data) {
|
||||
Data = data;
|
||||
}
|
||||
public VMOpType getType() {
|
||||
return Type;
|
||||
}
|
||||
public void setType(VMOpType type) {
|
||||
Type = type;
|
||||
}
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
}
|
127
junrar/src/main/java/junrar/unpack/vm/VMPreparedProgram.java
Normal file
127
junrar/src/main/java/junrar/unpack/vm/VMPreparedProgram.java
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class VMPreparedProgram
|
||||
{
|
||||
private List<VMPreparedCommand> Cmd = new ArrayList<VMPreparedCommand>();
|
||||
private List<VMPreparedCommand> AltCmd =new ArrayList<VMPreparedCommand>();
|
||||
private int CmdCount;
|
||||
|
||||
|
||||
|
||||
private Vector<Byte> GlobalData = new Vector<Byte>();
|
||||
private Vector<Byte> StaticData = new Vector<Byte>(); // static data contained in DB operators
|
||||
private int InitR[] = new int[7];
|
||||
|
||||
private int FilteredDataOffset;
|
||||
private int FilteredDataSize;
|
||||
|
||||
public VMPreparedProgram()
|
||||
{
|
||||
AltCmd=null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<VMPreparedCommand> getAltCmd() {
|
||||
return AltCmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setAltCmd(List<VMPreparedCommand> altCmd) {
|
||||
AltCmd = altCmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<VMPreparedCommand> getCmd() {
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
public void setCmd(List<VMPreparedCommand> cmd) {
|
||||
Cmd = cmd;
|
||||
}
|
||||
|
||||
public int getCmdCount() {
|
||||
return CmdCount;
|
||||
}
|
||||
|
||||
public void setCmdCount(int cmdCount) {
|
||||
CmdCount = cmdCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getFilteredDataOffset() {
|
||||
return FilteredDataOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setFilteredDataOffset(int filteredDataOffset) {
|
||||
FilteredDataOffset = filteredDataOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getFilteredDataSize() {
|
||||
return FilteredDataSize;
|
||||
}
|
||||
|
||||
public void setFilteredDataSize(int filteredDataSize) {
|
||||
FilteredDataSize = filteredDataSize;
|
||||
}
|
||||
|
||||
public Vector<Byte> getGlobalData() {
|
||||
return GlobalData;
|
||||
}
|
||||
|
||||
public void setGlobalData(Vector<Byte> globalData) {
|
||||
GlobalData = globalData;
|
||||
}
|
||||
|
||||
public int[] getInitR() {
|
||||
return InitR;
|
||||
}
|
||||
|
||||
public void setInitR(int[] initR) {
|
||||
InitR = initR;
|
||||
}
|
||||
|
||||
public Vector<Byte> getStaticData() {
|
||||
return StaticData;
|
||||
}
|
||||
|
||||
public void setStaticData(Vector<Byte> staticData) {
|
||||
StaticData = staticData;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 04.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class VMStandardFilterSignature {
|
||||
private int length;
|
||||
|
||||
private int CRC;
|
||||
|
||||
private VMStandardFilters type;
|
||||
|
||||
public VMStandardFilterSignature(int length, int crc, VMStandardFilters type) {
|
||||
super();
|
||||
this.length = length;
|
||||
CRC = crc;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getCRC() {
|
||||
return CRC;
|
||||
}
|
||||
|
||||
public void setCRC(int crc) {
|
||||
CRC = crc;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public VMStandardFilters getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(VMStandardFilters type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
79
junrar/src/main/java/junrar/unpack/vm/VMStandardFilters.java
Normal file
79
junrar/src/main/java/junrar/unpack/vm/VMStandardFilters.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 31.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unpack.vm;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public enum VMStandardFilters {
|
||||
VMSF_NONE ((int)0),
|
||||
VMSF_E8 ((int)1),
|
||||
VMSF_E8E9 ((int)2),
|
||||
VMSF_ITANIUM( (int)3),
|
||||
VMSF_RGB ((int)4),
|
||||
VMSF_AUDIO ((int)5),
|
||||
VMSF_DELTA ((int)6),
|
||||
VMSF_UPCASE ((int)7);
|
||||
|
||||
private int filter;
|
||||
|
||||
private VMStandardFilters(int filter){
|
||||
this.filter=filter;
|
||||
}
|
||||
|
||||
public int getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public boolean equals(int filter){
|
||||
return this.filter == filter;
|
||||
}
|
||||
|
||||
public static VMStandardFilters findFilter(int filter){
|
||||
if (VMSF_NONE.equals(filter)) {
|
||||
return VMSF_NONE;
|
||||
}
|
||||
|
||||
if (VMSF_E8.equals(filter)) {
|
||||
return VMSF_E8;
|
||||
}
|
||||
|
||||
if (VMSF_E8E9.equals(filter)) {
|
||||
return VMSF_E8E9;
|
||||
}
|
||||
if (VMSF_ITANIUM.equals(filter)) {
|
||||
return VMSF_ITANIUM;
|
||||
}
|
||||
|
||||
if (VMSF_RGB.equals(filter)) {
|
||||
return VMSF_RGB;
|
||||
}
|
||||
|
||||
if (VMSF_AUDIO.equals(filter)) {
|
||||
return VMSF_AUDIO;
|
||||
}
|
||||
if (VMSF_DELTA.equals(filter)) {
|
||||
return VMSF_DELTA;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
67
junrar/src/main/java/junrar/unsigned/UnsignedByte.java
Normal file
67
junrar/src/main/java/junrar/unsigned/UnsignedByte.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 04.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unsigned;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class UnsignedByte {
|
||||
|
||||
public static byte longToByte(long unsignedByte1){
|
||||
return (byte) (unsignedByte1&0xff);
|
||||
}
|
||||
public static byte intToByte(int unsignedByte1){
|
||||
return (byte) (unsignedByte1&0xff);
|
||||
}
|
||||
public static byte shortToByte(short unsignedByte1){
|
||||
return (byte) (unsignedByte1&0xff);
|
||||
}
|
||||
|
||||
|
||||
public static short add(byte unsignedByte1, byte unsignedByte2){
|
||||
return (short) (unsignedByte1 + unsignedByte2);
|
||||
}
|
||||
|
||||
public static short sub(byte unsignedByte1, byte unsignedByte2){
|
||||
|
||||
return (short) (unsignedByte1 - unsignedByte2);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
//tests unsigned (signed)
|
||||
//add
|
||||
System.out.println(add((byte)0xfe,(byte)0x01)); //255 (-1)
|
||||
System.out.println(add((byte)0xff,(byte)0x01)); //0 (0)
|
||||
System.out.println(add((byte)0x7f,(byte)0x01)); //128 (-128)
|
||||
System.out.println(add((byte)0xff,(byte)0xff)); //254 (-2)
|
||||
|
||||
//sub
|
||||
System.out.println(sub((byte)0xfe,(byte)0x01)); //253 (-3)
|
||||
System.out.println(sub((byte)0x00,(byte)0x01)); //255 (-1)
|
||||
System.out.println(sub((byte)0x80,(byte)0x01)); //127 (127)
|
||||
//mul
|
||||
System.out.println((byte)-1*(byte)-1);
|
||||
}
|
||||
}
|
29
junrar/src/main/java/junrar/unsigned/UnsignedInteger.java
Normal file
29
junrar/src/main/java/junrar/unsigned/UnsignedInteger.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 04.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unsigned;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class UnsignedInteger {
|
||||
|
||||
}
|
29
junrar/src/main/java/junrar/unsigned/UnsignedLong.java
Normal file
29
junrar/src/main/java/junrar/unsigned/UnsignedLong.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 04.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unsigned;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class UnsignedLong {
|
||||
|
||||
}
|
29
junrar/src/main/java/junrar/unsigned/UnsignedShort.java
Normal file
29
junrar/src/main/java/junrar/unsigned/UnsignedShort.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
|
||||
* Original author: Edmund Wagner
|
||||
* Creation date: 04.06.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 "&"
|
||||
* "<": "<" or "<"
|
||||
* ">": ">" or ">"
|
||||
* "@": "@"
|
||||
*/
|
||||
package junrar.unsigned;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME
|
||||
*
|
||||
* @author $LastChangedBy$
|
||||
* @version $LastChangedRevision$
|
||||
*/
|
||||
public class UnsignedShort {
|
||||
|
||||
}
|
101
junrar/src/main/java/junrar/util/VolumeHelper.java
Normal file
101
junrar/src/main/java/junrar/util/VolumeHelper.java
Normal file
@ -0,0 +1,101 @@
|
||||
package junrar.util;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author alban
|
||||
*/
|
||||
public class VolumeHelper {
|
||||
private VolumeHelper() {
|
||||
}
|
||||
|
||||
// public static boolean mergeArchive(Archive archive, ComprDataIO dataIO)
|
||||
// throws IOException {
|
||||
// FileHeader hd = dataIO.getSubHeader();
|
||||
// if (hd.getUnpVersion() >= 20 && hd.getFileCRC() != 0xffffffff
|
||||
// && dataIO.getPackedCRC() != ~hd.getFileCRC()) {
|
||||
// System.err.println("Data Bad CRC");
|
||||
// }
|
||||
//
|
||||
// boolean oldNumbering = !archive.getMainHeader().isNewNumbering()
|
||||
// || archive.isOldFormat();
|
||||
// String nextName = nextVolumeName(archive.getFile().getAbsolutePath(),
|
||||
// oldNumbering);
|
||||
// File nextVolume = new File(nextName);
|
||||
// UnrarCallback callback = archive.getUnrarCallback();
|
||||
// if ((callback != null) && !callback.isNextVolumeReady(nextVolume)) {
|
||||
// return false;
|
||||
// }
|
||||
// if (!nextVolume.exists()) {
|
||||
// return false;
|
||||
// }
|
||||
// archive.setFile(nextVolume);
|
||||
// hd = archive.nextFileHeader();
|
||||
// if (hd == null) {
|
||||
// return false;
|
||||
// }
|
||||
// dataIO.init(hd);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public static String nextVolumeName(String arcName, boolean oldNumbering) {
|
||||
if (!oldNumbering) {
|
||||
// part1.rar, part2.rar, ...
|
||||
int len = arcName.length();
|
||||
int indexR = len - 1;
|
||||
while ((indexR >= 0) && !isDigit(arcName.charAt(indexR))) {
|
||||
indexR--;
|
||||
}
|
||||
int index = indexR + 1;
|
||||
int indexL = indexR - 1;
|
||||
while ((indexL >= 0) && isDigit(arcName.charAt(indexL))) {
|
||||
indexL--;
|
||||
}
|
||||
if (indexL < 0) {
|
||||
return null;
|
||||
}
|
||||
indexL++;
|
||||
StringBuilder buffer = new StringBuilder(len);
|
||||
buffer.append(arcName, 0, indexL);
|
||||
char[] digits = new char[indexR - indexL + 1];
|
||||
arcName.getChars(indexL, indexR + 1, digits, 0);
|
||||
indexR = digits.length - 1;
|
||||
while ((indexR >= 0) && (++digits[indexR]) == '9' + 1) {
|
||||
digits[indexR] = '0';
|
||||
indexR--;
|
||||
}
|
||||
if (indexR < 0) {
|
||||
buffer.append('1');
|
||||
}
|
||||
buffer.append(digits);
|
||||
buffer.append(arcName, index, len);
|
||||
return buffer.toString();
|
||||
} else {
|
||||
// .rar, .r00, .r01, ...
|
||||
int len = arcName.length();
|
||||
if ((len <= 4) || (arcName.charAt(len - 4) != '.')) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
int off = len - 3;
|
||||
buffer.append(arcName, 0, off);
|
||||
if (!isDigit(arcName.charAt(off + 1))
|
||||
|| !isDigit(arcName.charAt(off + 2))) {
|
||||
buffer.append("r00");
|
||||
} else {
|
||||
char[] ext = new char[3];
|
||||
arcName.getChars(off, len, ext, 0);
|
||||
int i = ext.length - 1;
|
||||
while ((++ext[i]) == '9' + 1) {
|
||||
ext[i] = '0';
|
||||
i--;
|
||||
}
|
||||
buffer.append(ext);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDigit(char c) {
|
||||
return (c >= '0') && (c <= '9');
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
include ':app'
|
||||
include ':app', ':junrar'
|
||||
|
Loading…
Reference in New Issue
Block a user