format
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.simple.ARM;
|
||||
* BCJ filter for little endian ARM instructions.
|
||||
*/
|
||||
public class ARMOptions extends BCJOptions {
|
||||
|
||||
private static final int ALIGNMENT = 4;
|
||||
|
||||
public ARMOptions() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.simple.ARMThumb;
|
||||
* BCJ filter for little endian ARM-Thumb instructions.
|
||||
*/
|
||||
public class ARMThumbOptions extends BCJOptions {
|
||||
|
||||
private static final int ALIGNMENT = 2;
|
||||
|
||||
public ARMThumbOptions() {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
abstract class BCJCoder implements FilterCoder {
|
||||
|
||||
public static final long X86_FILTER_ID = 0x04;
|
||||
public static final long POWERPC_FILTER_ID = 0x05;
|
||||
public static final long IA64_FILTER_ID = 0x06;
|
||||
|
||||
@@ -6,33 +6,32 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
import org.tukaani.xz.simple.*;
|
||||
|
||||
class BCJDecoder extends BCJCoder implements FilterDecoder {
|
||||
|
||||
private final long filterID;
|
||||
private final int startOffset;
|
||||
|
||||
BCJDecoder(long filterID, byte[] props)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
assert isBCJFilterID(filterID);
|
||||
this.filterID = filterID;
|
||||
|
||||
if (props.length == 0) {
|
||||
if (props.length == 0)
|
||||
startOffset = 0;
|
||||
} else if (props.length == 4) {
|
||||
else if (props.length == 4) {
|
||||
int n = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
n |= (props[i] & 0xFF) << (i * 8);
|
||||
|
||||
startOffset = n;
|
||||
} else {
|
||||
} else
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported BCJ filter properties");
|
||||
}
|
||||
"Unsupported BCJ filter properties");
|
||||
}
|
||||
|
||||
public int getMemoryUsage() {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
class BCJEncoder extends BCJCoder implements FilterEncoder {
|
||||
|
||||
private final BCJOptions options;
|
||||
private final long filterID;
|
||||
private final byte[] props;
|
||||
@@ -18,16 +18,16 @@ class BCJEncoder extends BCJCoder implements FilterEncoder {
|
||||
assert isBCJFilterID(filterID);
|
||||
int startOffset = options.getStartOffset();
|
||||
|
||||
if (startOffset == 0) {
|
||||
if (startOffset == 0)
|
||||
props = new byte[0];
|
||||
} else {
|
||||
else {
|
||||
props = new byte[4];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
props[i] = (byte)(startOffset >>> (i * 8));
|
||||
props[i] = (byte) (startOffset >>> (i * 8));
|
||||
}
|
||||
|
||||
this.filterID = filterID;
|
||||
this.options = (BCJOptions)options.clone();
|
||||
this.options = (BCJOptions) options.clone();
|
||||
}
|
||||
|
||||
public long getFilterID() {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
abstract class BCJOptions extends FilterOptions {
|
||||
|
||||
private final int alignment;
|
||||
int startOffset = 0;
|
||||
|
||||
@@ -23,10 +23,10 @@ abstract class BCJOptions extends FilterOptions {
|
||||
* The default value is <code>0</code>.
|
||||
*/
|
||||
public void setStartOffset(int startOffset)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
if ((startOffset & (alignment - 1)) != 0)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Start offset must be a multiple of " + alignment);
|
||||
"Start offset must be a multiple of " + alignment);
|
||||
|
||||
this.startOffset = startOffset;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -18,6 +17,7 @@ import org.tukaani.xz.common.DecoderUtil;
|
||||
import org.tukaani.xz.check.Check;
|
||||
|
||||
class BlockInputStream extends InputStream {
|
||||
|
||||
private final DataInputStream inData;
|
||||
private final CountingInputStream inCounted;
|
||||
private InputStream filterChain;
|
||||
@@ -35,7 +35,7 @@ class BlockInputStream extends InputStream {
|
||||
public BlockInputStream(InputStream in, Check check, int memoryLimit,
|
||||
long unpaddedSizeInIndex,
|
||||
long uncompressedSizeInIndex)
|
||||
throws IOException, IndexIndicatorException {
|
||||
throws IOException, IndexIndicatorException {
|
||||
this.check = check;
|
||||
inData = new DataInputStream(in);
|
||||
|
||||
@@ -59,7 +59,7 @@ class BlockInputStream extends InputStream {
|
||||
// Check for reserved bits in Block Flags.
|
||||
if ((buf[1] & 0x3C) != 0)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported options in XZ Block Header");
|
||||
"Unsupported options in XZ Block Header");
|
||||
|
||||
// Memory for the Filter Flags field
|
||||
int filterCount = (buf[1] & 0x03) + 1;
|
||||
@@ -69,7 +69,7 @@ class BlockInputStream extends InputStream {
|
||||
// Use a stream to parse the fields after the Block Flags field.
|
||||
// Exclude the CRC32 field at the end.
|
||||
ByteArrayInputStream bufStream = new ByteArrayInputStream(
|
||||
buf, 2, headerSize - 6);
|
||||
buf, 2, headerSize - 6);
|
||||
|
||||
try {
|
||||
// Set the maximum valid compressed size. This is overriden
|
||||
@@ -83,7 +83,7 @@ class BlockInputStream extends InputStream {
|
||||
compressedSizeInHeader = DecoderUtil.decodeVLI(bufStream);
|
||||
|
||||
if (compressedSizeInHeader == 0
|
||||
|| compressedSizeInHeader > compressedSizeLimit)
|
||||
|| compressedSizeInHeader > compressedSizeLimit)
|
||||
throw new CorruptedInputException();
|
||||
|
||||
compressedSizeLimit = compressedSizeInHeader;
|
||||
@@ -102,7 +102,7 @@ class BlockInputStream extends InputStream {
|
||||
if (filterPropsSize > bufStream.available())
|
||||
throw new CorruptedInputException();
|
||||
|
||||
filterProps[i] = new byte[(int)filterPropsSize];
|
||||
filterProps[i] = new byte[(int) filterPropsSize];
|
||||
bufStream.read(filterProps[i]);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class BlockInputStream extends InputStream {
|
||||
for (int i = bufStream.available(); i > 0; --i)
|
||||
if (bufStream.read() != 0x00)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported options in XZ Block Header");
|
||||
"Unsupported options in XZ Block Header");
|
||||
|
||||
// Validate the Blcok Header against the Index when doing
|
||||
// random access reading.
|
||||
@@ -125,26 +125,26 @@ class BlockInputStream extends InputStream {
|
||||
int headerAndCheckSize = headerSize + check.getSize();
|
||||
if (headerAndCheckSize >= unpaddedSizeInIndex)
|
||||
throw new CorruptedInputException(
|
||||
"XZ Index does not match a Block Header");
|
||||
"XZ Index does not match a Block Header");
|
||||
|
||||
// The compressed size calculated from Unpadded Size must
|
||||
// match the value stored in the Compressed Size field in
|
||||
// the Block Header.
|
||||
long compressedSizeFromIndex
|
||||
= unpaddedSizeInIndex - headerAndCheckSize;
|
||||
= unpaddedSizeInIndex - headerAndCheckSize;
|
||||
if (compressedSizeFromIndex > compressedSizeLimit
|
||||
|| (compressedSizeInHeader != -1
|
||||
&& compressedSizeInHeader != compressedSizeFromIndex))
|
||||
|| (compressedSizeInHeader != -1
|
||||
&& compressedSizeInHeader != compressedSizeFromIndex))
|
||||
throw new CorruptedInputException(
|
||||
"XZ Index does not match a Block Header");
|
||||
"XZ Index does not match a Block Header");
|
||||
|
||||
// The uncompressed size stored in the Index must match
|
||||
// the value stored in the Uncompressed Size field in
|
||||
// the Block Header.
|
||||
if (uncompressedSizeInHeader != -1
|
||||
&& uncompressedSizeInHeader != uncompressedSizeInIndex)
|
||||
&& uncompressedSizeInHeader != uncompressedSizeInIndex)
|
||||
throw new CorruptedInputException(
|
||||
"XZ Index does not match a Block Header");
|
||||
"XZ Index does not match a Block Header");
|
||||
|
||||
// For further validation, pretend that the values from the Index
|
||||
// were stored in the Block Header.
|
||||
@@ -158,7 +158,7 @@ class BlockInputStream extends InputStream {
|
||||
// supported by this decoder implementation.
|
||||
FilterDecoder[] filters = new FilterDecoder[filterIDs.length];
|
||||
|
||||
for (int i = 0; i < filters.length; ++i) {
|
||||
for (int i = 0; i < filters.length; ++i)
|
||||
if (filterIDs[i] == LZMA2Coder.FILTER_ID)
|
||||
filters[i] = new LZMA2Decoder(filterProps[i]);
|
||||
|
||||
@@ -170,8 +170,7 @@ class BlockInputStream extends InputStream {
|
||||
|
||||
else
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unknown Filter ID " + filterIDs[i]);
|
||||
}
|
||||
"Unknown Filter ID " + filterIDs[i]);
|
||||
|
||||
RawCoder.validate(filters);
|
||||
|
||||
@@ -214,10 +213,10 @@ class BlockInputStream extends InputStream {
|
||||
// Catch invalid values.
|
||||
long compressedSize = inCounted.getSize();
|
||||
if (compressedSize < 0
|
||||
|| compressedSize > compressedSizeLimit
|
||||
|| uncompressedSize < 0
|
||||
|| (uncompressedSizeInHeader != -1
|
||||
&& uncompressedSize > uncompressedSizeInHeader))
|
||||
|| compressedSize > compressedSizeLimit
|
||||
|| uncompressedSize < 0
|
||||
|| (uncompressedSizeInHeader != -1
|
||||
&& uncompressedSize > uncompressedSizeInHeader))
|
||||
throw new CorruptedInputException();
|
||||
|
||||
// Check the Block integrity as soon as possible:
|
||||
@@ -248,9 +247,9 @@ class BlockInputStream extends InputStream {
|
||||
// Validate Compressed Size and Uncompressed Size if they were
|
||||
// present in Block Header.
|
||||
if ((compressedSizeInHeader != -1
|
||||
&& compressedSizeInHeader != compressedSize)
|
||||
|| (uncompressedSizeInHeader != -1
|
||||
&& uncompressedSizeInHeader != uncompressedSize))
|
||||
&& compressedSizeInHeader != compressedSize)
|
||||
|| (uncompressedSizeInHeader != -1
|
||||
&& uncompressedSizeInHeader != uncompressedSize))
|
||||
throw new CorruptedInputException();
|
||||
|
||||
// Block Padding bytes must be zeros.
|
||||
@@ -263,7 +262,7 @@ class BlockInputStream extends InputStream {
|
||||
inData.readFully(storedCheck);
|
||||
if (!Arrays.equals(check.finish(), storedCheck))
|
||||
throw new CorruptedInputException("Integrity check ("
|
||||
+ check.getName() + ") does not match");
|
||||
+ check.getName() + ") does not match");
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.common.EncoderUtil;
|
||||
import org.tukaani.xz.check.Check;
|
||||
|
||||
class BlockOutputStream extends FinishableOutputStream {
|
||||
|
||||
private final OutputStream out;
|
||||
private final CountingOutputStream outCounted;
|
||||
private FinishableOutputStream filterChain;
|
||||
@@ -72,7 +72,7 @@ class BlockOutputStream extends FinishableOutputStream {
|
||||
throw new UnsupportedOptionsException();
|
||||
|
||||
// Block Header Size
|
||||
buf[0] = (byte)(buf.length / 4);
|
||||
buf[0] = (byte) (buf.length / 4);
|
||||
|
||||
// Write the Block Header field to the output stream.
|
||||
out.write(buf);
|
||||
@@ -85,7 +85,7 @@ class BlockOutputStream extends FinishableOutputStream {
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
tempBuf[0] = (byte)b;
|
||||
tempBuf[0] = (byte) b;
|
||||
write(tempBuf, 0, 1);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ class BlockOutputStream extends FinishableOutputStream {
|
||||
// It is very hard to trigger this exception.
|
||||
// This is just to be pedantic.
|
||||
if (compressedSize < 0 || compressedSize > compressedSizeLimit
|
||||
|| uncompressedSize < 0)
|
||||
|| uncompressedSize < 0)
|
||||
throw new XZIOException("XZ Stream has grown too big");
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
/**
|
||||
@@ -15,6 +14,7 @@ package org.tukaani.xz;
|
||||
* already read from the input stream was corrupt too.
|
||||
*/
|
||||
public class CorruptedInputException extends XZIOException {
|
||||
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ public class CorruptedInputException extends XZIOException {
|
||||
* Creates a new CorruptedInputException with
|
||||
* the specified error detail message.
|
||||
*
|
||||
* @param s error detail message
|
||||
* @param s error detail message
|
||||
*/
|
||||
public CorruptedInputException(String s) {
|
||||
super(s);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
@@ -17,6 +16,7 @@ import java.io.IOException;
|
||||
* Counts the number of bytes read from an input stream.
|
||||
*/
|
||||
class CountingInputStream extends FilterInputStream {
|
||||
|
||||
private long size = 0;
|
||||
|
||||
public CountingInputStream(InputStream in) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -21,6 +20,7 @@ import java.io.IOException;
|
||||
* using this as the output stream for a chain of raw filters.
|
||||
*/
|
||||
class CountingOutputStream extends FinishableOutputStream {
|
||||
|
||||
private final OutputStream out;
|
||||
private long size = 0;
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
abstract class DeltaCoder implements FilterCoder {
|
||||
|
||||
public static final long FILTER_ID = 0x03;
|
||||
|
||||
public boolean changesSize() {
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
class DeltaDecoder extends DeltaCoder implements FilterDecoder {
|
||||
|
||||
private final int distance;
|
||||
|
||||
DeltaDecoder(byte[] props) throws UnsupportedOptionsException {
|
||||
if (props.length != 1)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported Delta filter properties");
|
||||
"Unsupported Delta filter properties");
|
||||
|
||||
distance = (props[0] & 0xFF) + 1;
|
||||
}
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
class DeltaEncoder extends DeltaCoder implements FilterEncoder {
|
||||
|
||||
private final DeltaOptions options;
|
||||
private final byte[] props = new byte[1];
|
||||
|
||||
DeltaEncoder(DeltaOptions options) {
|
||||
props[0] = (byte)(options.getDistance() - 1);
|
||||
this.options = (DeltaOptions)options.clone();
|
||||
props[0] = (byte) (options.getDistance() - 1);
|
||||
this.options = (DeltaOptions) options.clone();
|
||||
}
|
||||
|
||||
public long getFilterID() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -21,6 +20,7 @@ import org.tukaani.xz.delta.DeltaDecoder;
|
||||
* its input stream indicates end of input.
|
||||
*/
|
||||
public class DeltaInputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* Smallest supported delta calculation distance.
|
||||
*/
|
||||
@@ -41,12 +41,12 @@ public class DeltaInputStream extends InputStream {
|
||||
/**
|
||||
* Creates a new Delta decoder with the given delta calculation distance.
|
||||
*
|
||||
* @param in input stream from which Delta filtered data
|
||||
* is read
|
||||
* @param in input stream from which Delta filtered data
|
||||
* is read
|
||||
*
|
||||
* @param distance delta calculation distance, must be in the
|
||||
* range [<code>DISTANCE_MIN</code>,
|
||||
* <code>DISTANCE_MAX</code>]
|
||||
* @param distance delta calculation distance, must be in the
|
||||
* range [<code>DISTANCE_MIN</code>,
|
||||
* <code>DISTANCE_MAX</code>]
|
||||
*/
|
||||
public DeltaInputStream(InputStream in, int distance) {
|
||||
// Check for null because otherwise null isn't detect
|
||||
@@ -61,10 +61,10 @@ public class DeltaInputStream extends InputStream {
|
||||
/**
|
||||
* Decode the next byte from this input stream.
|
||||
*
|
||||
* @return the next decoded byte, or <code>-1</code> to indicate
|
||||
* the end of input on the input stream <code>in</code>
|
||||
* @return the next decoded byte, or <code>-1</code> to indicate
|
||||
* the end of input on the input stream <code>in</code>
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
|
||||
@@ -76,17 +76,17 @@ public class DeltaInputStream extends InputStream {
|
||||
* This calls <code>in.read(buf, off, len)</code> and defilters the
|
||||
* returned data.
|
||||
*
|
||||
* @param buf target buffer for decoded data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of bytes to read
|
||||
* @param buf target buffer for decoded data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of bytes to read
|
||||
*
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the input stream <code>in</code>
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the input stream <code>in</code>
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws IOException may be thrown by underlaying input
|
||||
* stream <code>in</code>
|
||||
* @throws IOException may be thrown by underlaying input
|
||||
* stream <code>in</code>
|
||||
*/
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (len == 0)
|
||||
@@ -116,7 +116,7 @@ public class DeltaInputStream extends InputStream {
|
||||
/**
|
||||
* Calls <code>in.available()</code>.
|
||||
*
|
||||
* @return the value returned by <code>in.available()</code>
|
||||
* @return the value returned by <code>in.available()</code>
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
if (in == null)
|
||||
@@ -132,15 +132,14 @@ public class DeltaInputStream extends InputStream {
|
||||
* Closes the stream and calls <code>in.close()</code>.
|
||||
* If the stream was already closed, this does nothing.
|
||||
*
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -27,6 +26,7 @@ import java.io.InputStream;
|
||||
* FLAC will give much smaller result at much better compression speed.
|
||||
*/
|
||||
public class DeltaOptions extends FilterOptions {
|
||||
|
||||
/**
|
||||
* Smallest supported delta calculation distance.
|
||||
*/
|
||||
@@ -42,7 +42,8 @@ public class DeltaOptions extends FilterOptions {
|
||||
/**
|
||||
* Creates new Delta options and sets the delta distance to 1 byte.
|
||||
*/
|
||||
public DeltaOptions() {}
|
||||
public DeltaOptions() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Delta options and sets the distance to the given value.
|
||||
@@ -58,8 +59,8 @@ public class DeltaOptions extends FilterOptions {
|
||||
public void setDistance(int distance) throws UnsupportedOptionsException {
|
||||
if (distance < DISTANCE_MIN || distance > DISTANCE_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Delta distance must be in the range [" + DISTANCE_MIN
|
||||
+ ", " + DISTANCE_MAX + "]: " + distance);
|
||||
"Delta distance must be in the range [" + DISTANCE_MIN
|
||||
+ ", " + DISTANCE_MAX + "]: " + distance);
|
||||
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.tukaani.xz.delta.DeltaEncoder;
|
||||
|
||||
class DeltaOutputStream extends FinishableOutputStream {
|
||||
|
||||
private static final int FILTER_BUF_SIZE = 4096;
|
||||
|
||||
private FinishableOutputStream out;
|
||||
@@ -34,7 +34,7 @@ class DeltaOutputStream extends FinishableOutputStream {
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
tempBuf[0] = (byte)b;
|
||||
tempBuf[0] = (byte) b;
|
||||
write(tempBuf, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
interface FilterCoder {
|
||||
|
||||
boolean changesSize();
|
||||
|
||||
boolean nonLastOK();
|
||||
|
||||
boolean lastOK();
|
||||
}
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
interface FilterDecoder extends FilterCoder {
|
||||
|
||||
int getMemoryUsage();
|
||||
|
||||
InputStream getInputStream(InputStream in);
|
||||
}
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
interface FilterEncoder extends FilterCoder {
|
||||
|
||||
long getFilterID();
|
||||
|
||||
byte[] getFilterProps();
|
||||
|
||||
boolean supportsFlushing();
|
||||
|
||||
FinishableOutputStream getOutputStream(FinishableOutputStream out);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -17,6 +16,7 @@ import java.io.IOException;
|
||||
* Base class for filter-specific options classes.
|
||||
*/
|
||||
public abstract class FilterOptions implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets how much memory the encoder will need with
|
||||
* the given filter chain. This function simply calls
|
||||
@@ -60,7 +60,7 @@ public abstract class FilterOptions implements Cloneable {
|
||||
* to XZOutputStream.
|
||||
*/
|
||||
public abstract FinishableOutputStream getOutputStream(
|
||||
FinishableOutputStream out);
|
||||
FinishableOutputStream out);
|
||||
|
||||
/**
|
||||
* Gets how much memory the decoder will need to decompress the data
|
||||
@@ -72,9 +72,10 @@ public abstract class FilterOptions implements Cloneable {
|
||||
* Gets a raw (no XZ headers) decoder input stream using these options.
|
||||
*/
|
||||
public abstract InputStream getInputStream(InputStream in)
|
||||
throws IOException;
|
||||
throws IOException;
|
||||
|
||||
abstract FilterEncoder getFilterEncoder();
|
||||
|
||||
FilterOptions() {}
|
||||
FilterOptions() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -17,6 +16,7 @@ import java.io.IOException;
|
||||
* the underlying stream.
|
||||
*/
|
||||
public abstract class FinishableOutputStream extends OutputStream {
|
||||
|
||||
/**
|
||||
* Finish the stream without closing the underlying stream.
|
||||
* No more data may be written to the stream after finishing.
|
||||
@@ -25,7 +25,9 @@ public abstract class FinishableOutputStream extends OutputStream {
|
||||
* does nothing. Subclasses should override it if they need finishing
|
||||
* support, which is the case, for example, with compressors.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void finish() throws IOException {};
|
||||
public void finish() throws IOException {
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -18,6 +17,7 @@ import java.io.IOException;
|
||||
* people will never need this.
|
||||
*/
|
||||
public class FinishableWrapperOutputStream extends FinishableOutputStream {
|
||||
|
||||
/**
|
||||
* The {@link java.io.OutputStream OutputStream} that has been
|
||||
* wrapped into a FinishableWrapperOutputStream.
|
||||
@@ -48,7 +48,7 @@ public class FinishableWrapperOutputStream extends FinishableOutputStream {
|
||||
|
||||
/**
|
||||
* Calls {@link java.io.OutputStream#write(byte[],int,int)
|
||||
out.write(buf, off, len)}.
|
||||
* out.write(buf, off, len)}.
|
||||
*/
|
||||
public void write(byte[] buf, int off, int len) throws IOException {
|
||||
out.write(buf, off, len);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.simple.IA64;
|
||||
* BCJ filter for Itanium (IA-64) instructions.
|
||||
*/
|
||||
public class IA64Options extends BCJOptions {
|
||||
|
||||
private static final int ALIGNMENT = 16;
|
||||
|
||||
public IA64Options() {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
class IndexIndicatorException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
abstract class LZMA2Coder implements FilterCoder {
|
||||
|
||||
public static final long FILTER_ID = 0x21;
|
||||
|
||||
public boolean changesSize() {
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
class LZMA2Decoder extends LZMA2Coder implements FilterDecoder {
|
||||
|
||||
private int dictSize;
|
||||
|
||||
LZMA2Decoder(byte[] props) throws UnsupportedOptionsException {
|
||||
@@ -19,7 +19,7 @@ class LZMA2Decoder extends LZMA2Coder implements FilterDecoder {
|
||||
// are too big for int.
|
||||
if (props.length != 1 || (props[0] & 0xFF) > 37)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported LZMA2 properties");
|
||||
"Unsupported LZMA2 properties");
|
||||
|
||||
dictSize = 2 | (props[0] & 1);
|
||||
dictSize <<= (props[0] >>> 1) + 11;
|
||||
|
||||
@@ -6,30 +6,30 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import org.tukaani.xz.lzma.LZMAEncoder;
|
||||
|
||||
class LZMA2Encoder extends LZMA2Coder implements FilterEncoder {
|
||||
|
||||
private final LZMA2Options options;
|
||||
private final byte[] props = new byte[1];
|
||||
|
||||
LZMA2Encoder(LZMA2Options options) {
|
||||
if (options.getPresetDict() != null)
|
||||
throw new IllegalArgumentException(
|
||||
"XZ doesn't support a preset dictionary for now");
|
||||
"XZ doesn't support a preset dictionary for now");
|
||||
|
||||
if (options.getMode() == LZMA2Options.MODE_UNCOMPRESSED) {
|
||||
props[0] = (byte)0;
|
||||
} else {
|
||||
if (options.getMode() == LZMA2Options.MODE_UNCOMPRESSED)
|
||||
props[0] = (byte) 0;
|
||||
else {
|
||||
int d = Math.max(options.getDictSize(),
|
||||
LZMA2Options.DICT_SIZE_MIN);
|
||||
props[0] = (byte)(LZMAEncoder.getDistSlot(d - 1) - 23);
|
||||
props[0] = (byte) (LZMAEncoder.getDistSlot(d - 1) - 23);
|
||||
}
|
||||
|
||||
// Make a private copy so that the caller is free to change its copy.
|
||||
this.options = (LZMA2Options)options.clone();
|
||||
this.options = (LZMA2Options) options.clone();
|
||||
}
|
||||
|
||||
public long getFilterID() {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -21,6 +20,7 @@ import org.tukaani.xz.lzma.LZMADecoder;
|
||||
* Decompresses a raw LZMA2 stream (no XZ headers).
|
||||
*/
|
||||
public class LZMA2InputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* Smallest valid LZMA2 dictionary size.
|
||||
* <p>
|
||||
@@ -47,7 +47,7 @@ public class LZMA2InputStream extends InputStream {
|
||||
|
||||
private final LZDecoder lz;
|
||||
private final RangeDecoderFromBuffer rc
|
||||
= new RangeDecoderFromBuffer(COMPRESSED_SIZE_MAX);
|
||||
= new RangeDecoderFromBuffer(COMPRESSED_SIZE_MAX);
|
||||
private LZMADecoder lzma;
|
||||
|
||||
private int uncompressedSize = 0;
|
||||
@@ -65,11 +65,11 @@ public class LZMA2InputStream extends InputStream {
|
||||
* Gets approximate decompressor memory requirements as kibibytes for
|
||||
* the given dictionary size.
|
||||
*
|
||||
* @param dictSize LZMA2 dictionary size as bytes, must be
|
||||
* in the range [<code>DICT_SIZE_MIN</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize LZMA2 dictionary size as bytes, must be
|
||||
* in the range [<code>DICT_SIZE_MIN</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @return approximate memory requirements as kibibytes (KiB)
|
||||
* @return approximate memory requirements as kibibytes (KiB)
|
||||
*/
|
||||
public static int getMemoryUsage(int dictSize) {
|
||||
// The base state is around 30-40 KiB (probabilities etc.),
|
||||
@@ -81,7 +81,7 @@ public class LZMA2InputStream extends InputStream {
|
||||
private static int getDictSize(int dictSize) {
|
||||
if (dictSize < DICT_SIZE_MIN || dictSize > DICT_SIZE_MAX)
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported dictionary size " + dictSize);
|
||||
"Unsupported dictionary size " + dictSize);
|
||||
|
||||
// Round dictionary size upward to a multiple of 16. This way LZMA
|
||||
// can use LZDecoder.getPos() for calculating LZMA's posMask.
|
||||
@@ -106,12 +106,12 @@ public class LZMA2InputStream extends InputStream {
|
||||
* was used when compressing. If you know the uncompressed size
|
||||
* of the data, this might allow saving some memory.
|
||||
*
|
||||
* @param in input stream from which LZMA2-compressed
|
||||
* data is read
|
||||
* @param in input stream from which LZMA2-compressed
|
||||
* data is read
|
||||
*
|
||||
* @param dictSize LZMA2 dictionary size as bytes, must be
|
||||
* in the range [<code>DICT_SIZE_MIN</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize LZMA2 dictionary size as bytes, must be
|
||||
* in the range [<code>DICT_SIZE_MIN</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
*/
|
||||
public LZMA2InputStream(InputStream in, int dictSize) {
|
||||
this(in, dictSize, null);
|
||||
@@ -125,15 +125,15 @@ public class LZMA2InputStream extends InputStream {
|
||||
* If a preset dictionary was used when compressing the data, the
|
||||
* same preset dictionary must be provided when decompressing.
|
||||
*
|
||||
* @param in input stream from which LZMA2-compressed
|
||||
* data is read
|
||||
* @param in input stream from which LZMA2-compressed
|
||||
* data is read
|
||||
*
|
||||
* @param dictSize LZMA2 dictionary size as bytes, must be
|
||||
* in the range [<code>DICT_SIZE_MIN</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize LZMA2 dictionary size as bytes, must be
|
||||
* in the range [<code>DICT_SIZE_MIN</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @param presetDict preset dictionary or <code>null</code>
|
||||
* to use no preset dictionary
|
||||
* @param presetDict preset dictionary or <code>null</code>
|
||||
* to use no preset dictionary
|
||||
*/
|
||||
public LZMA2InputStream(InputStream in, int dictSize, byte[] presetDict) {
|
||||
// Check for null because otherwise null isn't detect
|
||||
@@ -155,17 +155,17 @@ public class LZMA2InputStream extends InputStream {
|
||||
* may be inefficient. Wrap it in <code>java.io.BufferedInputStream</code>
|
||||
* if you need to read lots of data one byte at a time.
|
||||
*
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws CorruptedInputException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
|
||||
@@ -179,21 +179,21 @@ public class LZMA2InputStream extends InputStream {
|
||||
* bytes have been decompressed, the end of the LZMA2 stream is reached,
|
||||
* or an exception is thrown.
|
||||
*
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
*
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws CorruptedInputException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
|
||||
@@ -223,9 +223,9 @@ public class LZMA2InputStream extends InputStream {
|
||||
|
||||
int copySizeMax = Math.min(uncompressedSize, len);
|
||||
|
||||
if (!isLZMAChunk) {
|
||||
if (!isLZMAChunk)
|
||||
lz.copyUncompressed(in, copySizeMax);
|
||||
} else {
|
||||
else {
|
||||
lz.setLimit(copySizeMax);
|
||||
lzma.decode();
|
||||
if (!rc.isInBufferOK())
|
||||
@@ -263,9 +263,8 @@ public class LZMA2InputStream extends InputStream {
|
||||
needProps = true;
|
||||
needDictReset = false;
|
||||
lz.reset();
|
||||
} else if (needDictReset) {
|
||||
} else if (needDictReset)
|
||||
throw new CorruptedInputException();
|
||||
}
|
||||
|
||||
if (control >= 0x80) {
|
||||
isLZMAChunk = true;
|
||||
@@ -279,19 +278,16 @@ public class LZMA2InputStream extends InputStream {
|
||||
needProps = false;
|
||||
decodeProps();
|
||||
|
||||
} else if (needProps) {
|
||||
} else if (needProps)
|
||||
throw new CorruptedInputException();
|
||||
|
||||
} else if (control >= 0xA0) {
|
||||
else if (control >= 0xA0)
|
||||
lzma.reset();
|
||||
}
|
||||
|
||||
rc.prepareInputBuffer(in, compressedSize);
|
||||
|
||||
} else if (control > 0x02) {
|
||||
} else if (control > 0x02)
|
||||
throw new CorruptedInputException();
|
||||
|
||||
} else {
|
||||
else {
|
||||
isLZMAChunk = false;
|
||||
uncompressedSize = in.readUnsignedShort() + 1;
|
||||
}
|
||||
@@ -327,8 +323,8 @@ public class LZMA2InputStream extends InputStream {
|
||||
* will then be the number of uncompressed bytes remaining from that
|
||||
* chunk.
|
||||
*
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
if (in == null)
|
||||
@@ -344,15 +340,14 @@ public class LZMA2InputStream extends InputStream {
|
||||
* Closes the stream and calls <code>in.close()</code>.
|
||||
* If the stream was already closed, this does nothing.
|
||||
*
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -22,6 +21,7 @@ import org.tukaani.xz.lzma.LZMAEncoder;
|
||||
* <code>LZMA2Options(int)</code>.
|
||||
*/
|
||||
public class LZMA2Options extends FilterOptions {
|
||||
|
||||
/**
|
||||
* Minimum valid compression preset level is 0.
|
||||
*/
|
||||
@@ -124,10 +124,10 @@ public class LZMA2Options extends FilterOptions {
|
||||
public static final int MF_BT4 = LZEncoder.MF_BT4;
|
||||
|
||||
private static final int[] presetToDictSize = {
|
||||
1 << 18, 1 << 20, 1 << 21, 1 << 22, 1 << 22,
|
||||
1 << 23, 1 << 23, 1 << 24, 1 << 25, 1 << 26 };
|
||||
1 << 18, 1 << 20, 1 << 21, 1 << 22, 1 << 22,
|
||||
1 << 23, 1 << 23, 1 << 24, 1 << 25, 1 << 26};
|
||||
|
||||
private static final int[] presetToDepthLimit = { 4, 8, 24, 48 };
|
||||
private static final int[] presetToDepthLimit = {4, 8, 24, 48};
|
||||
|
||||
private int dictSize;
|
||||
private byte[] presetDict = null;
|
||||
@@ -155,8 +155,8 @@ public class LZMA2Options extends FilterOptions {
|
||||
/**
|
||||
* Creates new LZMA2 options and sets them to the given preset.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>preset</code> is not supported
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>preset</code> is not supported
|
||||
*/
|
||||
public LZMA2Options(int preset) throws UnsupportedOptionsException {
|
||||
setPreset(preset);
|
||||
@@ -165,12 +165,12 @@ public class LZMA2Options extends FilterOptions {
|
||||
/**
|
||||
* Creates new LZMA2 options and sets them to the given custom values.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* unsupported options were specified
|
||||
* @throws UnsupportedOptionsException
|
||||
* unsupported options were specified
|
||||
*/
|
||||
public LZMA2Options(int dictSize, int lc, int lp, int pb, int mode,
|
||||
int niceLen, int mf, int depthLimit)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
setDictSize(dictSize);
|
||||
setLcLp(lc, lp);
|
||||
setPb(pb);
|
||||
@@ -193,13 +193,13 @@ public class LZMA2Options extends FilterOptions {
|
||||
* 16 MiB, or 32 MiB, it is waste of memory to use the
|
||||
* presets 7, 8, or 9, respectively.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>preset</code> is not supported
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>preset</code> is not supported
|
||||
*/
|
||||
public void setPreset(int preset) throws UnsupportedOptionsException {
|
||||
if (preset < 0 || preset > 9)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported preset: " + preset);
|
||||
"Unsupported preset: " + preset);
|
||||
|
||||
lc = LC_DEFAULT;
|
||||
lp = LP_DEFAULT;
|
||||
@@ -231,19 +231,19 @@ public class LZMA2Options extends FilterOptions {
|
||||
* but sizes of 2^n and 2^n + 2^(n-1) bytes are somewhat
|
||||
* recommended.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>dictSize</code> is not supported
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>dictSize</code> is not supported
|
||||
*/
|
||||
public void setDictSize(int dictSize) throws UnsupportedOptionsException {
|
||||
if (dictSize < DICT_SIZE_MIN)
|
||||
throw new UnsupportedOptionsException(
|
||||
"LZMA2 dictionary size must be at least 4 KiB: "
|
||||
+ dictSize + " B");
|
||||
"LZMA2 dictionary size must be at least 4 KiB: "
|
||||
+ dictSize + " B");
|
||||
|
||||
if (dictSize > DICT_SIZE_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"LZMA2 dictionary size must not exceed "
|
||||
+ (DICT_SIZE_MAX >> 20) + " MiB: " + dictSize + " B");
|
||||
"LZMA2 dictionary size must not exceed "
|
||||
+ (DICT_SIZE_MAX >> 20) + " MiB: " + dictSize + " B");
|
||||
|
||||
this.dictSize = dictSize;
|
||||
}
|
||||
@@ -287,16 +287,16 @@ public class LZMA2Options extends FilterOptions {
|
||||
* Trying to exceed it will throw an exception. This function lets
|
||||
* you change both at the same time.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>lc</code> and <code>lp</code>
|
||||
* are invalid
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>lc</code> and <code>lp</code>
|
||||
* are invalid
|
||||
*/
|
||||
public void setLcLp(int lc, int lp) throws UnsupportedOptionsException {
|
||||
if (lc < 0 || lp < 0 || lc > LC_LP_MAX || lp > LC_LP_MAX
|
||||
|| lc + lp > LC_LP_MAX)
|
||||
|| lc + lp > LC_LP_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"lc + lp must not exceed " + LC_LP_MAX + ": "
|
||||
+ lc + " + " + lp);
|
||||
"lc + lp must not exceed " + LC_LP_MAX + ": "
|
||||
+ lc + " + " + lp);
|
||||
|
||||
this.lc = lc;
|
||||
this.lp = lp;
|
||||
@@ -316,17 +316,17 @@ public class LZMA2Options extends FilterOptions {
|
||||
* followed by another lower-case letter. In the US-ASCII character set,
|
||||
* the highest three bits are 010 for upper-case letters and 011 for
|
||||
* lower-case letters. When <code>lc</code> is at least 3, the literal
|
||||
* coding can take advantage of this property in the uncompressed data.
|
||||
* coding can take advantage of this property in the uncompressed data.
|
||||
* <p>
|
||||
* The default value (3) is usually good. If you want maximum compression,
|
||||
* try <code>setLc(4)</code>. Sometimes it helps a little, and sometimes it
|
||||
* makes compression worse. If it makes it worse, test for example
|
||||
* <code>setLc(2)</code> too.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>lc</code> is invalid, or the sum
|
||||
* of <code>lc</code> and <code>lp</code>
|
||||
* exceed LC_LP_MAX
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>lc</code> is invalid, or the sum
|
||||
* of <code>lc</code> and <code>lp</code>
|
||||
* exceed LC_LP_MAX
|
||||
*/
|
||||
public void setLc(int lc) throws UnsupportedOptionsException {
|
||||
setLcLp(lc, lp);
|
||||
@@ -339,10 +339,10 @@ public class LZMA2Options extends FilterOptions {
|
||||
* assumed when encoding literals. See {@link #setPb(int) setPb} for
|
||||
* more information about alignment.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>lp</code> is invalid, or the sum
|
||||
* of <code>lc</code> and <code>lp</code>
|
||||
* exceed LC_LP_MAX
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>lp</code> is invalid, or the sum
|
||||
* of <code>lc</code> and <code>lp</code>
|
||||
* exceed LC_LP_MAX
|
||||
*/
|
||||
public void setLp(int lp) throws UnsupportedOptionsException {
|
||||
setLcLp(lc, lp);
|
||||
@@ -383,13 +383,13 @@ public class LZMA2Options extends FilterOptions {
|
||||
* 16-byte alignment. It might be worth taking into account when designing
|
||||
* file formats that are likely to be often compressed with LZMA2.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>pb</code> is invalid
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>pb</code> is invalid
|
||||
*/
|
||||
public void setPb(int pb) throws UnsupportedOptionsException {
|
||||
if (pb < 0 || pb > PB_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"pb must not exceed " + PB_MAX + ": " + pb);
|
||||
"pb must not exceed " + PB_MAX + ": " + pb);
|
||||
|
||||
this.pb = pb;
|
||||
}
|
||||
@@ -416,13 +416,13 @@ public class LZMA2Options extends FilterOptions {
|
||||
* compress the data at all (and doesn't use a match finder) and will
|
||||
* simply wrap it in uncompressed LZMA2 chunks.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>mode</code> is not supported
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>mode</code> is not supported
|
||||
*/
|
||||
public void setMode(int mode) throws UnsupportedOptionsException {
|
||||
if (mode < MODE_UNCOMPRESSED || mode > MODE_NORMAL)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported compression mode: " + mode);
|
||||
"Unsupported compression mode: " + mode);
|
||||
|
||||
this.mode = mode;
|
||||
}
|
||||
@@ -441,19 +441,19 @@ public class LZMA2Options extends FilterOptions {
|
||||
* to give better compression at the expense of speed. The default
|
||||
* depends on the preset.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>niceLen</code> is invalid
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>niceLen</code> is invalid
|
||||
*/
|
||||
public void setNiceLen(int niceLen) throws UnsupportedOptionsException {
|
||||
if (niceLen < NICE_LEN_MIN)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Minimum nice length of matches is "
|
||||
+ NICE_LEN_MIN + " bytes: " + niceLen);
|
||||
"Minimum nice length of matches is "
|
||||
+ NICE_LEN_MIN + " bytes: " + niceLen);
|
||||
|
||||
if (niceLen > NICE_LEN_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Maximum nice length of matches is " + NICE_LEN_MAX
|
||||
+ ": " + niceLen);
|
||||
"Maximum nice length of matches is " + NICE_LEN_MAX
|
||||
+ ": " + niceLen);
|
||||
|
||||
this.niceLen = niceLen;
|
||||
}
|
||||
@@ -473,13 +473,13 @@ public class LZMA2Options extends FilterOptions {
|
||||
* than Binary Tree match finders. The default depends on the preset:
|
||||
* 0-3 use <code>MF_HC4</code> and 4-9 use <code>MF_BT4</code>.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>mf</code> is not supported
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>mf</code> is not supported
|
||||
*/
|
||||
public void setMatchFinder(int mf) throws UnsupportedOptionsException {
|
||||
if (mf != MF_HC4 && mf != MF_BT4)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported match finder: " + mf);
|
||||
"Unsupported match finder: " + mf);
|
||||
|
||||
this.mf = mf;
|
||||
}
|
||||
@@ -504,14 +504,14 @@ public class LZMA2Options extends FilterOptions {
|
||||
* higher than 1000 unless you are prepared to interrupt the compression
|
||||
* in case it is taking far too long.
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>depthLimit</code> is invalid
|
||||
* @throws UnsupportedOptionsException
|
||||
* <code>depthLimit</code> is invalid
|
||||
*/
|
||||
public void setDepthLimit(int depthLimit)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
if (depthLimit < 0)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Depth limit cannot be negative: " + depthLimit);
|
||||
"Depth limit cannot be negative: " + depthLimit);
|
||||
|
||||
this.depthLimit = depthLimit;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
@@ -17,6 +16,7 @@ import org.tukaani.xz.rangecoder.RangeEncoder;
|
||||
import org.tukaani.xz.lzma.LZMAEncoder;
|
||||
|
||||
class LZMA2OutputStream extends FinishableOutputStream {
|
||||
|
||||
static final int COMPRESSED_SIZE_MAX = 64 << 10;
|
||||
|
||||
private FinishableOutputStream out;
|
||||
@@ -62,10 +62,10 @@ class LZMA2OutputStream extends FinishableOutputStream {
|
||||
int dictSize = options.getDictSize();
|
||||
int extraSizeBefore = getExtraSizeBefore(dictSize);
|
||||
lzma = LZMAEncoder.getInstance(rc,
|
||||
options.getLc(), options.getLp(), options.getPb(),
|
||||
options.getMode(),
|
||||
dictSize, extraSizeBefore, options.getNiceLen(),
|
||||
options.getMatchFinder(), options.getDepthLimit());
|
||||
options.getLc(), options.getLp(), options.getPb(),
|
||||
options.getMode(),
|
||||
dictSize, extraSizeBefore, options.getNiceLen(),
|
||||
options.getMatchFinder(), options.getDepthLimit());
|
||||
|
||||
lz = lzma.getLZEncoder();
|
||||
|
||||
@@ -79,7 +79,7 @@ class LZMA2OutputStream extends FinishableOutputStream {
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
tempBuf[0] = (byte)b;
|
||||
tempBuf[0] = (byte) b;
|
||||
write(tempBuf, 0, 1);
|
||||
}
|
||||
|
||||
@@ -118,9 +118,9 @@ class LZMA2OutputStream extends FinishableOutputStream {
|
||||
|
||||
// +2 because the header of a compressed chunk is 2 bytes
|
||||
// bigger than the header of an uncompressed chunk.
|
||||
if (compressedSize + 2 < uncompressedSize) {
|
||||
if (compressedSize + 2 < uncompressedSize)
|
||||
writeLZMA(uncompressedSize, compressedSize);
|
||||
} else {
|
||||
else {
|
||||
lzma.reset();
|
||||
uncompressedSize = lzma.getUncompressedSize();
|
||||
assert uncompressedSize > 0 : uncompressedSize;
|
||||
@@ -133,20 +133,18 @@ class LZMA2OutputStream extends FinishableOutputStream {
|
||||
}
|
||||
|
||||
private void writeLZMA(int uncompressedSize, int compressedSize)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
int control;
|
||||
|
||||
if (propsNeeded) {
|
||||
if (propsNeeded)
|
||||
if (dictResetNeeded)
|
||||
control = 0x80 + (3 << 5);
|
||||
else
|
||||
control = 0x80 + (2 << 5);
|
||||
} else {
|
||||
if (stateResetNeeded)
|
||||
control = 0x80 + (1 << 5);
|
||||
else
|
||||
control = 0x80;
|
||||
}
|
||||
else if (stateResetNeeded)
|
||||
control = 0x80 + (1 << 5);
|
||||
else
|
||||
control = 0x80;
|
||||
|
||||
control |= (uncompressedSize - 1) >>> 16;
|
||||
outData.writeByte(control);
|
||||
@@ -239,11 +237,11 @@ class LZMA2OutputStream extends FinishableOutputStream {
|
||||
|
||||
public void close() throws IOException {
|
||||
if (out != null) {
|
||||
if (!finished) {
|
||||
if (!finished)
|
||||
try {
|
||||
writeEndMarker();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
out.close();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -35,6 +34,7 @@ import org.tukaani.xz.lzma.LZMADecoder;
|
||||
* @since 1.4
|
||||
*/
|
||||
public class LZMAInputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* Largest dictionary size supported by this implementation.
|
||||
* <p>
|
||||
@@ -67,28 +67,28 @@ public class LZMAInputStream extends InputStream {
|
||||
* Gets approximate decompressor memory requirements as kibibytes for
|
||||
* the given dictionary size and LZMA properties byte (lc, lp, and pb).
|
||||
*
|
||||
* @param dictSize LZMA dictionary size as bytes, should be
|
||||
* in the range [<code>0</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize LZMA dictionary size as bytes, should be
|
||||
* in the range [<code>0</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @param propsByte LZMA properties byte that encodes the values
|
||||
* of lc, lp, and pb
|
||||
* @param propsByte LZMA properties byte that encodes the values
|
||||
* of lc, lp, and pb
|
||||
*
|
||||
* @return approximate memory requirements as kibibytes (KiB)
|
||||
* @return approximate memory requirements as kibibytes (KiB)
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* if <code>dictSize</code> is outside
|
||||
* the range [<code>0</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
* @throws UnsupportedOptionsException
|
||||
* if <code>dictSize</code> is outside
|
||||
* the range [<code>0</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* if <code>propsByte</code> is invalid
|
||||
* @throws CorruptedInputException
|
||||
* if <code>propsByte</code> is invalid
|
||||
*/
|
||||
public static int getMemoryUsage(int dictSize, byte propsByte)
|
||||
throws UnsupportedOptionsException, CorruptedInputException {
|
||||
throws UnsupportedOptionsException, CorruptedInputException {
|
||||
if (dictSize < 0 || dictSize > DICT_SIZE_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"LZMA dictionary is too big for this implementation");
|
||||
"LZMA dictionary is too big for this implementation");
|
||||
|
||||
int props = propsByte & 0xFF;
|
||||
if (props > (4 * 5 + 4) * 9 + 8)
|
||||
@@ -105,17 +105,17 @@ public class LZMAInputStream extends InputStream {
|
||||
* Gets approximate decompressor memory requirements as kibibytes for
|
||||
* the given dictionary size, lc, and lp. Note that pb isn't needed.
|
||||
*
|
||||
* @param dictSize LZMA dictionary size as bytes, must be
|
||||
* in the range [<code>0</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize LZMA dictionary size as bytes, must be
|
||||
* in the range [<code>0</code>,
|
||||
* <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @param lc number of literal context bits, must be
|
||||
* in the range [0, 8]
|
||||
* @param lc number of literal context bits, must be
|
||||
* in the range [0, 8]
|
||||
*
|
||||
* @param lp number of literal position bits, must be
|
||||
* in the range [0, 4]
|
||||
* @param lp number of literal position bits, must be
|
||||
* in the range [0, 4]
|
||||
*
|
||||
* @return approximate memory requirements as kibibytes (KiB)
|
||||
* @return approximate memory requirements as kibibytes (KiB)
|
||||
*/
|
||||
public static int getMemoryUsage(int dictSize, int lc, int lp) {
|
||||
if (lc < 0 || lc > 8 || lp < 0 || lp > 4)
|
||||
@@ -135,7 +135,7 @@ public class LZMAInputStream extends InputStream {
|
||||
private static int getDictSize(int dictSize) {
|
||||
if (dictSize < 0 || dictSize > DICT_SIZE_MAX)
|
||||
throw new IllegalArgumentException(
|
||||
"LZMA dictionary is too big for this implementation");
|
||||
"LZMA dictionary is too big for this implementation");
|
||||
|
||||
// For performance reasons, use a 4 KiB dictionary if something
|
||||
// smaller was requested. It's a rare situation and the performance
|
||||
@@ -159,24 +159,24 @@ public class LZMAInputStream extends InputStream {
|
||||
* Creates a new .lzma file format decompressor without
|
||||
* a memory usage limit.
|
||||
*
|
||||
* @param in input stream from which .lzma data is read;
|
||||
* it might be a good idea to wrap it in
|
||||
* <code>BufferedInputStream</code>, see the
|
||||
* note at the top of this page
|
||||
* @param in input stream from which .lzma data is read;
|
||||
* it might be a good idea to wrap it in
|
||||
* <code>BufferedInputStream</code>, see the
|
||||
* note at the top of this page
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* file is corrupt or perhaps not in
|
||||
* the .lzma format at all
|
||||
* @throws CorruptedInputException
|
||||
* file is corrupt or perhaps not in
|
||||
* the .lzma format at all
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
*
|
||||
* @throws EOFException
|
||||
* file is truncated or perhaps not in
|
||||
* the .lzma format at all
|
||||
* @throws EOFException
|
||||
* file is truncated or perhaps not in
|
||||
* the .lzma format at all
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public LZMAInputStream(InputStream in) throws IOException {
|
||||
this(in, -1);
|
||||
@@ -186,34 +186,34 @@ public class LZMAInputStream extends InputStream {
|
||||
* Creates a new .lzma file format decompressor with an optional
|
||||
* memory usage limit.
|
||||
*
|
||||
* @param in input stream from which .lzma data is read;
|
||||
* it might be a good idea to wrap it in
|
||||
* <code>BufferedInputStream</code>, see the
|
||||
* note at the top of this page
|
||||
* @param in input stream from which .lzma data is read;
|
||||
* it might be a good idea to wrap it in
|
||||
* <code>BufferedInputStream</code>, see the
|
||||
* note at the top of this page
|
||||
*
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* file is corrupt or perhaps not in
|
||||
* the .lzma format at all
|
||||
* @throws CorruptedInputException
|
||||
* file is corrupt or perhaps not in
|
||||
* the .lzma format at all
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
*
|
||||
* @throws MemoryLimitException
|
||||
* memory usage limit was exceeded
|
||||
* @throws MemoryLimitException
|
||||
* memory usage limit was exceeded
|
||||
*
|
||||
* @throws EOFException
|
||||
* file is truncated or perhaps not in
|
||||
* the .lzma format at all
|
||||
* @throws EOFException
|
||||
* file is truncated or perhaps not in
|
||||
* the .lzma format at all
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public LZMAInputStream(InputStream in, int memoryLimit)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
DataInputStream inData = new DataInputStream(in);
|
||||
|
||||
// Properties byte (lc, lp, and pb)
|
||||
@@ -230,7 +230,7 @@ public class LZMAInputStream extends InputStream {
|
||||
// the uncompressed size beforehand.
|
||||
long uncompSize = 0;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
uncompSize |= (long)inData.readUnsignedByte() << (8 * i);
|
||||
uncompSize |= (long) inData.readUnsignedByte() << (8 * i);
|
||||
|
||||
// Check the memory usage limit.
|
||||
int memoryNeeded = getMemoryUsage(dictSize, propsByte);
|
||||
@@ -263,26 +263,26 @@ public class LZMAInputStream extends InputStream {
|
||||
* was used when compressing. If you know the uncompressed size
|
||||
* of the data, this might allow saving some memory.
|
||||
*
|
||||
* @param in input stream from which compressed
|
||||
* data is read
|
||||
* @param in input stream from which compressed
|
||||
* data is read
|
||||
*
|
||||
* @param uncompSize uncompressed size of the LZMA stream or -1
|
||||
* if the end marker is used in the LZMA stream
|
||||
* @param uncompSize uncompressed size of the LZMA stream or -1
|
||||
* if the end marker is used in the LZMA stream
|
||||
*
|
||||
* @param propsByte LZMA properties byte that has the encoded
|
||||
* values for literal context bits (lc), literal
|
||||
* position bits (lp), and position bits (pb)
|
||||
* @param propsByte LZMA properties byte that has the encoded
|
||||
* values for literal context bits (lc), literal
|
||||
* position bits (lp), and position bits (pb)
|
||||
*
|
||||
* @param dictSize dictionary size as bytes, must be in the range
|
||||
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize dictionary size as bytes, must be in the range
|
||||
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* if <code>propsByte</code> is invalid or
|
||||
* the first input byte is not 0x00
|
||||
* @throws CorruptedInputException
|
||||
* if <code>propsByte</code> is invalid or
|
||||
* the first input byte is not 0x00
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -295,37 +295,37 @@ public class LZMAInputStream extends InputStream {
|
||||
* Creates a new input stream that decompresses raw LZMA data (no .lzma
|
||||
* header) from <code>in</code> optionally with a preset dictionary.
|
||||
*
|
||||
* @param in input stream from which LZMA-compressed
|
||||
* data is read
|
||||
* @param in input stream from which LZMA-compressed
|
||||
* data is read
|
||||
*
|
||||
* @param uncompSize uncompressed size of the LZMA stream or -1
|
||||
* if the end marker is used in the LZMA stream
|
||||
* @param uncompSize uncompressed size of the LZMA stream or -1
|
||||
* if the end marker is used in the LZMA stream
|
||||
*
|
||||
* @param propsByte LZMA properties byte that has the encoded
|
||||
* values for literal context bits (lc), literal
|
||||
* position bits (lp), and position bits (pb)
|
||||
* @param propsByte LZMA properties byte that has the encoded
|
||||
* values for literal context bits (lc), literal
|
||||
* position bits (lp), and position bits (pb)
|
||||
*
|
||||
* @param dictSize dictionary size as bytes, must be in the range
|
||||
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize dictionary size as bytes, must be in the range
|
||||
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @param presetDict preset dictionary or <code>null</code>
|
||||
* to use no preset dictionary
|
||||
* @param presetDict preset dictionary or <code>null</code>
|
||||
* to use no preset dictionary
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* if <code>propsByte</code> is invalid or
|
||||
* the first input byte is not 0x00
|
||||
* @throws CorruptedInputException
|
||||
* if <code>propsByte</code> is invalid or
|
||||
* the first input byte is not 0x00
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* dictionary size or uncompressed size is too
|
||||
* big for this implementation
|
||||
*
|
||||
* @throws EOFException file is truncated or corrupt
|
||||
* @throws EOFException file is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public LZMAInputStream(InputStream in, long uncompSize, byte propsByte,
|
||||
int dictSize, byte[] presetDict)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
initialize(in, uncompSize, propsByte, dictSize, presetDict);
|
||||
}
|
||||
|
||||
@@ -333,49 +333,49 @@ public class LZMAInputStream extends InputStream {
|
||||
* Creates a new input stream that decompresses raw LZMA data (no .lzma
|
||||
* header) from <code>in</code> optionally with a preset dictionary.
|
||||
*
|
||||
* @param in input stream from which LZMA-compressed
|
||||
* data is read
|
||||
* @param in input stream from which LZMA-compressed
|
||||
* data is read
|
||||
*
|
||||
* @param uncompSize uncompressed size of the LZMA stream or -1
|
||||
* if the end marker is used in the LZMA stream
|
||||
* @param uncompSize uncompressed size of the LZMA stream or -1
|
||||
* if the end marker is used in the LZMA stream
|
||||
*
|
||||
* @param lc number of literal context bits, must be
|
||||
* in the range [0, 8]
|
||||
* @param lc number of literal context bits, must be
|
||||
* in the range [0, 8]
|
||||
*
|
||||
* @param lp number of literal position bits, must be
|
||||
* in the range [0, 4]
|
||||
* @param lp number of literal position bits, must be
|
||||
* in the range [0, 4]
|
||||
*
|
||||
* @param pb number position bits, must be
|
||||
* in the range [0, 4]
|
||||
* @param pb number position bits, must be
|
||||
* in the range [0, 4]
|
||||
*
|
||||
* @param dictSize dictionary size as bytes, must be in the range
|
||||
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
|
||||
* @param dictSize dictionary size as bytes, must be in the range
|
||||
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
|
||||
*
|
||||
* @param presetDict preset dictionary or <code>null</code>
|
||||
* to use no preset dictionary
|
||||
* @param presetDict preset dictionary or <code>null</code>
|
||||
* to use no preset dictionary
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* if the first input byte is not 0x00
|
||||
* @throws CorruptedInputException
|
||||
* if the first input byte is not 0x00
|
||||
*
|
||||
* @throws EOFException file is truncated or corrupt
|
||||
* @throws EOFException file is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public LZMAInputStream(InputStream in, long uncompSize,
|
||||
int lc, int lp, int pb,
|
||||
int dictSize, byte[] presetDict)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
initialize(in, uncompSize, lc, lp, pb, dictSize, presetDict);
|
||||
}
|
||||
|
||||
private void initialize(InputStream in, long uncompSize, byte propsByte,
|
||||
int dictSize, byte[] presetDict)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
// Validate the uncompressed size since the other "initialize" throws
|
||||
// IllegalArgumentException if uncompSize < -1.
|
||||
if (uncompSize < -1)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Uncompressed size is too big");
|
||||
"Uncompressed size is too big");
|
||||
|
||||
// Decode the properties byte. In contrast to LZMA2, there is no
|
||||
// limit of lc + lp <= 4.
|
||||
@@ -392,7 +392,7 @@ public class LZMAInputStream extends InputStream {
|
||||
// IllegalArgumentException if dictSize is not supported.
|
||||
if (dictSize < 0 || dictSize > DICT_SIZE_MAX)
|
||||
throw new UnsupportedOptionsException(
|
||||
"LZMA dictionary is too big for this implementation");
|
||||
"LZMA dictionary is too big for this implementation");
|
||||
|
||||
initialize(in, uncompSize, lc, lp, pb, dictSize, presetDict);
|
||||
}
|
||||
@@ -400,11 +400,11 @@ public class LZMAInputStream extends InputStream {
|
||||
private void initialize(InputStream in, long uncompSize,
|
||||
int lc, int lp, int pb,
|
||||
int dictSize, byte[] presetDict)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
// getDictSize validates dictSize and gives a message in
|
||||
// the exception too, so skip validating dictSize here.
|
||||
if (uncompSize < -1 || lc < 0 || lc > 8 || lp < 0 || lp > 4
|
||||
|| pb < 0 || pb > 4)
|
||||
|| pb < 0 || pb > 4)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.in = in;
|
||||
@@ -413,7 +413,7 @@ public class LZMAInputStream extends InputStream {
|
||||
// a uselessly large dictionary buffer.
|
||||
dictSize = getDictSize(dictSize);
|
||||
if (uncompSize >= 0 && dictSize > uncompSize)
|
||||
dictSize = getDictSize((int)uncompSize);
|
||||
dictSize = getDictSize((int) uncompSize);
|
||||
|
||||
lz = new LZDecoder(getDictSize(dictSize), presetDict);
|
||||
rc = new RangeDecoderFromStream(in);
|
||||
@@ -428,17 +428,17 @@ public class LZMAInputStream extends InputStream {
|
||||
* may be inefficient. Wrap it in <code>java.io.BufferedInputStream</code>
|
||||
* if you need to read lots of data one byte at a time.
|
||||
*
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws CorruptedInputException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
|
||||
@@ -452,20 +452,20 @@ public class LZMAInputStream extends InputStream {
|
||||
* bytes have been decompressed, the end of the LZMA stream is reached,
|
||||
* or an exception is thrown.
|
||||
*
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
*
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws CorruptedInputException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException compressed input is truncated or corrupt
|
||||
* @throws EOFException compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
|
||||
@@ -492,7 +492,7 @@ public class LZMAInputStream extends InputStream {
|
||||
// won't be exceeded.
|
||||
int copySizeMax = len;
|
||||
if (remainingSize >= 0 && remainingSize < len)
|
||||
copySizeMax = (int)remainingSize;
|
||||
copySizeMax = (int) remainingSize;
|
||||
|
||||
lz.setLimit(copySizeMax);
|
||||
|
||||
@@ -555,15 +555,14 @@ public class LZMAInputStream extends InputStream {
|
||||
* Closes the stream and calls <code>in.close()</code>.
|
||||
* If the stream was already closed, this does nothing.
|
||||
*
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
/**
|
||||
@@ -17,6 +16,7 @@ package org.tukaani.xz;
|
||||
* included in the error detail message in human readable format.
|
||||
*/
|
||||
public class MemoryLimitException extends XZIOException {
|
||||
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
private final int memoryNeeded;
|
||||
@@ -28,8 +28,8 @@ public class MemoryLimitException extends XZIOException {
|
||||
* The amount of memory needed and the memory usage limit are
|
||||
* included in the error detail message.
|
||||
*
|
||||
* @param memoryNeeded amount of memory needed as kibibytes (KiB)
|
||||
* @param memoryLimit specified memory usage limit as kibibytes (KiB)
|
||||
* @param memoryNeeded amount of memory needed as kibibytes (KiB)
|
||||
* @param memoryLimit specified memory usage limit as kibibytes (KiB)
|
||||
*/
|
||||
public MemoryLimitException(int memoryNeeded, int memoryLimit) {
|
||||
super("" + memoryNeeded + " KiB of memory would be needed; limit was "
|
||||
@@ -42,7 +42,7 @@ public class MemoryLimitException extends XZIOException {
|
||||
/**
|
||||
* Gets how much memory is required to decompress the data.
|
||||
*
|
||||
* @return amount of memory needed as kibibytes (KiB)
|
||||
* @return amount of memory needed as kibibytes (KiB)
|
||||
*/
|
||||
public int getMemoryNeeded() {
|
||||
return memoryNeeded;
|
||||
@@ -52,7 +52,7 @@ public class MemoryLimitException extends XZIOException {
|
||||
* Gets what the memory usage limit was at the time the exception
|
||||
* was created.
|
||||
*
|
||||
* @return memory usage limit as kibibytes (KiB)
|
||||
* @return memory usage limit as kibibytes (KiB)
|
||||
*/
|
||||
public int getMemoryLimit() {
|
||||
return memoryLimit;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.simple.PowerPC;
|
||||
* BCJ filter for big endian PowerPC instructions.
|
||||
*/
|
||||
public class PowerPCOptions extends BCJOptions {
|
||||
|
||||
private static final int ALIGNMENT = 4;
|
||||
|
||||
public PowerPCOptions() {
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
class RawCoder {
|
||||
|
||||
static void validate(FilterCoder[] filters)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
for (int i = 0; i < filters.length - 1; ++i)
|
||||
if (!filters[i].nonLastOK())
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported XZ filter chain");
|
||||
"Unsupported XZ filter chain");
|
||||
|
||||
if (!filters[filters.length - 1].lastOK())
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported XZ filter chain");
|
||||
"Unsupported XZ filter chain");
|
||||
|
||||
int changesSizeCount = 0;
|
||||
for (int i = 0; i < filters.length; ++i)
|
||||
@@ -28,6 +28,6 @@ class RawCoder {
|
||||
|
||||
if (changesSizeCount > 3)
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported XZ filter chain");
|
||||
"Unsupported XZ filter chain");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.simple.SPARC;
|
||||
* BCJ filter for SPARC.
|
||||
*/
|
||||
public class SPARCOptions extends BCJOptions {
|
||||
|
||||
private static final int ALIGNMENT = 4;
|
||||
|
||||
public SPARCOptions() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.File;
|
||||
@@ -19,6 +18,7 @@ import java.io.FileNotFoundException;
|
||||
* in a SeekableInputStream.
|
||||
*/
|
||||
public class SeekableFileInputStream extends SeekableInputStream {
|
||||
|
||||
/**
|
||||
* The RandomAccessFile that has been wrapped
|
||||
* into a SeekableFileInputStream.
|
||||
@@ -87,7 +87,7 @@ public class SeekableFileInputStream extends SeekableInputStream {
|
||||
|
||||
/**
|
||||
* Calls {@link RandomAccessFile#getFilePointer()
|
||||
randomAccessFile.getFilePointer()}.
|
||||
* randomAccessFile.getFilePointer()}.
|
||||
*/
|
||||
public long position() throws IOException {
|
||||
return randomAccessFile.getFilePointer();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import java.io.IOException;
|
||||
* Input stream with random access support.
|
||||
*/
|
||||
public abstract class SeekableInputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* Seeks <code>n</code> bytes forward in this stream.
|
||||
* <p>
|
||||
@@ -32,11 +32,11 @@ public abstract class SeekableInputStream extends InputStream {
|
||||
* {@link java.io.InputStream#skip(long) InputStream.skip}.
|
||||
*
|
||||
* @return <code>0</code> if <code>n</code> is negative,
|
||||
* less than <code>n</code> if skipping <code>n</code>
|
||||
* bytes would seek past the end of the file,
|
||||
* <code>n</code> otherwise
|
||||
* less than <code>n</code> if skipping <code>n</code>
|
||||
* bytes would seek past the end of the file,
|
||||
* <code>n</code> otherwise
|
||||
*
|
||||
* @throws IOException might be thrown by {@link #seek(long)}
|
||||
* @throws IOException might be thrown by {@link #seek(long)}
|
||||
*/
|
||||
public long skip(long n) throws IOException {
|
||||
if (n <= 0)
|
||||
@@ -72,10 +72,10 @@ public abstract class SeekableInputStream extends InputStream {
|
||||
* past the end of the stream, <code>read</code> will return
|
||||
* <code>-1</code> to indicate end of stream.
|
||||
*
|
||||
* @param pos new read position in the stream
|
||||
* @param pos new read position in the stream
|
||||
*
|
||||
* @throws IOException if <code>pos</code> is negative or if
|
||||
* a stream-specific I/O error occurs
|
||||
* @throws IOException if <code>pos</code> is negative or if
|
||||
* a stream-specific I/O error occurs
|
||||
*/
|
||||
public abstract void seek(long pos) throws IOException;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -74,6 +73,7 @@ import org.tukaani.xz.index.BlockInfo;
|
||||
* @see XZOutputStream
|
||||
*/
|
||||
public class SeekableXZInputStream extends SeekableInputStream {
|
||||
|
||||
/**
|
||||
* The input stream containing XZ compressed data.
|
||||
*/
|
||||
@@ -178,29 +178,29 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Creates a new seekable XZ decompressor without a memory usage limit.
|
||||
*
|
||||
* @param in seekable input stream containing one or more
|
||||
* XZ Streams; the whole input stream is used
|
||||
* @param in seekable input stream containing one or more
|
||||
* XZ Streams; the whole input stream is used
|
||||
*
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* XZ data is corrupt or truncated
|
||||
* @throws CorruptedInputException
|
||||
* XZ data is corrupt or truncated
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ headers seem valid but they specify
|
||||
* options not supported by this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ headers seem valid but they specify
|
||||
* options not supported by this implementation
|
||||
*
|
||||
* @throws EOFException
|
||||
* less than 6 bytes of input was available
|
||||
* from <code>in</code>, or (unlikely) the size
|
||||
* of the underlying stream got smaller while
|
||||
* this was reading from it
|
||||
* @throws EOFException
|
||||
* less than 6 bytes of input was available
|
||||
* from <code>in</code>, or (unlikely) the size
|
||||
* of the underlying stream got smaller while
|
||||
* this was reading from it
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public SeekableXZInputStream(SeekableInputStream in)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
this(in, -1);
|
||||
}
|
||||
|
||||
@@ -208,37 +208,37 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* Creates a new seekable XZ decomporessor with an optional
|
||||
* memory usage limit.
|
||||
*
|
||||
* @param in seekable input stream containing one or more
|
||||
* XZ Streams; the whole input stream is used
|
||||
* @param in seekable input stream containing one or more
|
||||
* XZ Streams; the whole input stream is used
|
||||
*
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
*
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* XZ data is corrupt or truncated
|
||||
* @throws CorruptedInputException
|
||||
* XZ data is corrupt or truncated
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ headers seem valid but they specify
|
||||
* options not supported by this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ headers seem valid but they specify
|
||||
* options not supported by this implementation
|
||||
*
|
||||
* @throws MemoryLimitException
|
||||
* decoded XZ Indexes would need more memory
|
||||
* than allowed by the memory usage limit
|
||||
* @throws MemoryLimitException
|
||||
* decoded XZ Indexes would need more memory
|
||||
* than allowed by the memory usage limit
|
||||
*
|
||||
* @throws EOFException
|
||||
* less than 6 bytes of input was available
|
||||
* from <code>in</code>, or (unlikely) the size
|
||||
* of the underlying stream got smaller while
|
||||
* this was reading from it
|
||||
* @throws EOFException
|
||||
* less than 6 bytes of input was available
|
||||
* from <code>in</code>, or (unlikely) the size
|
||||
* of the underlying stream got smaller while
|
||||
* this was reading from it
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public SeekableXZInputStream(SeekableInputStream in, int memoryLimit)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
this.in = in;
|
||||
DataInputStream inData = new DataInputStream(in);
|
||||
|
||||
@@ -255,7 +255,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
long pos = in.length();
|
||||
if ((pos & 3) != 0)
|
||||
throw new CorruptedInputException(
|
||||
"XZ file size is not a multiple of 4 bytes");
|
||||
"XZ file size is not a multiple of 4 bytes");
|
||||
|
||||
// Parse the headers starting from the end of the file.
|
||||
byte[] buf = new byte[DecoderUtil.STREAM_HEADER_SIZE];
|
||||
@@ -273,7 +273,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// Skipping more at once would be faster,
|
||||
// but usually there isn't much Stream Padding.
|
||||
if (buf[8] == 0x00 && buf[9] == 0x00 && buf[10] == 0x00
|
||||
&& buf[11] == 0x00) {
|
||||
&& buf[11] == 0x00) {
|
||||
streamPadding += 4;
|
||||
pos -= 4;
|
||||
continue;
|
||||
@@ -287,7 +287,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
StreamFlags streamFooter = DecoderUtil.decodeStreamFooter(buf);
|
||||
if (streamFooter.backwardSize >= pos)
|
||||
throw new CorruptedInputException(
|
||||
"Backward Size in XZ Stream Footer is too big");
|
||||
"Backward Size in XZ Stream Footer is too big");
|
||||
|
||||
// Check that the Check ID is supported. Store it in case this
|
||||
// is the first Stream in the file.
|
||||
@@ -309,8 +309,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// already needed so we need to recreate the exception.
|
||||
assert memoryLimit >= 0;
|
||||
throw new MemoryLimitException(
|
||||
e.getMemoryNeeded() + indexMemoryUsage,
|
||||
memoryLimit + indexMemoryUsage);
|
||||
e.getMemoryNeeded() + indexMemoryUsage,
|
||||
memoryLimit + indexMemoryUsage);
|
||||
}
|
||||
|
||||
// Update the memory usage and limit counters.
|
||||
@@ -329,7 +329,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
long off = index.getStreamSize() - DecoderUtil.STREAM_HEADER_SIZE;
|
||||
if (pos < off)
|
||||
throw new CorruptedInputException("XZ Index indicates "
|
||||
+ "too big compressed size for the XZ Stream");
|
||||
+ "too big compressed size for the XZ Stream");
|
||||
|
||||
// Seek to the beginning of this Stream.
|
||||
pos -= off;
|
||||
@@ -342,7 +342,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// Verify that the Stream Header matches the Stream Footer.
|
||||
if (!DecoderUtil.areStreamFlagsEqual(streamHeader, streamFooter))
|
||||
throw new CorruptedInputException(
|
||||
"XZ Stream Footer does not match Stream Header");
|
||||
"XZ Stream Footer does not match Stream Header");
|
||||
|
||||
// Update the total uncompressed size of the file and check that
|
||||
// it doesn't overflow.
|
||||
@@ -354,7 +354,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
blockCount += index.getRecordCount();
|
||||
if (blockCount < 0)
|
||||
throw new UnsupportedOptionsException(
|
||||
"XZ file has over " + Integer.MAX_VALUE + " Blocks");
|
||||
"XZ file has over " + Integer.MAX_VALUE + " Blocks");
|
||||
|
||||
// Add this Stream to the list of Streams.
|
||||
streams.add(index);
|
||||
@@ -371,9 +371,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// Store the relative offsets of the Streams. This way we don't
|
||||
// need to recalculate them in this class when seeking; the
|
||||
// IndexDecoder instances will handle them.
|
||||
IndexDecoder prev = (IndexDecoder)streams.get(streams.size() - 1);
|
||||
IndexDecoder prev = (IndexDecoder) streams.get(streams.size() - 1);
|
||||
for (int i = streams.size() - 2; i >= 0; --i) {
|
||||
IndexDecoder cur = (IndexDecoder)streams.get(i);
|
||||
IndexDecoder cur = (IndexDecoder) streams.get(i);
|
||||
cur.setOffsets(prev);
|
||||
prev = cur;
|
||||
}
|
||||
@@ -382,7 +382,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// The blockNumber will be left to -1 so that .hasNext()
|
||||
// and .setNext() work to get the first Block when starting
|
||||
// to decompress from the beginning of the file.
|
||||
IndexDecoder first = (IndexDecoder)streams.get(streams.size() - 1);
|
||||
IndexDecoder first = (IndexDecoder) streams.get(streams.size() - 1);
|
||||
curBlockInfo = new BlockInfo(first);
|
||||
|
||||
// queriedBlockInfo needs to be allocated too. The Stream used for
|
||||
@@ -447,9 +447,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Gets the uncompressed start position of the given Block.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -461,9 +461,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Gets the uncompressed size of the given Block.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -477,9 +477,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* the underlying .xz file.
|
||||
* This information is rarely useful to the users of this class.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -493,9 +493,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* This together with the uncompressed size can be used to calculate
|
||||
* the compression ratio of the specific Block.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -507,9 +507,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Gets integrity check type (Check ID) of the given Block.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>.
|
||||
*
|
||||
* @see #getCheckTypes()
|
||||
*
|
||||
@@ -524,9 +524,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* Gets the number of the Block that contains the byte at the given
|
||||
* uncompressed position.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>pos < 0</code> or
|
||||
* <code>pos >= length()</code>.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>pos < 0</code> or
|
||||
* <code>pos >= length()</code>.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -538,16 +538,16 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Decompresses the next byte from this input stream.
|
||||
*
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
|
||||
@@ -561,28 +561,28 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* bytes of uncompressed data. Less than <code>len</code> bytes may
|
||||
* be read only in the following situations:
|
||||
* <ul>
|
||||
* <li>The end of the compressed data was reached successfully.</li>
|
||||
* <li>An error is detected after at least one but less than
|
||||
* <code>len</code> bytes have already been successfully
|
||||
* decompressed. The next call with non-zero <code>len</code>
|
||||
* will immediately throw the pending exception.</li>
|
||||
* <li>An exception is thrown.</li>
|
||||
* <li>The end of the compressed data was reached successfully.</li>
|
||||
* <li>An error is detected after at least one but less than
|
||||
* <code>len</code> bytes have already been successfully
|
||||
* decompressed. The next call with non-zero <code>len</code>
|
||||
* will immediately throw the pending exception.</li>
|
||||
* <li>An exception is thrown.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
*
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
|
||||
@@ -620,9 +620,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
size += ret;
|
||||
off += ret;
|
||||
len -= ret;
|
||||
} else if (ret == -1) {
|
||||
} else if (ret == -1)
|
||||
blockDecoder = null;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// We know that the file isn't simply truncated because we could
|
||||
@@ -647,8 +646,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* thrown before the number of bytes claimed to be available have
|
||||
* been read from this input stream.
|
||||
*
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
if (in == null)
|
||||
@@ -667,16 +666,15 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* Closes the stream and calls <code>in.close()</code>.
|
||||
* If the stream was already closed, this does nothing.
|
||||
*
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -690,7 +688,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Gets the current uncompressed position in this input stream.
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*/
|
||||
public long position() throws IOException {
|
||||
if (in == null)
|
||||
@@ -709,11 +707,11 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
* <code>read</code> will return <code>-1</code> to indicate
|
||||
* the end of the stream.
|
||||
*
|
||||
* @param pos new uncompressed read position
|
||||
* @param pos new uncompressed read position
|
||||
*
|
||||
* @throws XZIOException
|
||||
* if <code>pos</code> is negative, or
|
||||
* if stream has been closed
|
||||
* @throws XZIOException
|
||||
* if <code>pos</code> is negative, or
|
||||
* if stream has been closed
|
||||
*/
|
||||
public void seek(long pos) throws IOException {
|
||||
if (in == null)
|
||||
@@ -729,10 +727,10 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
/**
|
||||
* Seeks to the beginning of the given XZ Block.
|
||||
*
|
||||
* @throws XZIOException
|
||||
* if <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>,
|
||||
* or if stream has been closed
|
||||
* @throws XZIOException
|
||||
* if <code>blockNumber < 0</code> or
|
||||
* <code>blockNumber >= getBlockCount()</code>,
|
||||
* or if stream has been closed
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -826,12 +824,12 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
private void locateBlockByPos(BlockInfo info, long pos) {
|
||||
if (pos < 0 || pos >= uncompressedSize)
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid uncompressed position: " + pos);
|
||||
"Invalid uncompressed position: " + pos);
|
||||
|
||||
// Locate the Stream that contains the target position.
|
||||
IndexDecoder index;
|
||||
for (int i = 0; ; ++i) {
|
||||
index = (IndexDecoder)streams.get(i);
|
||||
for (int i = 0;; ++i) {
|
||||
index = (IndexDecoder) streams.get(i);
|
||||
if (index.hasUncompressedOffset(pos))
|
||||
break;
|
||||
}
|
||||
@@ -853,7 +851,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// Validate.
|
||||
if (blockNumber < 0 || blockNumber >= blockCount)
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid XZ Block number: " + blockNumber);
|
||||
"Invalid XZ Block number: " + blockNumber);
|
||||
|
||||
// Skip the search if info already points to the correct Block.
|
||||
if (info.blockNumber == blockNumber)
|
||||
@@ -861,8 +859,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
|
||||
// Search the Stream that contains the given Block and then
|
||||
// search the Block from that Stream.
|
||||
for (int i = 0; ; ++i) {
|
||||
IndexDecoder index = (IndexDecoder)streams.get(i);
|
||||
for (int i = 0;; ++i) {
|
||||
IndexDecoder index = (IndexDecoder) streams.get(i);
|
||||
if (index.hasRecord(blockNumber)) {
|
||||
index.setBlockInfo(info, blockNumber);
|
||||
return;
|
||||
@@ -880,14 +878,14 @@ public class SeekableXZInputStream extends SeekableInputStream {
|
||||
// runs tight when initializing a new BlockInputStream.
|
||||
blockDecoder = null;
|
||||
blockDecoder = new BlockInputStream(in, check, memoryLimit,
|
||||
curBlockInfo.unpaddedSize, curBlockInfo.uncompressedSize);
|
||||
curBlockInfo.unpaddedSize, curBlockInfo.uncompressedSize);
|
||||
} catch (MemoryLimitException e) {
|
||||
// BlockInputStream doesn't know how much memory we had
|
||||
// already needed so we need to recreate the exception.
|
||||
assert memoryLimit >= 0;
|
||||
throw new MemoryLimitException(
|
||||
e.getMemoryNeeded() + indexMemoryUsage,
|
||||
memoryLimit + indexMemoryUsage);
|
||||
e.getMemoryNeeded() + indexMemoryUsage,
|
||||
memoryLimit + indexMemoryUsage);
|
||||
} catch (IndexIndicatorException e) {
|
||||
// It cannot be Index so the file must be corrupt.
|
||||
throw new CorruptedInputException();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -14,6 +13,7 @@ import java.io.IOException;
|
||||
import org.tukaani.xz.simple.SimpleFilter;
|
||||
|
||||
class SimpleInputStream extends InputStream {
|
||||
|
||||
private static final int FILTER_BUF_SIZE = 4096;
|
||||
|
||||
private InputStream in;
|
||||
@@ -127,12 +127,11 @@ class SimpleInputStream extends InputStream {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.tukaani.xz.simple.SimpleFilter;
|
||||
|
||||
class SimpleOutputStream extends FinishableOutputStream {
|
||||
|
||||
private static final int FILTER_BUF_SIZE = 4096;
|
||||
|
||||
private FinishableOutputStream out;
|
||||
@@ -41,7 +41,7 @@ class SimpleOutputStream extends FinishableOutputStream {
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
tempBuf[0] = (byte)b;
|
||||
tempBuf[0] = (byte) b;
|
||||
write(tempBuf, 0, 1);
|
||||
}
|
||||
|
||||
@@ -124,14 +124,14 @@ class SimpleOutputStream extends FinishableOutputStream {
|
||||
|
||||
public void close() throws IOException {
|
||||
if (out != null) {
|
||||
if (!finished) {
|
||||
if (!finished)
|
||||
// out.close() must be called even if writePending() fails.
|
||||
// writePending() saves the possible exception so we can
|
||||
// ignore exceptions here.
|
||||
try {
|
||||
writePending();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
out.close();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -40,6 +39,7 @@ import org.tukaani.xz.check.Check;
|
||||
* @see XZInputStream
|
||||
*/
|
||||
public class SingleXZInputStream extends InputStream {
|
||||
|
||||
private InputStream in;
|
||||
private int memoryLimit;
|
||||
private StreamFlags streamHeaderFlags;
|
||||
@@ -59,24 +59,24 @@ public class SingleXZInputStream extends InputStream {
|
||||
* from <code>in</code>. The header of the first Block is not read
|
||||
* until <code>read</code> is called.
|
||||
*
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
*
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
*
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public SingleXZInputStream(InputStream in) throws IOException {
|
||||
initialize(in, -1);
|
||||
@@ -89,31 +89,31 @@ public class SingleXZInputStream extends InputStream {
|
||||
* This is identical to <code>SingleXZInputStream(InputStream)</code>
|
||||
* except that this takes also the <code>memoryLimit</code> argument.
|
||||
*
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
*
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
*
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
*
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public SingleXZInputStream(InputStream in, int memoryLimit)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
initialize(in, memoryLimit);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public class SingleXZInputStream extends InputStream {
|
||||
}
|
||||
|
||||
private void initialize(InputStream in, int memoryLimit)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
byte[] streamHeader = new byte[DecoderUtil.STREAM_HEADER_SIZE];
|
||||
new DataInputStream(in).readFully(streamHeader);
|
||||
initialize(in, memoryLimit, streamHeader);
|
||||
@@ -140,7 +140,7 @@ public class SingleXZInputStream extends InputStream {
|
||||
/**
|
||||
* Gets the ID of the integrity check used in this XZ Stream.
|
||||
*
|
||||
* @return the Check ID specified in the XZ Stream Header
|
||||
* @return the Check ID specified in the XZ Stream Header
|
||||
*/
|
||||
public int getCheckType() {
|
||||
return streamHeaderFlags.checkType;
|
||||
@@ -149,7 +149,7 @@ public class SingleXZInputStream extends InputStream {
|
||||
/**
|
||||
* Gets the name of the integrity check used in this XZ Stream.
|
||||
*
|
||||
* @return the name of the check specified in the XZ Stream Header
|
||||
* @return the name of the check specified in the XZ Stream Header
|
||||
*/
|
||||
public String getCheckName() {
|
||||
return check.getName();
|
||||
@@ -162,19 +162,19 @@ public class SingleXZInputStream extends InputStream {
|
||||
* may be inefficient. Wrap it in {@link java.io.BufferedInputStream}
|
||||
* if you need to read lots of data one byte at a time.
|
||||
*
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
|
||||
@@ -188,31 +188,31 @@ public class SingleXZInputStream extends InputStream {
|
||||
* bytes of uncompressed data. Less than <code>len</code> bytes may
|
||||
* be read only in the following situations:
|
||||
* <ul>
|
||||
* <li>The end of the compressed data was reached successfully.</li>
|
||||
* <li>An error is detected after at least one but less <code>len</code>
|
||||
* bytes have already been successfully decompressed.
|
||||
* The next call with non-zero <code>len</code> will immediately
|
||||
* throw the pending exception.</li>
|
||||
* <li>An exception is thrown.</li>
|
||||
* <li>The end of the compressed data was reached successfully.</li>
|
||||
* <li>An error is detected after at least one but less <code>len</code>
|
||||
* bytes have already been successfully decompressed.
|
||||
* The next call with non-zero <code>len</code> will immediately
|
||||
* throw the pending exception.</li>
|
||||
* <li>An exception is thrown.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
*
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
|
||||
@@ -234,17 +234,16 @@ public class SingleXZInputStream extends InputStream {
|
||||
|
||||
try {
|
||||
while (len > 0) {
|
||||
if (blockDecoder == null) {
|
||||
if (blockDecoder == null)
|
||||
try {
|
||||
blockDecoder = new BlockInputStream(
|
||||
in, check, memoryLimit, -1, -1);
|
||||
in, check, memoryLimit, -1, -1);
|
||||
} catch (IndexIndicatorException e) {
|
||||
indexHash.validate(in);
|
||||
validateStreamFooter();
|
||||
endReached = true;
|
||||
return size > 0 ? size : -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = blockDecoder.read(buf, off, len);
|
||||
|
||||
@@ -274,9 +273,9 @@ public class SingleXZInputStream extends InputStream {
|
||||
|
||||
if (!DecoderUtil.areStreamFlagsEqual(streamHeaderFlags,
|
||||
streamFooterFlags)
|
||||
|| indexHash.getIndexSize() != streamFooterFlags.backwardSize)
|
||||
|| indexHash.getIndexSize() != streamFooterFlags.backwardSize)
|
||||
throw new CorruptedInputException(
|
||||
"XZ Stream Footer does not match Stream Header");
|
||||
"XZ Stream Footer does not match Stream Header");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,8 +286,8 @@ public class SingleXZInputStream extends InputStream {
|
||||
* thrown before the number of bytes claimed to be available have
|
||||
* been read from this input stream.
|
||||
*
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
if (in == null)
|
||||
@@ -304,15 +303,14 @@ public class SingleXZInputStream extends InputStream {
|
||||
* Closes the stream and calls <code>in.close()</code>.
|
||||
* If the stream was already closed, this does nothing.
|
||||
*
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
class UncompressedLZMA2OutputStream extends FinishableOutputStream {
|
||||
|
||||
private FinishableOutputStream out;
|
||||
private final DataOutputStream outData;
|
||||
|
||||
private final byte[] uncompBuf
|
||||
= new byte[LZMA2OutputStream.COMPRESSED_SIZE_MAX];
|
||||
= new byte[LZMA2OutputStream.COMPRESSED_SIZE_MAX];
|
||||
private int uncompPos = 0;
|
||||
private boolean dictResetNeeded = true;
|
||||
|
||||
@@ -40,7 +40,7 @@ class UncompressedLZMA2OutputStream extends FinishableOutputStream {
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
tempBuf[0] = (byte)b;
|
||||
tempBuf[0] = (byte) b;
|
||||
write(tempBuf, 0, 1);
|
||||
}
|
||||
|
||||
@@ -131,11 +131,11 @@ class UncompressedLZMA2OutputStream extends FinishableOutputStream {
|
||||
|
||||
public void close() throws IOException {
|
||||
if (out != null) {
|
||||
if (!finished) {
|
||||
if (!finished)
|
||||
try {
|
||||
writeEndMarker();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
out.close();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
/**
|
||||
@@ -14,19 +13,21 @@ package org.tukaani.xz;
|
||||
* are detected. Some other implementation might support those options.
|
||||
*/
|
||||
public class UnsupportedOptionsException extends XZIOException {
|
||||
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
/**
|
||||
* Creates a new UnsupportedOptionsException with null
|
||||
* as its error detail message.
|
||||
*/
|
||||
public UnsupportedOptionsException() {}
|
||||
public UnsupportedOptionsException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new UnsupportedOptionsException with the given
|
||||
* error detail message.
|
||||
*
|
||||
* @param s error detail message
|
||||
* @param s error detail message
|
||||
*/
|
||||
public UnsupportedOptionsException(String s) {
|
||||
super(s);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import org.tukaani.xz.simple.X86;
|
||||
* BCJ filter for x86 (32-bit and 64-bit) instructions.
|
||||
*/
|
||||
public class X86Options extends BCJOptions {
|
||||
|
||||
private static final int ALIGNMENT = 1;
|
||||
|
||||
public X86Options() {
|
||||
|
||||
@@ -6,24 +6,24 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
/**
|
||||
* XZ constants.
|
||||
*/
|
||||
public class XZ {
|
||||
|
||||
/**
|
||||
* XZ Header Magic Bytes begin a XZ file.
|
||||
* This can be useful to detect XZ compressed data.
|
||||
*/
|
||||
public static final byte[] HEADER_MAGIC = {
|
||||
(byte)0xFD, '7', 'z', 'X', 'Z', '\0' };
|
||||
(byte) 0xFD, '7', 'z', 'X', 'Z', '\0'};
|
||||
|
||||
/**
|
||||
* XZ Footer Magic Bytes are the last bytes of a XZ Stream.
|
||||
*/
|
||||
public static final byte[] FOOTER_MAGIC = { 'Y', 'Z' };
|
||||
public static final byte[] FOOTER_MAGIC = {'Y', 'Z'};
|
||||
|
||||
/**
|
||||
* Integrity check ID indicating that no integrity check is calculated.
|
||||
@@ -49,5 +49,6 @@ public class XZ {
|
||||
*/
|
||||
public static final int CHECK_SHA256 = 10;
|
||||
|
||||
private XZ() {}
|
||||
private XZ() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
/**
|
||||
* Thrown when the input data is not in the XZ format.
|
||||
*/
|
||||
public class XZFormatException extends XZIOException {
|
||||
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
/**
|
||||
@@ -15,6 +14,7 @@ package org.tukaani.xz;
|
||||
* from <code>XZIOException</code>.
|
||||
*/
|
||||
public class XZIOException extends java.io.IOException {
|
||||
|
||||
private static final long serialVersionUID = 3L;
|
||||
|
||||
public XZIOException() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -25,7 +24,8 @@ import org.tukaani.xz.common.DecoderUtil;
|
||||
* <h4>Typical use cases</h4>
|
||||
* <p>
|
||||
* Getting an input stream to decompress a .xz file:
|
||||
* <p><blockquote><pre>
|
||||
* <p>
|
||||
* <blockquote><pre>
|
||||
* InputStream infile = new FileInputStream("foo.xz");
|
||||
* XZInputStream inxz = new XZInputStream(infile);
|
||||
* </pre></blockquote>
|
||||
@@ -42,7 +42,8 @@ import org.tukaani.xz.common.DecoderUtil;
|
||||
* the specified limit, MemoryLimitException will be thrown when reading
|
||||
* from the stream. For example, the following sets the memory usage limit
|
||||
* to 100 MiB:
|
||||
* <p><blockquote><pre>
|
||||
* <p>
|
||||
* <blockquote><pre>
|
||||
* InputStream infile = new FileInputStream("foo.xz");
|
||||
* XZInputStream inxz = new XZInputStream(infile, 100 * 1024);
|
||||
* </pre></blockquote>
|
||||
@@ -61,6 +62,7 @@ import org.tukaani.xz.common.DecoderUtil;
|
||||
* @see SingleXZInputStream
|
||||
*/
|
||||
public class XZInputStream extends InputStream {
|
||||
|
||||
private final int memoryLimit;
|
||||
private InputStream in;
|
||||
private SingleXZInputStream xzIn;
|
||||
@@ -76,24 +78,24 @@ public class XZInputStream extends InputStream {
|
||||
* from <code>in</code>. The header of the first Block is not read
|
||||
* until <code>read</code> is called.
|
||||
*
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
*
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
*
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public XZInputStream(InputStream in) throws IOException {
|
||||
this(in, -1);
|
||||
@@ -105,28 +107,28 @@ public class XZInputStream extends InputStream {
|
||||
* This is identical to <code>XZInputStream(InputStream)</code> except
|
||||
* that this takes also the <code>memoryLimit</code> argument.
|
||||
*
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
* @param in input stream from which XZ-compressed
|
||||
* data is read
|
||||
*
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
* @param memoryLimit memory usage limit in kibibytes (KiB)
|
||||
* or <code>-1</code> to impose no
|
||||
* memory usage limit
|
||||
*
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
* @throws XZFormatException
|
||||
* input is not in the XZ format
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
* @throws CorruptedInputException
|
||||
* XZ header CRC32 doesn't match
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
* @throws UnsupportedOptionsException
|
||||
* XZ header is valid but specifies options
|
||||
* not supported by this implementation
|
||||
*
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
* @throws EOFException
|
||||
* less than 12 bytes of input was available
|
||||
* from <code>in</code>
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public XZInputStream(InputStream in, int memoryLimit) throws IOException {
|
||||
this.in = in;
|
||||
@@ -141,19 +143,19 @@ public class XZInputStream extends InputStream {
|
||||
* may be inefficient. Wrap it in {@link java.io.BufferedInputStream}
|
||||
* if you need to read lots of data one byte at a time.
|
||||
*
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
* @return the next decompressed byte, or <code>-1</code>
|
||||
* to indicate the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
|
||||
@@ -167,31 +169,31 @@ public class XZInputStream extends InputStream {
|
||||
* bytes of uncompressed data. Less than <code>len</code> bytes may
|
||||
* be read only in the following situations:
|
||||
* <ul>
|
||||
* <li>The end of the compressed data was reached successfully.</li>
|
||||
* <li>An error is detected after at least one but less <code>len</code>
|
||||
* bytes have already been successfully decompressed.
|
||||
* The next call with non-zero <code>len</code> will immediately
|
||||
* throw the pending exception.</li>
|
||||
* <li>An exception is thrown.</li>
|
||||
* <li>The end of the compressed data was reached successfully.</li>
|
||||
* <li>An error is detected after at least one but less <code>len</code>
|
||||
* bytes have already been successfully decompressed.
|
||||
* The next call with non-zero <code>len</code> will immediately
|
||||
* throw the pending exception.</li>
|
||||
* <li>An exception is thrown.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
* @param buf target buffer for uncompressed data
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len maximum number of uncompressed bytes to read
|
||||
*
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
* @return number of bytes read, or <code>-1</code> to indicate
|
||||
* the end of the compressed stream
|
||||
*
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
* @throws CorruptedInputException
|
||||
* @throws UnsupportedOptionsException
|
||||
* @throws MemoryLimitException
|
||||
*
|
||||
* @throws XZIOException if the stream has been closed
|
||||
* @throws XZIOException if the stream has been closed
|
||||
*
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
* @throws EOFException
|
||||
* compressed input is truncated or corrupt
|
||||
*
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
* @throws IOException may be thrown by <code>in</code>
|
||||
*/
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
|
||||
@@ -225,9 +227,8 @@ public class XZInputStream extends InputStream {
|
||||
size += ret;
|
||||
off += ret;
|
||||
len -= ret;
|
||||
} else if (ret == -1) {
|
||||
} else if (ret == -1)
|
||||
xzIn = null;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
@@ -270,7 +271,7 @@ public class XZInputStream extends InputStream {
|
||||
// Since this isn't the first .xz Stream, it is more
|
||||
// logical to tell that the data is corrupt.
|
||||
throw new CorruptedInputException(
|
||||
"Garbage after a valid XZ Stream");
|
||||
"Garbage after a valid XZ Stream");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,8 +283,8 @@ public class XZInputStream extends InputStream {
|
||||
* thrown before the number of bytes claimed to be available have
|
||||
* been read from this input stream.
|
||||
*
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
* @return the number of uncompressed bytes that can be read
|
||||
* without blocking
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
if (in == null)
|
||||
@@ -299,15 +300,14 @@ public class XZInputStream extends InputStream {
|
||||
* Closes the stream and calls <code>in.close()</code>.
|
||||
* If the stream was already closed, this does nothing.
|
||||
*
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
* @throws IOException if thrown by <code>in.close()</code>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (in != null) {
|
||||
if (in != null)
|
||||
try {
|
||||
in.close();
|
||||
} finally {
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -23,14 +22,16 @@ import org.tukaani.xz.index.IndexEncoder;
|
||||
* <p>
|
||||
* Getting an output stream to compress with LZMA2 using the default
|
||||
* settings and the default integrity check type (CRC64):
|
||||
* <p><blockquote><pre>
|
||||
* <p>
|
||||
* <blockquote><pre>
|
||||
* FileOutputStream outfile = new FileOutputStream("foo.xz");
|
||||
* XZOutputStream outxz = new XZOutputStream(outfile, new LZMA2Options());
|
||||
* </pre></blockquote>
|
||||
* <p>
|
||||
* Using the preset level <code>8</code> for LZMA2 (the default
|
||||
* is <code>6</code>) and SHA-256 instead of CRC64 for integrity checking:
|
||||
* <p><blockquote><pre>
|
||||
* <p>
|
||||
* <blockquote><pre>
|
||||
* XZOutputStream outxz = new XZOutputStream(outfile, new LZMA2Options(8),
|
||||
* XZ.CHECK_SHA256);
|
||||
* </pre></blockquote>
|
||||
@@ -38,7 +39,8 @@ import org.tukaani.xz.index.IndexEncoder;
|
||||
* Using the x86 BCJ filter together with LZMA2 to compress x86 executables
|
||||
* and printing the memory usage information before creating the
|
||||
* XZOutputStream:
|
||||
* <p><blockquote><pre>
|
||||
* <p>
|
||||
* <blockquote><pre>
|
||||
* X86Options x86 = new X86Options();
|
||||
* LZMA2Options lzma2 = new LZMA2Options();
|
||||
* FilterOptions[] options = { x86, lzma2 };
|
||||
@@ -52,6 +54,7 @@ import org.tukaani.xz.index.IndexEncoder;
|
||||
* </pre></blockquote>
|
||||
*/
|
||||
public class XZOutputStream extends FinishableOutputStream {
|
||||
|
||||
private OutputStream out;
|
||||
private final StreamFlags streamFlags = new StreamFlags();
|
||||
private final Check check;
|
||||
@@ -78,19 +81,19 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* a single-member FilterOptions array to
|
||||
* <code>XZOutputStream(OutputStream, FilterOptions[])</code>.
|
||||
*
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
*
|
||||
* @param filterOptions
|
||||
* filter options to use
|
||||
* @param filterOptions
|
||||
* filter options to use
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
*
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
*/
|
||||
public XZOutputStream(OutputStream out, FilterOptions filterOptions)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
this(out, filterOptions, XZ.CHECK_CRC64);
|
||||
}
|
||||
|
||||
@@ -100,23 +103,23 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* passing a single-member FilterOptions array to
|
||||
* <code>XZOutputStream(OutputStream, FilterOptions[], int)</code>.
|
||||
*
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
*
|
||||
* @param filterOptions
|
||||
* filter options to use
|
||||
* @param filterOptions
|
||||
* filter options to use
|
||||
*
|
||||
* @param checkType type of the integrity check,
|
||||
* for example XZ.CHECK_CRC32
|
||||
* @param checkType type of the integrity check,
|
||||
* for example XZ.CHECK_CRC32
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
*
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
*/
|
||||
public XZOutputStream(OutputStream out, FilterOptions filterOptions,
|
||||
int checkType) throws IOException {
|
||||
this(out, new FilterOptions[] { filterOptions }, checkType);
|
||||
this(out, new FilterOptions[] {filterOptions}, checkType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,19 +127,19 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* the integrity check. This constructor is equivalent
|
||||
* <code>XZOutputStream(out, filterOptions, XZ.CHECK_CRC64)</code>.
|
||||
*
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
*
|
||||
* @param filterOptions
|
||||
* array of filter options to use
|
||||
* @param filterOptions
|
||||
* array of filter options to use
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
*
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
*/
|
||||
public XZOutputStream(OutputStream out, FilterOptions[] filterOptions)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
this(out, filterOptions, XZ.CHECK_CRC64);
|
||||
}
|
||||
|
||||
@@ -144,19 +147,19 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* Creates a new XZ compressor using 1-4 filters and the specified
|
||||
* integrity check type.
|
||||
*
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
* @param out output stream to which the compressed data
|
||||
* will be written
|
||||
*
|
||||
* @param filterOptions
|
||||
* array of filter options to use
|
||||
* @param filterOptions
|
||||
* array of filter options to use
|
||||
*
|
||||
* @param checkType type of the integrity check,
|
||||
* for example XZ.CHECK_CRC32
|
||||
* @param checkType type of the integrity check,
|
||||
* for example XZ.CHECK_CRC32
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
* @throws UnsupportedOptionsException
|
||||
* invalid filter chain
|
||||
*
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
* @throws IOException may be thrown from <code>out</code>
|
||||
*/
|
||||
public XZOutputStream(OutputStream out, FilterOptions[] filterOptions,
|
||||
int checkType) throws IOException {
|
||||
@@ -174,15 +177,15 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* This is equivalent to passing a single-member FilterOptions array
|
||||
* to <code>updateFilters(FilterOptions[])</code>.
|
||||
*
|
||||
* @param filterOptions
|
||||
* new filter to use
|
||||
* @param filterOptions
|
||||
* new filter to use
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* unsupported filter chain, or trying to change
|
||||
* the filter chain in the middle of a Block
|
||||
* @throws UnsupportedOptionsException
|
||||
* unsupported filter chain, or trying to change
|
||||
* the filter chain in the middle of a Block
|
||||
*/
|
||||
public void updateFilters(FilterOptions filterOptions)
|
||||
throws XZIOException {
|
||||
throws XZIOException {
|
||||
FilterOptions[] opts = new FilterOptions[1];
|
||||
opts[0] = filterOptions;
|
||||
updateFilters(opts);
|
||||
@@ -196,22 +199,22 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* current XZ Block before calling this function. The new filter chain
|
||||
* will then be used for the next XZ Block.
|
||||
*
|
||||
* @param filterOptions
|
||||
* new filter chain to use
|
||||
* @param filterOptions
|
||||
* new filter chain to use
|
||||
*
|
||||
* @throws UnsupportedOptionsException
|
||||
* unsupported filter chain, or trying to change
|
||||
* the filter chain in the middle of a Block
|
||||
* @throws UnsupportedOptionsException
|
||||
* unsupported filter chain, or trying to change
|
||||
* the filter chain in the middle of a Block
|
||||
*/
|
||||
public void updateFilters(FilterOptions[] filterOptions)
|
||||
throws XZIOException {
|
||||
throws XZIOException {
|
||||
if (blockEncoder != null)
|
||||
throw new UnsupportedOptionsException("Changing filter options "
|
||||
+ "in the middle of a XZ Block not implemented");
|
||||
+ "in the middle of a XZ Block not implemented");
|
||||
|
||||
if (filterOptions.length < 1 || filterOptions.length > 4)
|
||||
throw new UnsupportedOptionsException(
|
||||
"XZ filter chain must be 1-4 filters");
|
||||
"XZ filter chain must be 1-4 filters");
|
||||
|
||||
filtersSupportFlushing = true;
|
||||
FilterEncoder[] newFilters = new FilterEncoder[filterOptions.length];
|
||||
@@ -227,17 +230,17 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
/**
|
||||
* Writes one byte to be compressed.
|
||||
*
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
*
|
||||
* @throws XZIOException
|
||||
* <code>finish()</code> or <code>close()</code>
|
||||
* was already called
|
||||
* @throws XZIOException
|
||||
* <code>finish()</code> or <code>close()</code>
|
||||
* was already called
|
||||
*
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
tempBuf[0] = (byte)b;
|
||||
tempBuf[0] = (byte) b;
|
||||
write(tempBuf, 0, 1);
|
||||
}
|
||||
|
||||
@@ -249,21 +252,21 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* be written to the underlaying output stream, but be aware that
|
||||
* flushing reduces compression ratio.
|
||||
*
|
||||
* @param buf buffer of bytes to be written
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len number of bytes to write
|
||||
* @param buf buffer of bytes to be written
|
||||
* @param off start offset in <code>buf</code>
|
||||
* @param len number of bytes to write
|
||||
*
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big: total file size
|
||||
* about 8 EiB or the Index field exceeds
|
||||
* 16 GiB; you shouldn't reach these sizes
|
||||
* in practice
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big: total file size
|
||||
* about 8 EiB or the Index field exceeds
|
||||
* 16 GiB; you shouldn't reach these sizes
|
||||
* in practice
|
||||
*
|
||||
* @throws XZIOException
|
||||
* <code>finish()</code> or <code>close()</code>
|
||||
* was already called and len > 0
|
||||
* @throws XZIOException
|
||||
* <code>finish()</code> or <code>close()</code>
|
||||
* was already called and len > 0
|
||||
*
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
*/
|
||||
public void write(byte[] buf, int off, int len) throws IOException {
|
||||
if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
|
||||
@@ -303,13 +306,13 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* Doing this very often will increase the size of the compressed
|
||||
* file a lot (more than plain <code>flush()</code> would do).
|
||||
*
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
*
|
||||
* @throws XZIOException
|
||||
* stream finished or closed
|
||||
* @throws XZIOException
|
||||
* stream finished or closed
|
||||
*
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
*/
|
||||
public void endBlock() throws IOException {
|
||||
if (exception != null)
|
||||
@@ -321,7 +324,7 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
// NOTE: Once there is threading with multiple Blocks, it's possible
|
||||
// that this function will be more like a barrier that returns
|
||||
// before the last Block has been finished.
|
||||
if (blockEncoder != null) {
|
||||
if (blockEncoder != null)
|
||||
try {
|
||||
blockEncoder.finish();
|
||||
index.add(blockEncoder.getUnpaddedSize(),
|
||||
@@ -331,7 +334,6 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
exception = e;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,13 +350,13 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* such a filter, <code>flush()</code> will call <code>endBlock()</code>
|
||||
* before flushing.
|
||||
*
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
*
|
||||
* @throws XZIOException
|
||||
* stream finished or closed
|
||||
* @throws XZIOException
|
||||
* stream finished or closed
|
||||
*
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
if (exception != null)
|
||||
@@ -364,18 +366,17 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
throw new XZIOException("Stream finished or closed");
|
||||
|
||||
try {
|
||||
if (blockEncoder != null) {
|
||||
if (filtersSupportFlushing) {
|
||||
if (blockEncoder != null)
|
||||
if (filtersSupportFlushing)
|
||||
// This will eventually call out.flush() so
|
||||
// no need to do it here again.
|
||||
blockEncoder.flush();
|
||||
} else {
|
||||
else {
|
||||
endBlock();
|
||||
out.flush();
|
||||
}
|
||||
} else {
|
||||
else
|
||||
out.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
throw e;
|
||||
@@ -395,10 +396,10 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* <code>close()</code>. If the stream will be closed anyway, there
|
||||
* usually is no need to call <code>finish()</code> separately.
|
||||
*
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
*
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
*/
|
||||
public void finish() throws IOException {
|
||||
if (!finished) {
|
||||
@@ -428,10 +429,10 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
* by <code>finish()</code> is thrown and the exception from the failed
|
||||
* <code>out.close()</code> is lost.
|
||||
*
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
* @throws XZIOException
|
||||
* XZ Stream has grown too big
|
||||
*
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
* @throws IOException may be thrown by the underlying output stream
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (out != null) {
|
||||
@@ -440,7 +441,8 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
// exception here.
|
||||
try {
|
||||
finish();
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
out.close();
|
||||
@@ -460,7 +462,7 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
|
||||
private void encodeStreamFlags(byte[] buf, int off) {
|
||||
buf[off] = 0x00;
|
||||
buf[off + 1] = (byte)streamFlags.checkType;
|
||||
buf[off + 1] = (byte) streamFlags.checkType;
|
||||
}
|
||||
|
||||
private void encodeStreamHeader() throws IOException {
|
||||
@@ -477,7 +479,7 @@ public class XZOutputStream extends FinishableOutputStream {
|
||||
byte[] buf = new byte[6];
|
||||
long backwardSize = index.getIndexSize() / 4 - 1;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
buf[i] = (byte)(backwardSize >>> (i * 8));
|
||||
buf[i] = (byte) (backwardSize >>> (i * 8));
|
||||
|
||||
encodeStreamFlags(buf, 4);
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.check;
|
||||
|
||||
public class CRC32 extends Check {
|
||||
|
||||
private final java.util.zip.CRC32 state = new java.util.zip.CRC32();
|
||||
|
||||
public CRC32() {
|
||||
@@ -23,10 +23,10 @@ public class CRC32 extends Check {
|
||||
|
||||
public byte[] finish() {
|
||||
long value = state.getValue();
|
||||
byte[] buf = { (byte)(value),
|
||||
(byte)(value >>> 8),
|
||||
(byte)(value >>> 16),
|
||||
(byte)(value >>> 24) };
|
||||
byte[] buf = {(byte) (value),
|
||||
(byte) (value >>> 8),
|
||||
(byte) (value >>> 16),
|
||||
(byte) (value >>> 24)};
|
||||
state.reset();
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.check;
|
||||
|
||||
public class CRC64 extends Check {
|
||||
|
||||
private static final long poly = 0xC96C5795D7870F42L;
|
||||
private static final long[] crcTable = new long[256];
|
||||
|
||||
@@ -17,15 +17,14 @@ public class CRC64 extends Check {
|
||||
|
||||
static {
|
||||
for (int b = 0; b < crcTable.length; ++b) {
|
||||
long r = b;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((r & 1) == 1)
|
||||
r = (r >>> 1) ^ poly;
|
||||
else
|
||||
r >>>= 1;
|
||||
}
|
||||
long r = b;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
if ((r & 1) == 1)
|
||||
r = (r >>> 1) ^ poly;
|
||||
else
|
||||
r >>>= 1;
|
||||
|
||||
crcTable[b] = r;
|
||||
crcTable[b] = r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +37,7 @@ public class CRC64 extends Check {
|
||||
int end = off + len;
|
||||
|
||||
while (off < end)
|
||||
crc = crcTable[(buf[off++] ^ (int)crc) & 0xFF] ^ (crc >>> 8);
|
||||
crc = crcTable[(buf[off++] ^ (int) crc) & 0xFF] ^ (crc >>> 8);
|
||||
}
|
||||
|
||||
public byte[] finish() {
|
||||
@@ -47,7 +46,7 @@ public class CRC64 extends Check {
|
||||
|
||||
byte[] buf = new byte[8];
|
||||
for (int i = 0; i < buf.length; ++i)
|
||||
buf[i] = (byte)(value >> (i * 8));
|
||||
buf[i] = (byte) (value >> (i * 8));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,18 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.check;
|
||||
|
||||
import org.tukaani.xz.XZ;
|
||||
import org.tukaani.xz.UnsupportedOptionsException;
|
||||
|
||||
public abstract class Check {
|
||||
|
||||
int size;
|
||||
String name;
|
||||
|
||||
public abstract void update(byte[] buf, int off, int len);
|
||||
|
||||
public abstract byte[] finish();
|
||||
|
||||
public void update(byte[] buf) {
|
||||
@@ -32,7 +33,7 @@ public abstract class Check {
|
||||
}
|
||||
|
||||
public static Check getInstance(int checkType)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
switch (checkType) {
|
||||
case XZ.CHECK_NONE:
|
||||
return new None();
|
||||
@@ -46,12 +47,13 @@ public abstract class Check {
|
||||
case XZ.CHECK_SHA256:
|
||||
try {
|
||||
return new SHA256();
|
||||
} catch (java.security.NoSuchAlgorithmException e) {}
|
||||
} catch (java.security.NoSuchAlgorithmException e) {
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported Check ID " + checkType);
|
||||
"Unsupported Check ID " + checkType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,17 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.check;
|
||||
|
||||
public class None extends Check {
|
||||
|
||||
public None() {
|
||||
size = 0;
|
||||
name = "None";
|
||||
}
|
||||
|
||||
public void update(byte[] buf, int off, int len) {}
|
||||
public void update(byte[] buf, int off, int len) {
|
||||
}
|
||||
|
||||
public byte[] finish() {
|
||||
byte[] empty = new byte[0];
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.check;
|
||||
|
||||
public class SHA256 extends Check {
|
||||
|
||||
private final java.security.MessageDigest sha256;
|
||||
|
||||
public SHA256() throws java.security.NoSuchAlgorithmException {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.common;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -19,6 +18,7 @@ import org.tukaani.xz.CorruptedInputException;
|
||||
import org.tukaani.xz.UnsupportedOptionsException;
|
||||
|
||||
public class DecoderUtil extends Util {
|
||||
|
||||
public static boolean isCRC32Valid(byte[] buf, int off, int len,
|
||||
int ref_off) {
|
||||
CRC32 crc32 = new CRC32();
|
||||
@@ -26,14 +26,14 @@ public class DecoderUtil extends Util {
|
||||
long value = crc32.getValue();
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
if ((byte)(value >>> (i * 8)) != buf[ref_off + i])
|
||||
if ((byte) (value >>> (i * 8)) != buf[ref_off + i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StreamFlags decodeStreamHeader(byte[] buf)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
for (int i = 0; i < XZ.HEADER_MAGIC.length; ++i)
|
||||
if (buf[i] != XZ.HEADER_MAGIC[i])
|
||||
throw new XZFormatException();
|
||||
@@ -46,17 +46,16 @@ public class DecoderUtil extends Util {
|
||||
return decodeStreamFlags(buf, XZ.HEADER_MAGIC.length);
|
||||
} catch (UnsupportedOptionsException e) {
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported options in XZ Stream Header");
|
||||
"Unsupported options in XZ Stream Header");
|
||||
}
|
||||
}
|
||||
|
||||
public static StreamFlags decodeStreamFooter(byte[] buf)
|
||||
throws IOException {
|
||||
if (buf[10] != XZ.FOOTER_MAGIC[0] || buf[11] != XZ.FOOTER_MAGIC[1]) {
|
||||
throws IOException {
|
||||
if (buf[10] != XZ.FOOTER_MAGIC[0] || buf[11] != XZ.FOOTER_MAGIC[1])
|
||||
// NOTE: The exception could be XZFormatException too.
|
||||
// It depends on the situation which one is better.
|
||||
throw new CorruptedInputException("XZ Stream Footer is corrupt");
|
||||
}
|
||||
|
||||
if (!isCRC32Valid(buf, 4, 6, 0))
|
||||
throw new CorruptedInputException("XZ Stream Footer is corrupt");
|
||||
@@ -66,7 +65,7 @@ public class DecoderUtil extends Util {
|
||||
streamFlags = decodeStreamFlags(buf, 8);
|
||||
} catch (UnsupportedOptionsException e) {
|
||||
throw new UnsupportedOptionsException(
|
||||
"Unsupported options in XZ Stream Footer");
|
||||
"Unsupported options in XZ Stream Footer");
|
||||
}
|
||||
|
||||
streamFlags.backwardSize = 0;
|
||||
@@ -79,7 +78,7 @@ public class DecoderUtil extends Util {
|
||||
}
|
||||
|
||||
private static StreamFlags decodeStreamFlags(byte[] buf, int off)
|
||||
throws UnsupportedOptionsException {
|
||||
throws UnsupportedOptionsException {
|
||||
if (buf[off] != 0x00 || (buf[off + 1] & 0xFF) >= 0x10)
|
||||
throw new UnsupportedOptionsException();
|
||||
|
||||
@@ -113,7 +112,7 @@ public class DecoderUtil extends Util {
|
||||
if (b == 0x00)
|
||||
throw new CorruptedInputException();
|
||||
|
||||
num |= (long)(b & 0x7F) << (i * 7);
|
||||
num |= (long) (b & 0x7F) << (i * 7);
|
||||
}
|
||||
|
||||
return num;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.common;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -14,23 +13,24 @@ import java.io.IOException;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
public class EncoderUtil extends Util {
|
||||
|
||||
public static void writeCRC32(OutputStream out, byte[] buf)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
CRC32 crc32 = new CRC32();
|
||||
crc32.update(buf);
|
||||
long value = crc32.getValue();
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
out.write((byte)(value >>> (i * 8)));
|
||||
out.write((byte) (value >>> (i * 8)));
|
||||
}
|
||||
|
||||
public static void encodeVLI(OutputStream out, long num)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
while (num >= 0x80) {
|
||||
out.write((byte)(num | 0x80));
|
||||
out.write((byte) (num | 0x80));
|
||||
num >>>= 7;
|
||||
}
|
||||
|
||||
out.write((byte)num);
|
||||
out.write((byte) num);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.common;
|
||||
|
||||
public class StreamFlags {
|
||||
|
||||
public int checkType = -1;
|
||||
public long backwardSize = -1;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.common;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static final int STREAM_HEADER_SIZE = 12;
|
||||
public static final long BACKWARD_SIZE_MAX = 1L << 34;
|
||||
public static final int BLOCK_HEADER_SIZE_MAX = 1024;
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.delta;
|
||||
|
||||
abstract class DeltaCoder {
|
||||
|
||||
static final int DISTANCE_MIN = 1;
|
||||
static final int DISTANCE_MAX = 256;
|
||||
static final int DISTANCE_MASK = DISTANCE_MAX - 1;
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.delta;
|
||||
|
||||
public class DeltaDecoder extends DeltaCoder {
|
||||
|
||||
public DeltaDecoder(int distance) {
|
||||
super(distance);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.delta;
|
||||
|
||||
public class DeltaEncoder extends DeltaCoder {
|
||||
|
||||
public DeltaEncoder(int distance) {
|
||||
super(distance);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public class DeltaEncoder extends DeltaCoder {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
byte tmp = history[(distance + pos) & DISTANCE_MASK];
|
||||
history[pos-- & DISTANCE_MASK] = in[in_off + i];
|
||||
out[i] = (byte)(in[in_off + i] - tmp);
|
||||
out[i] = (byte) (in[in_off + i] - tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.index;
|
||||
|
||||
import org.tukaani.xz.common.StreamFlags;
|
||||
|
||||
public class BlockInfo {
|
||||
|
||||
public int blockNumber = -1;
|
||||
public long compressedOffset = -1;
|
||||
public long uncompressedOffset = -1;
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.index;
|
||||
|
||||
import org.tukaani.xz.common.Util;
|
||||
import org.tukaani.xz.XZIOException;
|
||||
|
||||
abstract class IndexBase {
|
||||
|
||||
private final XZIOException invalidIndexException;
|
||||
long blocksSum = 0;
|
||||
long uncompressedSum = 0;
|
||||
@@ -34,11 +34,11 @@ abstract class IndexBase {
|
||||
|
||||
public long getStreamSize() {
|
||||
return Util.STREAM_HEADER_SIZE + blocksSum + getIndexSize()
|
||||
+ Util.STREAM_HEADER_SIZE;
|
||||
+ Util.STREAM_HEADER_SIZE;
|
||||
}
|
||||
|
||||
int getIndexPaddingSize() {
|
||||
return (int)((4 - getUnpaddedIndexSize()) & 3);
|
||||
return (int) ((4 - getUnpaddedIndexSize()) & 3);
|
||||
}
|
||||
|
||||
void add(long unpaddedSize, long uncompressedSize) throws XZIOException {
|
||||
@@ -49,8 +49,8 @@ abstract class IndexBase {
|
||||
++recordCount;
|
||||
|
||||
if (blocksSum < 0 || uncompressedSum < 0
|
||||
|| getIndexSize() > Util.BACKWARD_SIZE_MAX
|
||||
|| getStreamSize() < 0)
|
||||
|| getIndexSize() > Util.BACKWARD_SIZE_MAX
|
||||
|| getStreamSize() < 0)
|
||||
throw invalidIndexException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.index;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -20,6 +19,7 @@ import org.tukaani.xz.MemoryLimitException;
|
||||
import org.tukaani.xz.UnsupportedOptionsException;
|
||||
|
||||
public class IndexDecoder extends IndexBase {
|
||||
|
||||
private final StreamFlags streamFlags;
|
||||
private final long streamPadding;
|
||||
private final int memoryUsage;
|
||||
@@ -40,7 +40,7 @@ public class IndexDecoder extends IndexBase {
|
||||
|
||||
public IndexDecoder(SeekableInputStream in, StreamFlags streamFooterFlags,
|
||||
long streamPadding, int memoryLimit)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
super(new CorruptedInputException("XZ Index is corrupt"));
|
||||
this.streamFlags = streamFooterFlags;
|
||||
this.streamPadding = streamPadding;
|
||||
@@ -71,21 +71,21 @@ public class IndexDecoder extends IndexBase {
|
||||
// allocate the arrays to hold the Records.
|
||||
if (count > Integer.MAX_VALUE)
|
||||
throw new UnsupportedOptionsException("XZ Index has over "
|
||||
+ Integer.MAX_VALUE + " Records");
|
||||
+ Integer.MAX_VALUE + " Records");
|
||||
|
||||
// Calculate approximate memory requirements and check the
|
||||
// memory usage limit.
|
||||
memoryUsage = 1 + (int)((16L * count + 1023) / 1024);
|
||||
memoryUsage = 1 + (int) ((16L * count + 1023) / 1024);
|
||||
if (memoryLimit >= 0 && memoryUsage > memoryLimit)
|
||||
throw new MemoryLimitException(memoryUsage, memoryLimit);
|
||||
|
||||
// Allocate the arrays for the Records.
|
||||
unpadded = new long[(int)count];
|
||||
uncompressed = new long[(int)count];
|
||||
unpadded = new long[(int) count];
|
||||
uncompressed = new long[(int) count];
|
||||
int record = 0;
|
||||
|
||||
// Decode the Records.
|
||||
for (int i = (int)count; i > 0; --i) {
|
||||
for (int i = (int) count; i > 0; --i) {
|
||||
// Get the next Record.
|
||||
long unpaddedSize = DecoderUtil.decodeVLI(inChecked);
|
||||
long uncompressedSize = DecoderUtil.decodeVLI(inChecked);
|
||||
@@ -135,7 +135,7 @@ public class IndexDecoder extends IndexBase {
|
||||
public void setOffsets(IndexDecoder prev) {
|
||||
// NOTE: SeekableXZInputStream checks that the total number of Blocks
|
||||
// in concatenated Streams fits into an int.
|
||||
recordOffset = prev.recordOffset + (int)prev.recordCount;
|
||||
recordOffset = prev.recordOffset + (int) prev.recordCount;
|
||||
compressedOffset = prev.compressedOffset
|
||||
+ prev.getStreamSize() + prev.streamPadding;
|
||||
assert (compressedOffset & 3) == 0;
|
||||
@@ -153,7 +153,7 @@ public class IndexDecoder extends IndexBase {
|
||||
public int getRecordCount() {
|
||||
// It was already checked in the constructor that it fits into an int.
|
||||
// Otherwise we couldn't have allocated the arrays.
|
||||
return (int)recordCount;
|
||||
return (int) recordCount;
|
||||
}
|
||||
|
||||
public long getUncompressedSize() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.index;
|
||||
|
||||
import java.io.OutputStream;
|
||||
@@ -18,6 +17,7 @@ import org.tukaani.xz.common.EncoderUtil;
|
||||
import org.tukaani.xz.XZIOException;
|
||||
|
||||
public class IndexEncoder extends IndexBase {
|
||||
|
||||
private final ArrayList records = new ArrayList();
|
||||
|
||||
public IndexEncoder() {
|
||||
@@ -25,7 +25,7 @@ public class IndexEncoder extends IndexBase {
|
||||
}
|
||||
|
||||
public void add(long unpaddedSize, long uncompressedSize)
|
||||
throws XZIOException {
|
||||
throws XZIOException {
|
||||
super.add(unpaddedSize, uncompressedSize);
|
||||
records.add(new IndexRecord(unpaddedSize, uncompressedSize));
|
||||
}
|
||||
@@ -41,8 +41,8 @@ public class IndexEncoder extends IndexBase {
|
||||
EncoderUtil.encodeVLI(outChecked, recordCount);
|
||||
|
||||
// List of Records
|
||||
for (Iterator i = records.iterator(); i.hasNext(); ) {
|
||||
IndexRecord record = (IndexRecord)i.next();
|
||||
for (Iterator i = records.iterator(); i.hasNext();) {
|
||||
IndexRecord record = (IndexRecord) i.next();
|
||||
EncoderUtil.encodeVLI(outChecked, record.unpadded);
|
||||
EncoderUtil.encodeVLI(outChecked, record.uncompressed);
|
||||
}
|
||||
@@ -54,6 +54,6 @@ public class IndexEncoder extends IndexBase {
|
||||
// CRC32
|
||||
long value = crc32.getValue();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
out.write((byte)(value >>> (i * 8)));
|
||||
out.write((byte) (value >>> (i * 8)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.index;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -20,6 +19,7 @@ import org.tukaani.xz.XZIOException;
|
||||
import org.tukaani.xz.CorruptedInputException;
|
||||
|
||||
public class IndexHash extends IndexBase {
|
||||
|
||||
private org.tukaani.xz.check.Check hash;
|
||||
|
||||
public IndexHash() {
|
||||
@@ -33,7 +33,7 @@ public class IndexHash extends IndexBase {
|
||||
}
|
||||
|
||||
public void add(long unpaddedSize, long uncompressedSize)
|
||||
throws XZIOException {
|
||||
throws XZIOException {
|
||||
super.add(unpaddedSize, uncompressedSize);
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(2 * 8);
|
||||
@@ -68,15 +68,15 @@ public class IndexHash extends IndexBase {
|
||||
}
|
||||
|
||||
if (stored.blocksSum > blocksSum
|
||||
|| stored.uncompressedSum > uncompressedSum
|
||||
|| stored.indexListSize > indexListSize)
|
||||
|| stored.uncompressedSum > uncompressedSum
|
||||
|| stored.indexListSize > indexListSize)
|
||||
throw new CorruptedInputException("XZ Index is corrupt");
|
||||
}
|
||||
|
||||
if (stored.blocksSum != blocksSum
|
||||
|| stored.uncompressedSum != uncompressedSum
|
||||
|| stored.indexListSize != indexListSize
|
||||
|| !Arrays.equals(stored.hash.finish(), hash.finish()))
|
||||
|| stored.uncompressedSum != uncompressedSum
|
||||
|| stored.indexListSize != indexListSize
|
||||
|| !Arrays.equals(stored.hash.finish(), hash.finish()))
|
||||
throw new CorruptedInputException("XZ Index is corrupt");
|
||||
|
||||
// Index Padding
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.index;
|
||||
|
||||
class IndexRecord {
|
||||
|
||||
final long unpadded;
|
||||
final long uncompressed;
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
final class BT4 extends LZEncoder {
|
||||
|
||||
private final Hash234 hash;
|
||||
private final int[] tree;
|
||||
private final Matches matches;
|
||||
@@ -25,7 +25,7 @@ final class BT4 extends LZEncoder {
|
||||
}
|
||||
|
||||
BT4(int dictSize, int beforeSizeMin, int readAheadMax,
|
||||
int niceLen, int matchLenMax, int depthLimit) {
|
||||
int niceLen, int matchLenMax, int depthLimit) {
|
||||
super(dictSize, beforeSizeMin, readAheadMax, niceLen, matchLenMax);
|
||||
|
||||
cyclicSize = dictSize + 1;
|
||||
@@ -100,7 +100,7 @@ final class BT4 extends LZEncoder {
|
||||
// Also here the hashing algorithm guarantees that if the first byte
|
||||
// matches, also the next two bytes do.
|
||||
if (delta2 != delta3 && delta3 < cyclicSize
|
||||
&& buf[readPos - delta3] == buf[readPos]) {
|
||||
&& buf[readPos - delta3] == buf[readPos]) {
|
||||
lenBest = 3;
|
||||
matches.dist[matches.count++] = delta3 - 1;
|
||||
delta2 = delta3;
|
||||
@@ -170,7 +170,7 @@ final class BT4 extends LZEncoder {
|
||||
}
|
||||
|
||||
if ((buf[readPos + len - delta] & 0xFF)
|
||||
< (buf[readPos + len] & 0xFF)) {
|
||||
< (buf[readPos + len] & 0xFF)) {
|
||||
tree[ptr1] = currentMatch;
|
||||
ptr1 = pair + 1;
|
||||
currentMatch = tree[ptr1];
|
||||
@@ -205,21 +205,20 @@ final class BT4 extends LZEncoder {
|
||||
+ (delta > cyclicPos ? cyclicSize : 0)) << 1;
|
||||
int len = Math.min(len0, len1);
|
||||
|
||||
if (buf[readPos + len - delta] == buf[readPos + len]) {
|
||||
if (buf[readPos + len - delta] == buf[readPos + len])
|
||||
// No need to look for longer matches than niceLenLimit
|
||||
// because we only are updating the tree, not returning
|
||||
// matches found to the caller.
|
||||
do {
|
||||
do
|
||||
if (++len == niceLenLimit) {
|
||||
tree[ptr1] = tree[pair];
|
||||
tree[ptr0] = tree[pair + 1];
|
||||
return;
|
||||
}
|
||||
} while (buf[readPos + len - delta] == buf[readPos + len]);
|
||||
}
|
||||
while (buf[readPos + len - delta] == buf[readPos + len]);
|
||||
|
||||
if ((buf[readPos + len - delta] & 0xFF)
|
||||
< (buf[readPos + len] & 0xFF)) {
|
||||
< (buf[readPos + len] & 0xFF)) {
|
||||
tree[ptr1] = currentMatch;
|
||||
ptr1 = pair + 1;
|
||||
currentMatch = tree[ptr1];
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
/**
|
||||
* Provides a CRC32 table using the polynomial from IEEE 802.3.
|
||||
*/
|
||||
class CRC32Hash {
|
||||
|
||||
private static final int CRC32_POLY = 0xEDB88320;
|
||||
|
||||
static final int[] crcTable = new int[256];
|
||||
@@ -22,12 +22,11 @@ class CRC32Hash {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
int r = i;
|
||||
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
for (int j = 0; j < 8; ++j)
|
||||
if ((r & 1) != 0)
|
||||
r = (r >>> 1) ^ CRC32_POLY;
|
||||
else
|
||||
r >>>= 1;
|
||||
}
|
||||
|
||||
crcTable[i] = r;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
final class HC4 extends LZEncoder {
|
||||
|
||||
private final Hash234 hash;
|
||||
private final int[] chain;
|
||||
private final Matches matches;
|
||||
@@ -32,7 +32,7 @@ final class HC4 extends LZEncoder {
|
||||
* See <code>LZEncoder.getInstance</code> for parameter descriptions.
|
||||
*/
|
||||
HC4(int dictSize, int beforeSizeMin, int readAheadMax,
|
||||
int niceLen, int matchLenMax, int depthLimit) {
|
||||
int niceLen, int matchLenMax, int depthLimit) {
|
||||
super(dictSize, beforeSizeMin, readAheadMax, niceLen, matchLenMax);
|
||||
|
||||
hash = new Hash234(dictSize);
|
||||
@@ -57,7 +57,7 @@ final class HC4 extends LZEncoder {
|
||||
* Moves to the next byte, checks that there is enough available space,
|
||||
* and possibly normalizes the hash tables and the hash chain.
|
||||
*
|
||||
* @return number of bytes available, including the current byte
|
||||
* @return number of bytes available, including the current byte
|
||||
*/
|
||||
private int movePos() {
|
||||
int avail = movePos(4, 4);
|
||||
@@ -118,7 +118,7 @@ final class HC4 extends LZEncoder {
|
||||
// Also here the hashing algorithm guarantees that if the first byte
|
||||
// matches, also the next two bytes do.
|
||||
if (delta2 != delta3 && delta3 < cyclicSize
|
||||
&& buf[readPos - delta3] == buf[readPos]) {
|
||||
&& buf[readPos - delta3] == buf[readPos]) {
|
||||
lenBest = 3;
|
||||
matches.dist[matches.count++] = delta3 - 1;
|
||||
delta2 = delta3;
|
||||
@@ -161,7 +161,7 @@ final class HC4 extends LZEncoder {
|
||||
// a match that is at least one byte longer than lenBest. This
|
||||
// too short matches get quickly skipped.
|
||||
if (buf[readPos + lenBest - delta] == buf[readPos + lenBest]
|
||||
&& buf[readPos - delta] == buf[readPos]) {
|
||||
&& buf[readPos - delta] == buf[readPos]) {
|
||||
// Calculate the length of the match.
|
||||
int len = 0;
|
||||
while (++len < matchLenLimit)
|
||||
@@ -188,13 +188,12 @@ final class HC4 extends LZEncoder {
|
||||
public void skip(int len) {
|
||||
assert len >= 0;
|
||||
|
||||
while (len-- > 0) {
|
||||
while (len-- > 0)
|
||||
if (movePos() != 0) {
|
||||
// Update the hash chain and hash tables.
|
||||
hash.calcHashes(buf, readPos);
|
||||
chain[cyclicPos] = hash.getHash4Pos();
|
||||
hash.updateTables(lzPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
final class Hash234 extends CRC32Hash {
|
||||
|
||||
private static final int HASH_2_SIZE = 1 << 10;
|
||||
private static final int HASH_2_MASK = HASH_2_SIZE - 1;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
@@ -15,6 +14,7 @@ import java.io.IOException;
|
||||
import org.tukaani.xz.CorruptedInputException;
|
||||
|
||||
public final class LZDecoder {
|
||||
|
||||
private final byte[] buf;
|
||||
private int start = 0;
|
||||
private int pos = 0;
|
||||
@@ -104,7 +104,7 @@ public final class LZDecoder {
|
||||
}
|
||||
|
||||
public void copyUncompressed(DataInputStream inData, int len)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
int copySize = Math.min(buf.length - pos, len);
|
||||
inData.readFully(buf, pos, copySize);
|
||||
pos += copySize;
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class LZEncoder {
|
||||
|
||||
public static final int MF_HC4 = 0x04;
|
||||
public static final int MF_BT4 = 0x14;
|
||||
|
||||
@@ -43,20 +43,19 @@ public abstract class LZEncoder {
|
||||
private int pendingSize = 0;
|
||||
|
||||
static void normalize(int[] positions, int normalizationOffset) {
|
||||
for (int i = 0; i < positions.length; ++i) {
|
||||
for (int i = 0; i < positions.length; ++i)
|
||||
if (positions[i] <= normalizationOffset)
|
||||
positions[i] = 0;
|
||||
else
|
||||
positions[i] -= normalizationOffset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the LZ window buffer that needs to be allocated.
|
||||
*/
|
||||
private static int getBufSize(
|
||||
int dictSize, int extraSizeBefore, int extraSizeAfter,
|
||||
int matchLenMax) {
|
||||
int dictSize, int extraSizeBefore, int extraSizeAfter,
|
||||
int matchLenMax) {
|
||||
int keepSizeBefore = extraSizeBefore + dictSize;
|
||||
int keepSizeAfter = extraSizeAfter + matchLenMax;
|
||||
int reserveSize = Math.min(dictSize / 2 + (256 << 10), 512 << 20);
|
||||
@@ -68,8 +67,8 @@ public abstract class LZEncoder {
|
||||
* the match finder as kibibytes.
|
||||
*/
|
||||
public static int getMemoryUsage(
|
||||
int dictSize, int extraSizeBefore, int extraSizeAfter,
|
||||
int matchLenMax, int mf) {
|
||||
int dictSize, int extraSizeBefore, int extraSizeAfter,
|
||||
int matchLenMax, int mf) {
|
||||
// Buffer size + a little extra
|
||||
int m = getBufSize(dictSize, extraSizeBefore, extraSizeAfter,
|
||||
matchLenMax) / 1024 + 10;
|
||||
@@ -93,30 +92,30 @@ public abstract class LZEncoder {
|
||||
/**
|
||||
* Creates a new LZEncoder.
|
||||
* <p>
|
||||
* @param dictSize dictionary size
|
||||
* @param dictSize dictionary size
|
||||
*
|
||||
* @param extraSizeBefore
|
||||
* number of bytes to keep available in the
|
||||
* history in addition to dictSize
|
||||
* @param extraSizeBefore
|
||||
* number of bytes to keep available in the
|
||||
* history in addition to dictSize
|
||||
*
|
||||
* @param extraSizeAfter
|
||||
* number of bytes that must be available
|
||||
* after current position + matchLenMax
|
||||
* @param extraSizeAfter
|
||||
* number of bytes that must be available
|
||||
* after current position + matchLenMax
|
||||
*
|
||||
* @param niceLen if a match of at least <code>niceLen</code>
|
||||
* bytes is found, be happy with it and don't
|
||||
* stop looking for longer matches
|
||||
* @param niceLen if a match of at least <code>niceLen</code>
|
||||
* bytes is found, be happy with it and don't
|
||||
* stop looking for longer matches
|
||||
*
|
||||
* @param matchLenMax don't test for matches longer than
|
||||
* <code>matchLenMax</code> bytes
|
||||
* @param matchLenMax don't test for matches longer than
|
||||
* <code>matchLenMax</code> bytes
|
||||
*
|
||||
* @param mf match finder ID
|
||||
* @param mf match finder ID
|
||||
*
|
||||
* @param depthLimit match finder search depth limit
|
||||
* @param depthLimit match finder search depth limit
|
||||
*/
|
||||
public static LZEncoder getInstance(
|
||||
int dictSize, int extraSizeBefore, int extraSizeAfter,
|
||||
int niceLen, int matchLenMax, int mf, int depthLimit) {
|
||||
int dictSize, int extraSizeBefore, int extraSizeAfter,
|
||||
int niceLen, int matchLenMax, int mf, int depthLimit) {
|
||||
switch (mf) {
|
||||
case MF_HC4:
|
||||
return new HC4(dictSize, extraSizeBefore, extraSizeAfter,
|
||||
@@ -270,7 +269,7 @@ public abstract class LZEncoder {
|
||||
}
|
||||
|
||||
public void copyUncompressed(OutputStream out, int backward, int len)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
out.write(buf, readPos + 1 - backward, len);
|
||||
}
|
||||
|
||||
@@ -319,10 +318,10 @@ public abstract class LZEncoder {
|
||||
/**
|
||||
* Get the length of a match at the given distance.
|
||||
*
|
||||
* @param dist zero-based distance of the match to test
|
||||
* @param lenLimit don't test for a match longer than this
|
||||
* @param dist zero-based distance of the match to test
|
||||
* @param lenLimit don't test for a match longer than this
|
||||
*
|
||||
* @return length of the match; it is in the range [0, lenLimit]
|
||||
* @return length of the match; it is in the range [0, lenLimit]
|
||||
*/
|
||||
public int getMatchLen(int dist, int lenLimit) {
|
||||
int backPos = readPos - dist - 1;
|
||||
@@ -337,11 +336,11 @@ public abstract class LZEncoder {
|
||||
/**
|
||||
* Get the length of a match at the given distance and forward offset.
|
||||
*
|
||||
* @param forward forward offset
|
||||
* @param dist zero-based distance of the match to test
|
||||
* @param lenLimit don't test for a match longer than this
|
||||
* @param forward forward offset
|
||||
* @param dist zero-based distance of the match to test
|
||||
* @param lenLimit don't test for a match longer than this
|
||||
*
|
||||
* @return length of the match; it is in the range [0, lenLimit]
|
||||
* @return length of the match; it is in the range [0, lenLimit]
|
||||
*/
|
||||
public int getMatchLen(int forward, int dist, int lenLimit) {
|
||||
int curPos = readPos + forward;
|
||||
@@ -360,9 +359,9 @@ public abstract class LZEncoder {
|
||||
* useless for actual encoding since match finder's results should
|
||||
* naturally always be valid if it isn't broken.
|
||||
*
|
||||
* @param matches return value from <code>getMatches</code>
|
||||
* @param matches return value from <code>getMatches</code>
|
||||
*
|
||||
* @return true if matches are valid, false if match finder is broken
|
||||
* @return true if matches are valid, false if match finder is broken
|
||||
*/
|
||||
public boolean verifyMatches(Matches matches) {
|
||||
int lenLimit = Math.min(getAvail(), matchLenMax);
|
||||
@@ -378,18 +377,18 @@ public abstract class LZEncoder {
|
||||
* Moves to the next byte, checks if there is enough input available,
|
||||
* and returns the amount of input available.
|
||||
*
|
||||
* @param requiredForFlushing
|
||||
* minimum number of available bytes when
|
||||
* flushing; encoding may be continued with
|
||||
* new input after flushing
|
||||
* @param requiredForFinishing
|
||||
* minimum number of available bytes when
|
||||
* finishing; encoding must not be continued
|
||||
* after finishing or the match finder state
|
||||
* may be corrupt
|
||||
* @param requiredForFlushing
|
||||
* minimum number of available bytes when
|
||||
* flushing; encoding may be continued with
|
||||
* new input after flushing
|
||||
* @param requiredForFinishing
|
||||
* minimum number of available bytes when
|
||||
* finishing; encoding must not be continued
|
||||
* after finishing or the match finder state
|
||||
* may be corrupt
|
||||
*
|
||||
* @return the number of bytes available or zero if there
|
||||
* is not enough input available
|
||||
* @return the number of bytes available or zero if there
|
||||
* is not enough input available
|
||||
*/
|
||||
int movePos(int requiredForFlushing, int requiredForFinishing) {
|
||||
assert requiredForFlushing >= requiredForFinishing;
|
||||
@@ -397,12 +396,11 @@ public abstract class LZEncoder {
|
||||
++readPos;
|
||||
int avail = writePos - readPos;
|
||||
|
||||
if (avail < requiredForFlushing) {
|
||||
if (avail < requiredForFlushing)
|
||||
if (avail < requiredForFinishing || !finishing) {
|
||||
++pendingSize;
|
||||
avail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return avail;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lz;
|
||||
|
||||
public final class Matches {
|
||||
|
||||
public final int[] len;
|
||||
public final int[] dist;
|
||||
public int count = 0;
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
import org.tukaani.xz.rangecoder.RangeCoder;
|
||||
|
||||
abstract class LZMACoder {
|
||||
|
||||
static final int POS_STATES_MAX = 1 << 4;
|
||||
|
||||
static final int MATCH_LEN_MIN = 2;
|
||||
@@ -44,11 +44,11 @@ abstract class LZMACoder {
|
||||
final short[] isRep2 = new short[State.STATES];
|
||||
final short[][] isRep0Long = new short[State.STATES][POS_STATES_MAX];
|
||||
final short[][] distSlots = new short[DIST_STATES][DIST_SLOTS];
|
||||
final short[][] distSpecial = { new short[2], new short[2],
|
||||
new short[4], new short[4],
|
||||
new short[8], new short[8],
|
||||
new short[16], new short[16],
|
||||
new short[32], new short[32] };
|
||||
final short[][] distSpecial = {new short[2], new short[2],
|
||||
new short[4], new short[4],
|
||||
new short[8], new short[8],
|
||||
new short[16], new short[16],
|
||||
new short[32], new short[32]};
|
||||
final short[] distAlign = new short[ALIGN_SIZE];
|
||||
|
||||
static final int getDistState(int len) {
|
||||
@@ -88,8 +88,8 @@ abstract class LZMACoder {
|
||||
RangeCoder.initProbs(distAlign);
|
||||
}
|
||||
|
||||
|
||||
abstract class LiteralCoder {
|
||||
|
||||
private final int lc;
|
||||
private final int literalPosMask;
|
||||
|
||||
@@ -104,8 +104,8 @@ abstract class LZMACoder {
|
||||
return low + high;
|
||||
}
|
||||
|
||||
|
||||
abstract class LiteralSubcoder {
|
||||
|
||||
final short[] probs = new short[0x300];
|
||||
|
||||
void reset() {
|
||||
@@ -114,8 +114,8 @@ abstract class LZMACoder {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class LengthCoder {
|
||||
|
||||
static final int LOW_SYMBOLS = 1 << 3;
|
||||
static final int MID_SYMBOLS = 1 << 3;
|
||||
static final int HIGH_SYMBOLS = 1 << 8;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -15,6 +14,7 @@ import org.tukaani.xz.lz.LZDecoder;
|
||||
import org.tukaani.xz.rangecoder.RangeDecoder;
|
||||
|
||||
public final class LZMADecoder extends LZMACoder {
|
||||
|
||||
private final LZDecoder lz;
|
||||
private final RangeDecoder rc;
|
||||
private final LiteralDecoder literalDecoder;
|
||||
@@ -52,9 +52,9 @@ public final class LZMADecoder extends LZMACoder {
|
||||
while (lz.hasSpace()) {
|
||||
int posState = lz.getPos() & posMask;
|
||||
|
||||
if (rc.decodeBit(isMatch[state.get()], posState) == 0) {
|
||||
if (rc.decodeBit(isMatch[state.get()], posState) == 0)
|
||||
literalDecoder.decode();
|
||||
} else {
|
||||
else {
|
||||
int len = rc.decodeBit(isRep, state.get()) == 0
|
||||
? decodeMatch(posState)
|
||||
: decodeRepMatch(posState);
|
||||
@@ -79,16 +79,16 @@ public final class LZMADecoder extends LZMACoder {
|
||||
int len = matchLenDecoder.decode(posState);
|
||||
int distSlot = rc.decodeBitTree(distSlots[getDistState(len)]);
|
||||
|
||||
if (distSlot < DIST_MODEL_START) {
|
||||
if (distSlot < DIST_MODEL_START)
|
||||
reps[0] = distSlot;
|
||||
} else {
|
||||
else {
|
||||
int limit = (distSlot >> 1) - 1;
|
||||
reps[0] = (2 | (distSlot & 1)) << limit;
|
||||
|
||||
if (distSlot < DIST_MODEL_END) {
|
||||
if (distSlot < DIST_MODEL_END)
|
||||
reps[0] |= rc.decodeReverseBitTree(
|
||||
distSpecial[distSlot - DIST_MODEL_START]);
|
||||
} else {
|
||||
distSpecial[distSlot - DIST_MODEL_START]);
|
||||
else {
|
||||
reps[0] |= rc.decodeDirectBits(limit - ALIGN_BITS)
|
||||
<< ALIGN_BITS;
|
||||
reps[0] |= rc.decodeReverseBitTree(distAlign);
|
||||
@@ -107,12 +107,12 @@ public final class LZMADecoder extends LZMACoder {
|
||||
} else {
|
||||
int tmp;
|
||||
|
||||
if (rc.decodeBit(isRep1, state.get()) == 0) {
|
||||
if (rc.decodeBit(isRep1, state.get()) == 0)
|
||||
tmp = reps[1];
|
||||
} else {
|
||||
if (rc.decodeBit(isRep2, state.get()) == 0) {
|
||||
else {
|
||||
if (rc.decodeBit(isRep2, state.get()) == 0)
|
||||
tmp = reps[2];
|
||||
} else {
|
||||
else {
|
||||
tmp = reps[3];
|
||||
reps[3] = reps[2];
|
||||
}
|
||||
@@ -129,8 +129,8 @@ public final class LZMADecoder extends LZMACoder {
|
||||
return repLenDecoder.decode(posState);
|
||||
}
|
||||
|
||||
|
||||
private class LiteralDecoder extends LiteralCoder {
|
||||
|
||||
LiteralSubdecoder[] subdecoders;
|
||||
|
||||
LiteralDecoder(int lc, int lp) {
|
||||
@@ -151,17 +151,16 @@ public final class LZMADecoder extends LZMACoder {
|
||||
subdecoders[i].decode();
|
||||
}
|
||||
|
||||
|
||||
private class LiteralSubdecoder extends LiteralSubcoder {
|
||||
|
||||
void decode() throws IOException {
|
||||
int symbol = 1;
|
||||
|
||||
if (state.isLiteral()) {
|
||||
do {
|
||||
if (state.isLiteral())
|
||||
do
|
||||
symbol = (symbol << 1) | rc.decodeBit(probs, symbol);
|
||||
} while (symbol < 0x100);
|
||||
|
||||
} else {
|
||||
while (symbol < 0x100);
|
||||
else {
|
||||
int matchByte = lz.getByte(reps[0]);
|
||||
int offset = 0x100;
|
||||
int matchBit;
|
||||
@@ -176,14 +175,14 @@ public final class LZMADecoder extends LZMACoder {
|
||||
} while (symbol < 0x100);
|
||||
}
|
||||
|
||||
lz.putByte((byte)symbol);
|
||||
lz.putByte((byte) symbol);
|
||||
state.updateLiteral();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class LengthDecoder extends LengthCoder {
|
||||
|
||||
int decode(int posState) throws IOException {
|
||||
if (rc.decodeBit(choice, 0) == 0)
|
||||
return rc.decodeBitTree(low[posState]) + MATCH_LEN_MIN;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
import org.tukaani.xz.lz.LZEncoder;
|
||||
@@ -15,6 +14,7 @@ import org.tukaani.xz.lz.Matches;
|
||||
import org.tukaani.xz.rangecoder.RangeEncoder;
|
||||
|
||||
public abstract class LZMAEncoder extends LZMACoder {
|
||||
|
||||
public static final int MODE_FAST = 1;
|
||||
public static final int MODE_NORMAL = 2;
|
||||
|
||||
@@ -28,7 +28,7 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
* less space than MATCH_LEN_MAX bytes.
|
||||
*/
|
||||
private static final int LZMA2_UNCOMPRESSED_LIMIT
|
||||
= (2 << 20) - MATCH_LEN_MAX;
|
||||
= (2 << 20) - MATCH_LEN_MAX;
|
||||
|
||||
/**
|
||||
* LZMA2 chunk is considered full when its compressed size exceeds
|
||||
@@ -58,7 +58,7 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
private final int distSlotPricesSize;
|
||||
private final int[][] distSlotPrices;
|
||||
private final int[][] fullDistPrices
|
||||
= new int[DIST_STATES][FULL_DISTANCES];
|
||||
= new int[DIST_STATES][FULL_DISTANCES];
|
||||
private final int[] alignPrices = new int[ALIGN_SIZE];
|
||||
|
||||
int back = 0;
|
||||
@@ -72,12 +72,12 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
switch (mode) {
|
||||
case MODE_FAST:
|
||||
m += LZMAEncoderFast.getMemoryUsage(
|
||||
dictSize, extraSizeBefore, mf);
|
||||
dictSize, extraSizeBefore, mf);
|
||||
break;
|
||||
|
||||
case MODE_NORMAL:
|
||||
m += LZMAEncoderNormal.getMemoryUsage(
|
||||
dictSize, extraSizeBefore, mf);
|
||||
dictSize, extraSizeBefore, mf);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -88,9 +88,9 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
}
|
||||
|
||||
public static LZMAEncoder getInstance(
|
||||
RangeEncoder rc, int lc, int lp, int pb, int mode,
|
||||
int dictSize, int extraSizeBefore,
|
||||
int niceLen, int mf, int depthLimit) {
|
||||
RangeEncoder rc, int lc, int lp, int pb, int mode,
|
||||
int dictSize, int extraSizeBefore,
|
||||
int niceLen, int mf, int depthLimit) {
|
||||
switch (mode) {
|
||||
case MODE_FAST:
|
||||
return new LZMAEncoderFast(rc, lc, lp, pb,
|
||||
@@ -207,14 +207,14 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
/**
|
||||
* Compresses for LZMA2.
|
||||
*
|
||||
* @return true if the LZMA2 chunk became full, false otherwise
|
||||
* @return true if the LZMA2 chunk became full, false otherwise
|
||||
*/
|
||||
public boolean encodeForLZMA2() {
|
||||
if (!lz.isStarted() && !encodeInit())
|
||||
return false;
|
||||
|
||||
while (uncompressedSize <= LZMA2_UNCOMPRESSED_LIMIT
|
||||
&& rc.getPendingSize() <= LZMA2_COMPRESSED_LIMIT)
|
||||
&& rc.getPendingSize() <= LZMA2_COMPRESSED_LIMIT)
|
||||
if (!encodeSymbol())
|
||||
return false;
|
||||
|
||||
@@ -291,11 +291,11 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
int base = (2 | (distSlot & 1)) << footerBits;
|
||||
int distReduced = dist - base;
|
||||
|
||||
if (distSlot < DIST_MODEL_END) {
|
||||
if (distSlot < DIST_MODEL_END)
|
||||
rc.encodeReverseBitTree(
|
||||
distSpecial[distSlot - DIST_MODEL_START],
|
||||
distReduced);
|
||||
} else {
|
||||
distSpecial[distSlot - DIST_MODEL_START],
|
||||
distReduced);
|
||||
else {
|
||||
rc.encodeDirectBits(distReduced >>> ALIGN_BITS,
|
||||
footerBits - ALIGN_BITS);
|
||||
rc.encodeReverseBitTree(distAlign, distReduced & ALIGN_MASK);
|
||||
@@ -319,9 +319,9 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
int dist = reps[rep];
|
||||
rc.encodeBit(isRep0, state.get(), 1);
|
||||
|
||||
if (rep == 1) {
|
||||
if (rep == 1)
|
||||
rc.encodeBit(isRep1, state.get(), 0);
|
||||
} else {
|
||||
else {
|
||||
rc.encodeBit(isRep1, state.get(), 1);
|
||||
rc.encodeBit(isRep2, state.get(), rep - 2);
|
||||
|
||||
@@ -335,9 +335,9 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
reps[0] = dist;
|
||||
}
|
||||
|
||||
if (len == 1) {
|
||||
if (len == 1)
|
||||
state.updateShortRep();
|
||||
} else {
|
||||
else {
|
||||
repLenEncoder.encode(len, posState);
|
||||
state.updateLongRep();
|
||||
}
|
||||
@@ -379,11 +379,11 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
int getLongRepPrice(int anyRepPrice, int rep, State state, int posState) {
|
||||
int price = anyRepPrice;
|
||||
|
||||
if (rep == 0) {
|
||||
if (rep == 0)
|
||||
price += RangeEncoder.getBitPrice(isRep0[state.get()], 0)
|
||||
+ RangeEncoder.getBitPrice(
|
||||
isRep0Long[state.get()][posState], 1);
|
||||
} else {
|
||||
isRep0Long[state.get()][posState], 1);
|
||||
else {
|
||||
price += RangeEncoder.getBitPrice(isRep0[state.get()], 1);
|
||||
|
||||
if (rep == 1)
|
||||
@@ -410,9 +410,9 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
+ matchLenEncoder.getPrice(len, posState);
|
||||
int distState = getDistState(len);
|
||||
|
||||
if (dist < FULL_DISTANCES) {
|
||||
if (dist < FULL_DISTANCES)
|
||||
price += fullDistPrices[distState][dist];
|
||||
} else {
|
||||
else {
|
||||
// Note that distSlotPrices includes also
|
||||
// the price of direct bits.
|
||||
int distSlot = getDistSlot(dist);
|
||||
@@ -429,24 +429,24 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
for (int distState = 0; distState < DIST_STATES; ++distState) {
|
||||
for (int distSlot = 0; distSlot < distSlotPricesSize; ++distSlot)
|
||||
distSlotPrices[distState][distSlot]
|
||||
= RangeEncoder.getBitTreePrice(
|
||||
distSlots[distState], distSlot);
|
||||
= RangeEncoder.getBitTreePrice(
|
||||
distSlots[distState], distSlot);
|
||||
|
||||
for (int distSlot = DIST_MODEL_END; distSlot < distSlotPricesSize;
|
||||
++distSlot) {
|
||||
++distSlot) {
|
||||
int count = (distSlot >>> 1) - 1 - ALIGN_BITS;
|
||||
distSlotPrices[distState][distSlot]
|
||||
+= RangeEncoder.getDirectBitsPrice(count);
|
||||
+= RangeEncoder.getDirectBitsPrice(count);
|
||||
}
|
||||
|
||||
for (int dist = 0; dist < DIST_MODEL_START; ++dist)
|
||||
fullDistPrices[distState][dist]
|
||||
= distSlotPrices[distState][dist];
|
||||
= distSlotPrices[distState][dist];
|
||||
}
|
||||
|
||||
int dist = DIST_MODEL_START;
|
||||
for (int distSlot = DIST_MODEL_START; distSlot < DIST_MODEL_END;
|
||||
++distSlot) {
|
||||
++distSlot) {
|
||||
int footerBits = (distSlot >>> 1) - 1;
|
||||
int base = (2 | (distSlot & 1)) << footerBits;
|
||||
|
||||
@@ -454,12 +454,12 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
for (int i = 0; i < limit; ++i) {
|
||||
int distReduced = dist - base;
|
||||
int price = RangeEncoder.getReverseBitTreePrice(
|
||||
distSpecial[distSlot - DIST_MODEL_START],
|
||||
distReduced);
|
||||
distSpecial[distSlot - DIST_MODEL_START],
|
||||
distReduced);
|
||||
|
||||
for (int distState = 0; distState < DIST_STATES; ++distState)
|
||||
fullDistPrices[distState][dist]
|
||||
= distSlotPrices[distState][distSlot] + price;
|
||||
= distSlotPrices[distState][distSlot] + price;
|
||||
|
||||
++dist;
|
||||
}
|
||||
@@ -492,8 +492,8 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
repLenEncoder.updatePrices();
|
||||
}
|
||||
|
||||
|
||||
class LiteralEncoder extends LiteralCoder {
|
||||
|
||||
LiteralSubencoder[] subencoders;
|
||||
|
||||
LiteralEncoder(int lc, int lp) {
|
||||
@@ -527,17 +527,18 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
int getPrice(int curByte, int matchByte,
|
||||
int prevByte, int pos, State state) {
|
||||
int price = RangeEncoder.getBitPrice(
|
||||
isMatch[state.get()][pos & posMask], 0);
|
||||
isMatch[state.get()][pos & posMask], 0);
|
||||
|
||||
int i = getSubcoderIndex(prevByte, pos);
|
||||
price += state.isLiteral()
|
||||
? subencoders[i].getNormalPrice(curByte)
|
||||
: subencoders[i].getMatchedPrice(curByte, matchByte);
|
||||
? subencoders[i].getNormalPrice(curByte)
|
||||
: subencoders[i].getMatchedPrice(curByte, matchByte);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
private class LiteralSubencoder extends LiteralSubcoder {
|
||||
|
||||
void encode() {
|
||||
int symbol = lz.getByte(readAhead) | 0x100;
|
||||
|
||||
@@ -616,8 +617,8 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LengthEncoder extends LengthCoder {
|
||||
|
||||
/**
|
||||
* The prices are updated after at least
|
||||
* <code>PRICE_UPDATE_INTERVAL</code> many lengths
|
||||
@@ -676,12 +677,11 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
}
|
||||
|
||||
void updatePrices() {
|
||||
for (int posState = 0; posState < counters.length; ++posState) {
|
||||
for (int posState = 0; posState < counters.length; ++posState)
|
||||
if (counters[posState] <= 0) {
|
||||
counters[posState] = PRICE_UPDATE_INTERVAL;
|
||||
updatePrices(posState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePrices(int posState) {
|
||||
@@ -690,22 +690,22 @@ public abstract class LZMAEncoder extends LZMACoder {
|
||||
int i = 0;
|
||||
for (; i < LOW_SYMBOLS; ++i)
|
||||
prices[posState][i] = choice0Price
|
||||
+ RangeEncoder.getBitTreePrice(low[posState], i);
|
||||
+ RangeEncoder.getBitTreePrice(low[posState], i);
|
||||
|
||||
choice0Price = RangeEncoder.getBitPrice(choice[0], 1);
|
||||
int choice1Price = RangeEncoder.getBitPrice(choice[1], 0);
|
||||
|
||||
for (; i < LOW_SYMBOLS + MID_SYMBOLS; ++i)
|
||||
prices[posState][i] = choice0Price + choice1Price
|
||||
+ RangeEncoder.getBitTreePrice(mid[posState],
|
||||
i - LOW_SYMBOLS);
|
||||
+ RangeEncoder.getBitTreePrice(mid[posState],
|
||||
i - LOW_SYMBOLS);
|
||||
|
||||
choice1Price = RangeEncoder.getBitPrice(choice[1], 1);
|
||||
|
||||
for (; i < prices[posState].length; ++i)
|
||||
prices[posState][i] = choice0Price + choice1Price
|
||||
+ RangeEncoder.getBitTreePrice(high, i - LOW_SYMBOLS
|
||||
- MID_SYMBOLS);
|
||||
+ RangeEncoder.getBitTreePrice(high, i - LOW_SYMBOLS
|
||||
- MID_SYMBOLS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
import org.tukaani.xz.lz.LZEncoder;
|
||||
@@ -15,6 +14,7 @@ import org.tukaani.xz.lz.Matches;
|
||||
import org.tukaani.xz.rangecoder.RangeEncoder;
|
||||
|
||||
final class LZMAEncoderFast extends LZMAEncoder {
|
||||
|
||||
private static int EXTRA_SIZE_BEFORE = 1;
|
||||
private static int EXTRA_SIZE_AFTER = MATCH_LEN_MAX - 1;
|
||||
|
||||
@@ -22,13 +22,13 @@ final class LZMAEncoderFast extends LZMAEncoder {
|
||||
|
||||
static int getMemoryUsage(int dictSize, int extraSizeBefore, int mf) {
|
||||
return LZEncoder.getMemoryUsage(
|
||||
dictSize, Math.max(extraSizeBefore, EXTRA_SIZE_BEFORE),
|
||||
EXTRA_SIZE_AFTER, MATCH_LEN_MAX, mf);
|
||||
dictSize, Math.max(extraSizeBefore, EXTRA_SIZE_BEFORE),
|
||||
EXTRA_SIZE_AFTER, MATCH_LEN_MAX, mf);
|
||||
}
|
||||
|
||||
LZMAEncoderFast(RangeEncoder rc, int lc, int lp, int pb,
|
||||
int dictSize, int extraSizeBefore,
|
||||
int niceLen, int mf, int depthLimit) {
|
||||
int dictSize, int extraSizeBefore,
|
||||
int niceLen, int mf, int depthLimit) {
|
||||
super(rc, LZEncoder.getInstance(dictSize,
|
||||
Math.max(extraSizeBefore,
|
||||
EXTRA_SIZE_BEFORE),
|
||||
@@ -95,7 +95,7 @@ final class LZMAEncoderFast extends LZMAEncoder {
|
||||
}
|
||||
|
||||
while (matches.count > 1
|
||||
&& mainLen == matches.len[matches.count - 2] + 1) {
|
||||
&& mainLen == matches.len[matches.count - 2] + 1) {
|
||||
if (!changePair(matches.dist[matches.count - 2], mainDist))
|
||||
break;
|
||||
|
||||
@@ -108,15 +108,14 @@ final class LZMAEncoderFast extends LZMAEncoder {
|
||||
mainLen = 1;
|
||||
}
|
||||
|
||||
if (bestRepLen >= MATCH_LEN_MIN) {
|
||||
if (bestRepLen >= MATCH_LEN_MIN)
|
||||
if (bestRepLen + 1 >= mainLen
|
||||
|| (bestRepLen + 2 >= mainLen && mainDist >= (1 << 9))
|
||||
|| (bestRepLen + 3 >= mainLen && mainDist >= (1 << 15))) {
|
||||
|| (bestRepLen + 2 >= mainLen && mainDist >= (1 << 9))
|
||||
|| (bestRepLen + 3 >= mainLen && mainDist >= (1 << 15))) {
|
||||
back = bestRepIndex;
|
||||
skip(bestRepLen - 1);
|
||||
return bestRepLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (mainLen < MATCH_LEN_MIN || avail <= MATCH_LEN_MIN)
|
||||
return 1;
|
||||
@@ -130,12 +129,12 @@ final class LZMAEncoderFast extends LZMAEncoder {
|
||||
int newDist = matches.dist[matches.count - 1];
|
||||
|
||||
if ((newLen >= mainLen && newDist < mainDist)
|
||||
|| (newLen == mainLen + 1
|
||||
&& !changePair(mainDist, newDist))
|
||||
|| newLen > mainLen + 1
|
||||
|| (newLen + 1 >= mainLen
|
||||
&& mainLen >= MATCH_LEN_MIN + 1
|
||||
&& changePair(newDist, mainDist)))
|
||||
|| (newLen == mainLen + 1
|
||||
&& !changePair(mainDist, newDist))
|
||||
|| newLen > mainLen + 1
|
||||
|| (newLen + 1 >= mainLen
|
||||
&& mainLen >= MATCH_LEN_MIN + 1
|
||||
&& changePair(newDist, mainDist)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
import org.tukaani.xz.lz.LZEncoder;
|
||||
@@ -15,6 +14,7 @@ import org.tukaani.xz.lz.Matches;
|
||||
import org.tukaani.xz.rangecoder.RangeEncoder;
|
||||
|
||||
final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
|
||||
private static final int OPTS = 4096;
|
||||
|
||||
private static int EXTRA_SIZE_BEFORE = OPTS;
|
||||
@@ -33,14 +33,14 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
|
||||
static int getMemoryUsage(int dictSize, int extraSizeBefore, int mf) {
|
||||
return LZEncoder.getMemoryUsage(dictSize,
|
||||
Math.max(extraSizeBefore, EXTRA_SIZE_BEFORE),
|
||||
EXTRA_SIZE_AFTER, MATCH_LEN_MAX, mf)
|
||||
Math.max(extraSizeBefore, EXTRA_SIZE_BEFORE),
|
||||
EXTRA_SIZE_AFTER, MATCH_LEN_MAX, mf)
|
||||
+ OPTS * 64 / 1024;
|
||||
}
|
||||
|
||||
LZMAEncoderNormal(RangeEncoder rc, int lc, int lp, int pb,
|
||||
int dictSize, int extraSizeBefore,
|
||||
int niceLen, int mf, int depthLimit) {
|
||||
int dictSize, int extraSizeBefore,
|
||||
int niceLen, int mf, int depthLimit) {
|
||||
super(rc, LZEncoder.getInstance(dictSize,
|
||||
Math.max(extraSizeBefore,
|
||||
EXTRA_SIZE_BEFORE),
|
||||
@@ -166,10 +166,9 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
// encoded as a repeated match (short or long), we must be return
|
||||
// to have the byte encoded as a literal.
|
||||
if (mainLen < MATCH_LEN_MIN && curByte != matchByte
|
||||
&& repLens[repBest] < MATCH_LEN_MIN)
|
||||
&& repLens[repBest] < MATCH_LEN_MIN)
|
||||
return 1;
|
||||
|
||||
|
||||
int pos = lz.getPos();
|
||||
int posState = pos & posMask;
|
||||
|
||||
@@ -202,7 +201,6 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Update the lookup tables for distances and lengths before using
|
||||
// those price calculation functions. (The price function above
|
||||
// don't need these tables.)
|
||||
@@ -263,7 +261,6 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
avail = Math.min(lz.getAvail(), OPTS - 1);
|
||||
|
||||
// Get matches for later bytes and optimize the use of LZMA symbols
|
||||
@@ -272,7 +269,7 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
while (++optCur < optEnd) {
|
||||
matches = getMatches();
|
||||
if (matches.count > 0
|
||||
&& matches.len[matches.count - 1] >= niceLen)
|
||||
&& matches.len[matches.count - 1] >= niceLen)
|
||||
break;
|
||||
|
||||
--avail;
|
||||
@@ -314,14 +311,12 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
opts[optCur].state.updateLongRep();
|
||||
else
|
||||
opts[optCur].state.updateMatch();
|
||||
} else {
|
||||
} else
|
||||
opts[optCur].state.set(opts[optPrev].state);
|
||||
}
|
||||
|
||||
opts[optCur].state.updateLiteral();
|
||||
} else {
|
||||
} else
|
||||
opts[optCur].state.set(opts[optPrev].state);
|
||||
}
|
||||
|
||||
if (optPrev == optCur - 1) {
|
||||
// Must be either a short rep or a literal.
|
||||
@@ -378,8 +373,8 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
|
||||
// Try a literal.
|
||||
int literalPrice = opts[optCur].price
|
||||
+ literalEncoder.getPrice(curByte, matchByte, lz.getByte(1),
|
||||
pos, opts[optCur].state);
|
||||
+ literalEncoder.getPrice(curByte, matchByte, lz.getByte(1),
|
||||
pos, opts[optCur].state);
|
||||
if (literalPrice < opts[optCur + 1].price) {
|
||||
opts[optCur + 1].set1(literalPrice, optCur, -1);
|
||||
nextIsByte = true;
|
||||
@@ -387,7 +382,7 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
|
||||
// Try a short rep.
|
||||
if (matchByte == curByte && (opts[optCur + 1].optPrev == optCur
|
||||
|| opts[optCur + 1].backPrev != 0)) {
|
||||
|| opts[optCur + 1].backPrev != 0)) {
|
||||
int shortRepPrice = getShortRepPrice(anyRepPrice,
|
||||
opts[optCur].state,
|
||||
posState);
|
||||
@@ -514,7 +509,7 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
while (startLen > matches.len[match])
|
||||
++match;
|
||||
|
||||
for (int len = startLen; ; ++len) {
|
||||
for (int len = startLen;; ++len) {
|
||||
int dist = matches.dist[match];
|
||||
|
||||
// Calculate the price of a match of len bytes from the nearest
|
||||
@@ -541,9 +536,9 @@ final class LZMAEncoderNormal extends LZMAEncoder {
|
||||
int matchByte = lz.getByte(0); // lz.getByte(len, len)
|
||||
int prevByte = lz.getByte(len, 1);
|
||||
int price = matchAndLenPrice
|
||||
+ literalEncoder.getPrice(curByte, matchByte,
|
||||
prevByte, pos + len,
|
||||
nextState);
|
||||
+ literalEncoder.getPrice(curByte, matchByte,
|
||||
prevByte, pos + len,
|
||||
nextState);
|
||||
nextState.updateLiteral();
|
||||
|
||||
// Rep0
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
final class Optimum {
|
||||
|
||||
private static final int INFINITY_PRICE = 1 << 30;
|
||||
|
||||
final State state = new State();
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.lzma;
|
||||
|
||||
final class State {
|
||||
|
||||
static final int STATES = 12;
|
||||
|
||||
private static final int LIT_STATES = 7;
|
||||
@@ -30,7 +30,8 @@ final class State {
|
||||
|
||||
private int state;
|
||||
|
||||
State() {}
|
||||
State() {
|
||||
}
|
||||
|
||||
State(State other) {
|
||||
state = other.state;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* <li>Single-threaded streamed compression and decompression</li>
|
||||
* <li>Single-threaded decompression with limited random access support</li>
|
||||
* <li>Raw streams (no .xz headers) for advanced users, including LZMA2
|
||||
* with preset dictionary</li>
|
||||
* with preset dictionary</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Threading is planned but it is unknown when it will be implemented.
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.rangecoder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class RangeCoder {
|
||||
|
||||
static final int SHIFT_BITS = 8;
|
||||
static final int TOP_MASK = 0xFF000000;
|
||||
static final int BIT_MODEL_TOTAL_BITS = 11;
|
||||
static final int BIT_MODEL_TOTAL = 1 << BIT_MODEL_TOTAL_BITS;
|
||||
static final short PROB_INIT = (short)(BIT_MODEL_TOTAL / 2);
|
||||
static final short PROB_INIT = (short) (BIT_MODEL_TOTAL / 2);
|
||||
static final int MOVE_BITS = 5;
|
||||
|
||||
public static final void initProbs(short[] probs) {
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.rangecoder;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class RangeDecoder extends RangeCoder {
|
||||
|
||||
int range = 0;
|
||||
int code = 0;
|
||||
|
||||
@@ -29,13 +29,12 @@ public abstract class RangeDecoder extends RangeCoder {
|
||||
// Compare code and bound as if they were unsigned 32-bit integers.
|
||||
if ((code ^ 0x80000000) < (bound ^ 0x80000000)) {
|
||||
range = bound;
|
||||
probs[index] = (short)(
|
||||
prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS));
|
||||
probs[index] = (short) (prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS));
|
||||
bit = 0;
|
||||
} else {
|
||||
range -= bound;
|
||||
code -= bound;
|
||||
probs[index] = (short)(prob - (prob >>> MOVE_BITS));
|
||||
probs[index] = (short) (prob - (prob >>> MOVE_BITS));
|
||||
bit = 1;
|
||||
}
|
||||
|
||||
@@ -45,9 +44,9 @@ public abstract class RangeDecoder extends RangeCoder {
|
||||
public int decodeBitTree(short[] probs) throws IOException {
|
||||
int symbol = 1;
|
||||
|
||||
do {
|
||||
do
|
||||
symbol = (symbol << 1) | decodeBit(probs, symbol);
|
||||
} while (symbol < probs.length);
|
||||
while (symbol < probs.length);
|
||||
|
||||
return symbol - probs.length;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.rangecoder;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
@@ -15,6 +14,7 @@ import java.io.IOException;
|
||||
import org.tukaani.xz.CorruptedInputException;
|
||||
|
||||
public final class RangeDecoderFromBuffer extends RangeDecoder {
|
||||
|
||||
private static final int INIT_SIZE = 5;
|
||||
|
||||
private final byte[] buf;
|
||||
@@ -26,7 +26,7 @@ public final class RangeDecoderFromBuffer extends RangeDecoder {
|
||||
}
|
||||
|
||||
public void prepareInputBuffer(DataInputStream in, int len)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (len < INIT_SIZE)
|
||||
throw new CorruptedInputException();
|
||||
|
||||
@@ -50,7 +50,7 @@ public final class RangeDecoderFromBuffer extends RangeDecoder {
|
||||
}
|
||||
|
||||
public void normalize() throws IOException {
|
||||
if ((range & TOP_MASK) == 0) {
|
||||
if ((range & TOP_MASK) == 0)
|
||||
try {
|
||||
// If the input is corrupt, this might throw
|
||||
// ArrayIndexOutOfBoundsException.
|
||||
@@ -59,6 +59,5 @@ public final class RangeDecoderFromBuffer extends RangeDecoder {
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new CorruptedInputException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.rangecoder;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -16,6 +15,7 @@ import java.io.IOException;
|
||||
import org.tukaani.xz.CorruptedInputException;
|
||||
|
||||
public final class RangeDecoderFromStream extends RangeDecoder {
|
||||
|
||||
private final DataInputStream inData;
|
||||
|
||||
public RangeDecoderFromStream(InputStream in) throws IOException {
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.rangecoder;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class RangeEncoder extends RangeCoder {
|
||||
|
||||
private static final int MOVE_REDUCING_BITS = 4;
|
||||
private static final int BIT_PRICE_SHIFT_BITS = 4;
|
||||
|
||||
private static final int[] prices
|
||||
= new int[BIT_MODEL_TOTAL >>> MOVE_REDUCING_BITS];
|
||||
= new int[BIT_MODEL_TOTAL >>> MOVE_REDUCING_BITS];
|
||||
|
||||
private long low;
|
||||
private int range;
|
||||
@@ -35,7 +35,7 @@ public final class RangeEncoder extends RangeCoder {
|
||||
|
||||
static {
|
||||
for (int i = (1 << MOVE_REDUCING_BITS) / 2; i < BIT_MODEL_TOTAL;
|
||||
i += (1 << MOVE_REDUCING_BITS)) {
|
||||
i += (1 << MOVE_REDUCING_BITS)) {
|
||||
int w = i;
|
||||
int bitCount = 0;
|
||||
|
||||
@@ -50,8 +50,8 @@ public final class RangeEncoder extends RangeCoder {
|
||||
}
|
||||
|
||||
prices[i >> MOVE_REDUCING_BITS]
|
||||
= (BIT_MODEL_TOTAL_BITS << BIT_PRICE_SHIFT_BITS)
|
||||
- 15 - bitCount;
|
||||
= (BIT_MODEL_TOTAL_BITS << BIT_PRICE_SHIFT_BITS)
|
||||
- 15 - bitCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,17 +84,17 @@ public final class RangeEncoder extends RangeCoder {
|
||||
}
|
||||
|
||||
private void shiftLow() {
|
||||
int lowHi = (int)(low >>> 32);
|
||||
int lowHi = (int) (low >>> 32);
|
||||
|
||||
if (lowHi != 0 || low < 0xFF000000L) {
|
||||
int temp = cache;
|
||||
|
||||
do {
|
||||
buf[bufPos++] = (byte)(temp + lowHi);
|
||||
buf[bufPos++] = (byte) (temp + lowHi);
|
||||
temp = 0xFF;
|
||||
} while (--cacheSize != 0);
|
||||
|
||||
cache = (byte)(low >>> 24);
|
||||
cache = (byte) (low >>> 24);
|
||||
}
|
||||
|
||||
++cacheSize;
|
||||
@@ -108,12 +108,11 @@ public final class RangeEncoder extends RangeCoder {
|
||||
// NOTE: Any non-zero value for bit is taken as 1.
|
||||
if (bit == 0) {
|
||||
range = bound;
|
||||
probs[index] = (short)(
|
||||
prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS));
|
||||
probs[index] = (short) (prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS));
|
||||
} else {
|
||||
low += bound & 0xFFFFFFFFL;
|
||||
range -= bound;
|
||||
probs[index] = (short)(prob - (prob >>> MOVE_BITS));
|
||||
probs[index] = (short) (prob - (prob >>> MOVE_BITS));
|
||||
}
|
||||
|
||||
if ((range & TOP_MASK) == 0) {
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public final class ARM implements SimpleFilter {
|
||||
|
||||
private final boolean isEncoder;
|
||||
private int pos;
|
||||
|
||||
@@ -23,7 +23,7 @@ public final class ARM implements SimpleFilter {
|
||||
int end = off + len - 4;
|
||||
int i;
|
||||
|
||||
for (i = off; i <= end; i += 4) {
|
||||
for (i = off; i <= end; i += 4)
|
||||
if ((buf[i + 3] & 0xFF) == 0xEB) {
|
||||
int src = ((buf[i + 2] & 0xFF) << 16)
|
||||
| ((buf[i + 1] & 0xFF) << 8)
|
||||
@@ -37,11 +37,10 @@ public final class ARM implements SimpleFilter {
|
||||
dest = src - (pos + i - off);
|
||||
|
||||
dest >>>= 2;
|
||||
buf[i + 2] = (byte)(dest >>> 16);
|
||||
buf[i + 1] = (byte)(dest >>> 8);
|
||||
buf[i] = (byte)dest;
|
||||
buf[i + 2] = (byte) (dest >>> 16);
|
||||
buf[i + 1] = (byte) (dest >>> 8);
|
||||
buf[i] = (byte) dest;
|
||||
}
|
||||
}
|
||||
|
||||
i -= off;
|
||||
pos += i;
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public final class ARMThumb implements SimpleFilter {
|
||||
|
||||
private final boolean isEncoder;
|
||||
private int pos;
|
||||
|
||||
@@ -23,7 +23,7 @@ public final class ARMThumb implements SimpleFilter {
|
||||
int end = off + len - 4;
|
||||
int i;
|
||||
|
||||
for (i = off; i <= end; i += 2) {
|
||||
for (i = off; i <= end; i += 2)
|
||||
if ((buf[i + 1] & 0xF8) == 0xF0 && (buf[i + 3] & 0xF8) == 0xF8) {
|
||||
int src = ((buf[i + 1] & 0x07) << 19)
|
||||
| ((buf[i] & 0xFF) << 11)
|
||||
@@ -38,13 +38,12 @@ public final class ARMThumb implements SimpleFilter {
|
||||
dest = src - (pos + i - off);
|
||||
|
||||
dest >>>= 1;
|
||||
buf[i + 1] = (byte)(0xF0 | ((dest >>> 19) & 0x07));
|
||||
buf[i] = (byte)(dest >>> 11);
|
||||
buf[i + 3] = (byte)(0xF8 | ((dest >>> 8) & 0x07));
|
||||
buf[i + 2] = (byte)dest;
|
||||
buf[i + 1] = (byte) (0xF0 | ((dest >>> 19) & 0x07));
|
||||
buf[i] = (byte) (dest >>> 11);
|
||||
buf[i + 3] = (byte) (0xF8 | ((dest >>> 8) & 0x07));
|
||||
buf[i + 2] = (byte) dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
i -= off;
|
||||
pos += i;
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public final class IA64 implements SimpleFilter {
|
||||
|
||||
private static final int[] BRANCH_TABLE = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 4, 6, 6, 0, 0, 7, 7,
|
||||
4, 4, 0, 0, 4, 4, 0, 0 };
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 4, 6, 6, 0, 0, 7, 7,
|
||||
4, 4, 0, 0, 4, 4, 0, 0};
|
||||
|
||||
private final boolean isEncoder;
|
||||
private int pos;
|
||||
@@ -47,11 +47,11 @@ public final class IA64 implements SimpleFilter {
|
||||
long instrNorm = instr >>> bitRes;
|
||||
|
||||
if (((instrNorm >>> 37) & 0x0F) != 0x05
|
||||
|| ((instrNorm >>> 9) & 0x07) != 0x00)
|
||||
|| ((instrNorm >>> 9) & 0x07) != 0x00)
|
||||
continue;
|
||||
|
||||
int src = (int)((instrNorm >>> 13) & 0x0FFFFF);
|
||||
src |= ((int)(instrNorm >>> 36) & 1) << 20;
|
||||
int src = (int) ((instrNorm >>> 13) & 0x0FFFFF);
|
||||
src |= ((int) (instrNorm >>> 36) & 1) << 20;
|
||||
src <<= 4;
|
||||
|
||||
int dest;
|
||||
@@ -70,7 +70,7 @@ public final class IA64 implements SimpleFilter {
|
||||
instr |= instrNorm << bitRes;
|
||||
|
||||
for (int j = 0; j < 6; ++j)
|
||||
buf[i + bytePos + j] = (byte)(instr >>> (8 * j));
|
||||
buf[i + bytePos + j] = (byte) (instr >>> (8 * j));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public final class PowerPC implements SimpleFilter {
|
||||
|
||||
private final boolean isEncoder;
|
||||
private int pos;
|
||||
|
||||
@@ -23,7 +23,7 @@ public final class PowerPC implements SimpleFilter {
|
||||
int end = off + len - 4;
|
||||
int i;
|
||||
|
||||
for (i = off; i <= end; i += 4) {
|
||||
for (i = off; i <= end; i += 4)
|
||||
if ((buf[i] & 0xFC) == 0x48 && (buf[i + 3] & 0x03) == 0x01) {
|
||||
int src = ((buf[i] & 0x03) << 24)
|
||||
| ((buf[i + 1] & 0xFF) << 16)
|
||||
@@ -36,12 +36,11 @@ public final class PowerPC implements SimpleFilter {
|
||||
else
|
||||
dest = src - (pos + i - off);
|
||||
|
||||
buf[i] = (byte)(0x48 | ((dest >>> 24) & 0x03));
|
||||
buf[i + 1] = (byte)(dest >>> 16);
|
||||
buf[i + 2] = (byte)(dest >>> 8);
|
||||
buf[i + 3] = (byte)((buf[i + 3] & 0x03) | dest);
|
||||
buf[i] = (byte) (0x48 | ((dest >>> 24) & 0x03));
|
||||
buf[i + 1] = (byte) (dest >>> 16);
|
||||
buf[i + 2] = (byte) (dest >>> 8);
|
||||
buf[i + 3] = (byte) ((buf[i + 3] & 0x03) | dest);
|
||||
}
|
||||
}
|
||||
|
||||
i -= off;
|
||||
pos += i;
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public final class SPARC implements SimpleFilter {
|
||||
|
||||
private final boolean isEncoder;
|
||||
private int pos;
|
||||
|
||||
@@ -23,9 +23,9 @@ public final class SPARC implements SimpleFilter {
|
||||
int end = off + len - 4;
|
||||
int i;
|
||||
|
||||
for (i = off; i <= end; i += 4) {
|
||||
for (i = off; i <= end; i += 4)
|
||||
if ((buf[i] == 0x40 && (buf[i + 1] & 0xC0) == 0x00)
|
||||
|| (buf[i] == 0x7F && (buf[i + 1] & 0xC0) == 0xC0)) {
|
||||
|| (buf[i] == 0x7F && (buf[i + 1] & 0xC0) == 0xC0)) {
|
||||
int src = ((buf[i] & 0xFF) << 24)
|
||||
| ((buf[i + 1] & 0xFF) << 16)
|
||||
| ((buf[i + 2] & 0xFF) << 8)
|
||||
@@ -42,12 +42,11 @@ public final class SPARC implements SimpleFilter {
|
||||
dest = (((0 - ((dest >>> 22) & 1)) << 22) & 0x3FFFFFFF)
|
||||
| (dest & 0x3FFFFF) | 0x40000000;
|
||||
|
||||
buf[i] = (byte)(dest >>> 24);
|
||||
buf[i + 1] = (byte)(dest >>> 16);
|
||||
buf[i + 2] = (byte)(dest >>> 8);
|
||||
buf[i + 3] = (byte)dest;
|
||||
buf[i] = (byte) (dest >>> 24);
|
||||
buf[i + 1] = (byte) (dest >>> 16);
|
||||
buf[i + 2] = (byte) (dest >>> 8);
|
||||
buf[i + 3] = (byte) dest;
|
||||
}
|
||||
}
|
||||
|
||||
i -= off;
|
||||
pos += i;
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public interface SimpleFilter {
|
||||
|
||||
int code(byte[] buf, int off, int len);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package org.tukaani.xz.simple;
|
||||
|
||||
public final class X86 implements SimpleFilter {
|
||||
|
||||
private static final boolean[] MASK_TO_ALLOWED_STATUS
|
||||
= {true, true, true, false, true, false, false, false};
|
||||
= {true, true, true, false, true, false, false, false};
|
||||
|
||||
private static final int[] MASK_TO_BIT_NUMBER = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
@@ -40,18 +40,17 @@ public final class X86 implements SimpleFilter {
|
||||
continue;
|
||||
|
||||
prevPos = i - prevPos;
|
||||
if ((prevPos & ~3) != 0) { // (unsigned)prevPos > 3
|
||||
if ((prevPos & ~3) != 0) // (unsigned)prevPos > 3
|
||||
prevMask = 0;
|
||||
} else {
|
||||
else {
|
||||
prevMask = (prevMask << (prevPos - 1)) & 7;
|
||||
if (prevMask != 0) {
|
||||
if (prevMask != 0)
|
||||
if (!MASK_TO_ALLOWED_STATUS[prevMask] || test86MSByte(
|
||||
buf[i + 4 - MASK_TO_BIT_NUMBER[prevMask]])) {
|
||||
buf[i + 4 - MASK_TO_BIT_NUMBER[prevMask]])) {
|
||||
prevPos = i;
|
||||
prevMask = (prevMask << 1) | 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevPos = i;
|
||||
@@ -72,20 +71,19 @@ public final class X86 implements SimpleFilter {
|
||||
break;
|
||||
|
||||
int index = MASK_TO_BIT_NUMBER[prevMask] * 8;
|
||||
if (!test86MSByte((byte)(dest >>> (24 - index))))
|
||||
if (!test86MSByte((byte) (dest >>> (24 - index))))
|
||||
break;
|
||||
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
|
||||
buf[i + 1] = (byte)dest;
|
||||
buf[i + 2] = (byte)(dest >>> 8);
|
||||
buf[i + 3] = (byte)(dest >>> 16);
|
||||
buf[i + 4] = (byte)(~(((dest >>> 24) & 1) - 1));
|
||||
buf[i + 1] = (byte) dest;
|
||||
buf[i + 2] = (byte) (dest >>> 8);
|
||||
buf[i + 3] = (byte) (dest >>> 16);
|
||||
buf[i + 4] = (byte) (~(((dest >>> 24) & 1) - 1));
|
||||
i += 4;
|
||||
} else {
|
||||
} else
|
||||
prevMask = (prevMask << 1) | 1;
|
||||
}
|
||||
}
|
||||
|
||||
prevPos = i - prevPos;
|
||||
|
||||
Reference in New Issue
Block a user