All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.zving.preloader.zip.ZipOutputStream Maven / Gradle / Ivy
package com.zving.preloader.zip;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.ZipException;
public class ZipOutputStream
extends FilterOutputStream
{
private static final int BYTE_MASK = 255;
private static final int SHORT = 2;
private static final int WORD = 4;
private static final int BUFFER_SIZE = 512;
private static final int DEFLATER_BLOCK_SIZE = 8192;
public static final int DEFLATED = 8;
public static final int DEFAULT_COMPRESSION = -1;
public static final int STORED = 0;
static final String DEFAULT_ENCODING = null;
public static final int UFT8_NAMES_FLAG = 2048;
/**
* @deprecated
*/
public static final int EFS_FLAG = 2048;
private ZipEntry entry;
private String comment = "";
private int level = -1;
private boolean hasCompressionLevelChanged = false;
private int method = 8;
private final List entries = new LinkedList();
private final CRC32 crc = new CRC32();
private long written = 0L;
private long dataStart = 0L;
private long localDataStart = 0L;
private long cdOffset = 0L;
private long cdLength = 0L;
private static final byte[] ZERO = new byte[2];
private static final byte[] LZERO = new byte[4];
private final Map offsets = new HashMap();
private String encoding = null;
private ZipEncoding zipEncoding = ZipEncodingHelper.getZipEncoding(DEFAULT_ENCODING);
protected Deflater def = new Deflater(this.level, true);
protected byte[] buf = new byte['Ȁ'];
private RandomAccessFile raf = null;
private boolean useUTF8Flag = true;
private boolean fallbackToUTF8 = false;
private UnicodeExtraFieldPolicy createUnicodeExtraFields = UnicodeExtraFieldPolicy.NEVER;
public ZipOutputStream(OutputStream out)
{
super(out);
}
public ZipOutputStream(File file)
throws IOException
{
super(null);
try
{
this.raf = new RandomAccessFile(file, "rw");
this.raf.setLength(0L);
}
catch (IOException e)
{
if (this.raf != null)
{
try
{
this.raf.close();
}
catch (IOException localIOException1) {}
this.raf = null;
}
this.out = new FileOutputStream(file);
}
}
public boolean isSeekable()
{
return this.raf != null;
}
public void setEncoding(String encoding)
{
this.encoding = encoding;
this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
this.useUTF8Flag = ((this.useUTF8Flag) && (ZipEncodingHelper.isUTF8(encoding)));
}
public String getEncoding()
{
return this.encoding;
}
public void setUseLanguageEncodingFlag(boolean b)
{
this.useUTF8Flag = ((b) && (ZipEncodingHelper.isUTF8(this.encoding)));
}
public void setCreateUnicodeExtraFields(UnicodeExtraFieldPolicy b)
{
this.createUnicodeExtraFields = b;
}
public void setFallbackToUTF8(boolean b)
{
this.fallbackToUTF8 = b;
}
public void finish()
throws IOException
{
closeEntry();
this.cdOffset = this.written;
for (Iterator i = this.entries.iterator(); i.hasNext();) {
writeCentralFileHeader((ZipEntry)i.next());
}
this.cdLength = (this.written - this.cdOffset);
writeCentralDirectoryEnd();
this.offsets.clear();
this.entries.clear();
this.def.end();
}
public void closeEntry()
throws IOException
{
if (this.entry == null) {
return;
}
long realCrc = this.crc.getValue();
this.crc.reset();
if (this.entry.getMethod() == 8)
{
this.def.finish();
while (!this.def.finished()) {
deflate();
}
this.entry.setSize(adjustToLong(this.def.getTotalIn()));
this.entry.setCompressedSize(adjustToLong(this.def.getTotalOut()));
this.entry.setCrc(realCrc);
this.def.reset();
this.written += this.entry.getCompressedSize();
}
else if (this.raf == null)
{
if (this.entry.getCrc() != realCrc) {
throw new ZipException("bad CRC checksum for entry " + this.entry.getName() + ": " + Long.toHexString(this.entry.getCrc()) +
" instead of " + Long.toHexString(realCrc));
}
if (this.entry.getSize() != this.written - this.dataStart) {
throw new ZipException("bad size for entry " + this.entry.getName() + ": " + this.entry.getSize() + " instead of " + (
this.written - this.dataStart));
}
}
else
{
long size = this.written - this.dataStart;
this.entry.setSize(size);
this.entry.setCompressedSize(size);
this.entry.setCrc(realCrc);
}
if (this.raf != null)
{
long save = this.raf.getFilePointer();
this.raf.seek(this.localDataStart);
writeOut(ZipLong.getBytes(this.entry.getCrc()));
writeOut(ZipLong.getBytes(this.entry.getCompressedSize()));
writeOut(ZipLong.getBytes(this.entry.getSize()));
this.raf.seek(save);
}
writeDataDescriptor(this.entry);
this.entry = null;
}
public void putNextEntry(ZipEntry ze)
throws IOException
{
closeEntry();
this.entry = ze;
this.entries.add(this.entry);
if (this.entry.getMethod() == -1) {
this.entry.setMethod(this.method);
}
if (this.entry.getTime() == -1L) {
this.entry.setTime(System.currentTimeMillis());
}
if ((this.entry.getMethod() == 0) && (this.raf == null))
{
if (this.entry.getSize() == -1L) {
throw new ZipException("uncompressed size is required for STORED method when not writing to a file");
}
if (this.entry.getCrc() == -1L) {
throw new ZipException("crc checksum is required for STORED method when not writing to a file");
}
this.entry.setCompressedSize(this.entry.getSize());
}
if ((this.entry.getMethod() == 8) && (this.hasCompressionLevelChanged))
{
this.def.setLevel(this.level);
this.hasCompressionLevelChanged = false;
}
writeLocalFileHeader(this.entry);
}
public void setComment(String comment)
{
this.comment = comment;
}
public void setLevel(int level)
{
if ((level < -1) || (level > 9)) {
throw new IllegalArgumentException("Invalid compression level: " + level);
}
this.hasCompressionLevelChanged = (this.level != level);
this.level = level;
}
public void setMethod(int method)
{
this.method = method;
}
public void write(byte[] b, int offset, int length)
throws IOException
{
if (this.entry.getMethod() == 8)
{
if ((length > 0) &&
(!this.def.finished())) {
if (length <= 8192)
{
this.def.setInput(b, offset, length);
deflateUntilInputIsNeeded();
}
else
{
int fullblocks = length / 8192;
for (int i = 0; i < fullblocks; i++)
{
this.def.setInput(b, offset + i * 8192, 8192);
deflateUntilInputIsNeeded();
}
int done = fullblocks * 8192;
if (done < length)
{
this.def.setInput(b, offset + done, length - done);
deflateUntilInputIsNeeded();
}
}
}
}
else
{
writeOut(b, offset, length);
this.written += length;
}
this.crc.update(b, offset, length);
}
public void write(int b)
throws IOException
{
byte[] buff = new byte[1];
buff[0] = ((byte)(b & 0xFF));
write(buff, 0, 1);
}
public void close()
throws IOException
{
finish();
if (this.raf != null) {
this.raf.close();
}
if (this.out != null) {
this.out.close();
}
}
public void flush()
throws IOException
{
if (this.out != null) {
this.out.flush();
}
}
protected static final byte[] LFH_SIG = ZipLong.getBytes(67324752L);
protected static final byte[] DD_SIG = ZipLong.getBytes(134695760L);
protected static final byte[] CFH_SIG = ZipLong.getBytes(33639248L);
protected static final byte[] EOCD_SIG = ZipLong.getBytes(101010256L);
protected final void deflate()
throws IOException
{
int len = this.def.deflate(this.buf, 0, this.buf.length);
if (len > 0) {
writeOut(this.buf, 0, len);
}
}
protected void writeLocalFileHeader(ZipEntry ze)
throws IOException
{
boolean encodable = this.zipEncoding.canEncode(ze.getName());
ZipEncoding entryEncoding;
if ((!encodable) && (this.fallbackToUTF8)) {
entryEncoding = ZipEncodingHelper.UTF8_ZIP_ENCODING;
} else {
entryEncoding = this.zipEncoding;
}
ByteBuffer name = entryEncoding.encode(ze.getName());
if (this.createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER)
{
if ((this.createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS) || (!encodable)) {
ze.addExtraField(new UnicodePathExtraField(ze.getName(), name.array(), name.arrayOffset(), name.limit()));
}
String comm = ze.getComment();
if ((comm != null) && (!"".equals(comm)))
{
boolean commentEncodable = this.zipEncoding.canEncode(comm);
if ((this.createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS) || (!commentEncodable))
{
ByteBuffer commentB = entryEncoding.encode(comm);
ze.addExtraField(new UnicodeCommentExtraField(comm, commentB.array(), commentB.arrayOffset(), commentB.limit()));
}
}
}
this.offsets.put(ze, ZipLong.getBytes(this.written));
writeOut(LFH_SIG);
this.written += 4L;
int zipMethod = ze.getMethod();
writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod, (!encodable) && (this.fallbackToUTF8));
this.written += 4L;
writeOut(ZipShort.getBytes(zipMethod));
this.written += 2L;
writeOut(toDosTime(ze.getTime()));
this.written += 4L;
this.localDataStart = this.written;
if ((zipMethod == 8) || (this.raf != null))
{
writeOut(LZERO);
writeOut(LZERO);
writeOut(LZERO);
}
else
{
writeOut(ZipLong.getBytes(ze.getCrc()));
writeOut(ZipLong.getBytes(ze.getSize()));
writeOut(ZipLong.getBytes(ze.getSize()));
}
this.written += 12L;
writeOut(ZipShort.getBytes(name.limit()));
this.written += 2L;
byte[] extra = ze.getLocalFileDataExtra();
writeOut(ZipShort.getBytes(extra.length));
this.written += 2L;
writeOut(name.array(), name.arrayOffset(), name.limit());
this.written += name.limit();
writeOut(extra);
this.written += extra.length;
this.dataStart = this.written;
}
protected void writeDataDescriptor(ZipEntry ze)
throws IOException
{
if ((ze.getMethod() != 8) || (this.raf != null)) {
return;
}
writeOut(DD_SIG);
writeOut(ZipLong.getBytes(this.entry.getCrc()));
writeOut(ZipLong.getBytes(this.entry.getCompressedSize()));
writeOut(ZipLong.getBytes(this.entry.getSize()));
this.written += 16L;
}
protected void writeCentralFileHeader(ZipEntry ze)
throws IOException
{
writeOut(CFH_SIG);
this.written += 4L;
writeOut(ZipShort.getBytes(ze.getPlatform() << 8 | 0x14));
this.written += 2L;
int zipMethod = ze.getMethod();
boolean encodable = this.zipEncoding.canEncode(ze.getName());
writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod, (!encodable) && (this.fallbackToUTF8));
this.written += 4L;
writeOut(ZipShort.getBytes(zipMethod));
this.written += 2L;
writeOut(toDosTime(ze.getTime()));
this.written += 4L;
writeOut(ZipLong.getBytes(ze.getCrc()));
writeOut(ZipLong.getBytes(ze.getCompressedSize()));
writeOut(ZipLong.getBytes(ze.getSize()));
this.written += 12L;
ZipEncoding entryEncoding;
if ((!encodable) && (this.fallbackToUTF8)) {
entryEncoding = ZipEncodingHelper.UTF8_ZIP_ENCODING;
} else {
entryEncoding = this.zipEncoding;
}
ByteBuffer name = entryEncoding.encode(ze.getName());
writeOut(ZipShort.getBytes(name.limit()));
this.written += 2L;
byte[] extra = ze.getCentralDirectoryExtra();
writeOut(ZipShort.getBytes(extra.length));
this.written += 2L;
String comm = ze.getComment();
if (comm == null) {
comm = "";
}
ByteBuffer commentB = entryEncoding.encode(comm);
writeOut(ZipShort.getBytes(commentB.limit()));
this.written += 2L;
writeOut(ZERO);
this.written += 2L;
writeOut(ZipShort.getBytes(ze.getInternalAttributes()));
this.written += 2L;
writeOut(ZipLong.getBytes(ze.getExternalAttributes()));
this.written += 4L;
writeOut((byte[])this.offsets.get(ze));
this.written += 4L;
writeOut(name.array(), name.arrayOffset(), name.limit());
this.written += name.limit();
writeOut(extra);
this.written += extra.length;
writeOut(commentB.array(), commentB.arrayOffset(), commentB.limit());
this.written += commentB.limit();
}
protected void writeCentralDirectoryEnd()
throws IOException
{
writeOut(EOCD_SIG);
writeOut(ZERO);
writeOut(ZERO);
byte[] num = ZipShort.getBytes(this.entries.size());
writeOut(num);
writeOut(num);
writeOut(ZipLong.getBytes(this.cdLength));
writeOut(ZipLong.getBytes(this.cdOffset));
ByteBuffer data = this.zipEncoding.encode(this.comment);
writeOut(ZipShort.getBytes(data.limit()));
writeOut(data.array(), data.arrayOffset(), data.limit());
}
private static final byte[] DOS_TIME_MIN = ZipLong.getBytes(8448L);
protected static ZipLong toDosTime(Date time)
{
return new ZipLong(toDosTime(time.getTime()));
}
protected static byte[] toDosTime(long t)
{
Calendar c = Calendar.getInstance();
c.setTimeInMillis(t);
int year = c.get(1);
if (year < 1980) {
return DOS_TIME_MIN;
}
int month = c.get(2) + 1;
long value = year - 1980 << 25 | month << 21 | c.get(5) << 16 | c.get(11) << 11 |
c.get(12) << 5 | c.get(13) >> 1;
return ZipLong.getBytes(value);
}
protected byte[] getBytes(String name)
throws ZipException
{
try
{
ByteBuffer b = ZipEncodingHelper.getZipEncoding(this.encoding).encode(name);
byte[] result = new byte[b.limit()];
System.arraycopy(b.array(), b.arrayOffset(), result, 0, result.length);
return result;
}
catch (IOException ex)
{
throw new ZipException("Failed to encode name: " + ex.getMessage());
}
}
protected final void writeOut(byte[] data)
throws IOException
{
writeOut(data, 0, data.length);
}
protected final void writeOut(byte[] data, int offset, int length)
throws IOException
{
if (this.raf != null) {
this.raf.write(data, offset, length);
} else {
this.out.write(data, offset, length);
}
}
protected static long adjustToLong(int i)
{
if (i < 0) {
return 4294967296L + i;
}
return i;
}
private void deflateUntilInputIsNeeded()
throws IOException
{
while (!this.def.needsInput()) {
deflate();
}
}
private void writeVersionNeededToExtractAndGeneralPurposeBits(int zipMethod, boolean utfFallback)
throws IOException
{
int versionNeededToExtract = 10;
int generalPurposeFlag = (this.useUTF8Flag) || (utfFallback) ? 2048 : 0;
if ((zipMethod == 8) && (this.raf == null))
{
versionNeededToExtract = 20;
generalPurposeFlag |= 0x8;
}
writeOut(ZipShort.getBytes(versionNeededToExtract));
writeOut(ZipShort.getBytes(generalPurposeFlag));
}
public static final class UnicodeExtraFieldPolicy
{
public static final UnicodeExtraFieldPolicy ALWAYS = new UnicodeExtraFieldPolicy("always");
public static final UnicodeExtraFieldPolicy NEVER = new UnicodeExtraFieldPolicy("never");
public static final UnicodeExtraFieldPolicy NOT_ENCODEABLE = new UnicodeExtraFieldPolicy("not encodeable");
private final String name;
private UnicodeExtraFieldPolicy(String n)
{
this.name = n;
}
public String toString()
{
return this.name;
}
}
}