mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
Merge branch 'addzip' of git://github.com/CUBoulderBoy/avian into CUBoulderBoy-addzip
This commit is contained in:
commit
da69b735f4
@ -12,4 +12,8 @@ package java.util.jar;
|
||||
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
public abstract class JarEntry extends ZipEntry { }
|
||||
public abstract class JarEntry extends ZipEntry {
|
||||
public JarEntry(){
|
||||
super(null);
|
||||
}
|
||||
}
|
||||
|
@ -11,16 +11,16 @@
|
||||
package java.util.zip;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DeflaterOutputStream extends OutputStream {
|
||||
private final OutputStream out;
|
||||
private final Deflater deflater;
|
||||
private final byte[] buffer;
|
||||
public class DeflaterOutputStream extends FilterOutputStream {
|
||||
protected final Deflater deflater;
|
||||
protected final byte[] buffer;
|
||||
|
||||
public DeflaterOutputStream(OutputStream out, Deflater deflater, int bufferSize)
|
||||
{
|
||||
this.out = out;
|
||||
super(out);
|
||||
this.deflater = deflater;
|
||||
this.buffer = new byte[bufferSize];
|
||||
}
|
||||
|
@ -10,12 +10,205 @@
|
||||
|
||||
package java.util.zip;
|
||||
|
||||
public abstract class ZipEntry {
|
||||
public abstract String getName();
|
||||
public abstract int getCompressedSize();
|
||||
public abstract int getSize();
|
||||
/**
|
||||
* Class ZipEntry:
|
||||
*
|
||||
* Class to store and retrieve information for entries in a zip file
|
||||
* Contains variables for all standard zip format field as well as
|
||||
* setter and accessor methods
|
||||
*
|
||||
* "name" is used to store the string name of the entrys
|
||||
* "reqVersion" stores a byte encoded minimum required version to open the zip
|
||||
* "compressionMethod" stores the method used to compress the zip
|
||||
* "modTimeDate" stores an MSDOS time field "millisTime" stores time in long format
|
||||
* "crc" stores crc data for the zip entry
|
||||
* "compSize" and "uncompSize" store compressed and uncompressed sizes
|
||||
* "offset" stores data regarding the offset from the start of the zip file
|
||||
*
|
||||
* @author Christopher Jordan
|
||||
* @author David Chau
|
||||
* @author Aaron Davis
|
||||
* @author Riley Moses
|
||||
*/
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class ZipEntry {
|
||||
String name;
|
||||
short reqVersion = -1;
|
||||
short compressionMethod = -1;
|
||||
int modTimeDate = -1;
|
||||
long millisTime = -1;
|
||||
int crc = -1;
|
||||
int compSize = 0;
|
||||
int uncompSize = 0;
|
||||
int offset = -1;
|
||||
|
||||
public ZipEntry(String name) {
|
||||
this.name = name;
|
||||
setTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
//Method to return name of the file
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
//Method to check if file is a directory
|
||||
public boolean isDirectory() {
|
||||
return getName().endsWith("/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setRequiredVersion:
|
||||
*
|
||||
* Method to set the minimum version required to open the zip file
|
||||
* Valid values for the compression method are the numbers 1.0 to 10.0
|
||||
*
|
||||
* @author Christopher Jordan
|
||||
*/
|
||||
private boolean setRequiredVersion(float versionFloat){
|
||||
//Check for valid version numbers
|
||||
if (versionFloat < 1 || versionFloat > 100){
|
||||
return false;
|
||||
}
|
||||
|
||||
//Convert to short value for storage
|
||||
versionFloat = versionFloat * 10;
|
||||
short versionShort = (short)versionFloat;
|
||||
|
||||
//Set value of version
|
||||
reqVersion = versionShort;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Method to set the compression method for the file
|
||||
//Valid methods are "stored" = 0 or "deflated" = 8
|
||||
public void setMethod(short compMethod){
|
||||
if (compMethod == 0 || compMethod == 8){
|
||||
this.compressionMethod = compMethod;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMethod(){
|
||||
return this.compressionMethod;
|
||||
}
|
||||
|
||||
//Methods to set and get the crc for the entry
|
||||
public void setCrc(int crc){
|
||||
if (crc < 0 || crc > 0xffffffff){
|
||||
return;
|
||||
}
|
||||
else
|
||||
this.crc = crc;
|
||||
}
|
||||
|
||||
public int getCrc(){
|
||||
return this.crc;
|
||||
}
|
||||
|
||||
//Methods to set and get the time and date
|
||||
public void setTime(long currentTime){
|
||||
modTimeDate = computeDOSDateTime(currentTime);
|
||||
millisTime = currentTime;
|
||||
}
|
||||
|
||||
public long getTime(){
|
||||
return millisTime;
|
||||
}
|
||||
|
||||
public int getJavaTime(){
|
||||
return modTimeDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method computeDOSDateTime():
|
||||
*
|
||||
* Takes the time from a long and converts to a Calendar object
|
||||
*
|
||||
* Time is stored in the MSDOS format 5 bits for hour, 6 bits for min, 5 bits for seconds
|
||||
* Hours are in military time and must be adjusted to time zone
|
||||
* Seconds are divided by two before storing and must be multiplied by two to retrieve
|
||||
*
|
||||
* Date is stored in the MSDOS format 7 bit for year, 4 bit for month, 5 bits for day of month
|
||||
* Year is the number of years since 1980 per, the month is stored starting at 0
|
||||
* for January. Day of month is stored with nature numbering
|
||||
*
|
||||
* Bit masks and shifting are used to build the time and date bytes
|
||||
*
|
||||
* @author Christopher Jordan
|
||||
* @author Aaron Davis
|
||||
**/
|
||||
private static int computeDOSDateTime(long currentTime){
|
||||
final int DAY_OF_MONTH = 5;
|
||||
final int HOUR_OF_DAY = 11;
|
||||
final int MINUTE = 12;
|
||||
final int MONTH = 2;
|
||||
final int SECOND = 13;
|
||||
final int YEAR = 1;
|
||||
|
||||
//Create calendar object, then set time to value passed in
|
||||
Calendar modCalendar = Calendar.getInstance();
|
||||
modCalendar.setTime(new Date(currentTime));
|
||||
|
||||
//Hour
|
||||
int timeBits = modCalendar.get(HOUR_OF_DAY);
|
||||
timeBits = timeBits - 6;
|
||||
timeBits = timeBits << 6;
|
||||
|
||||
//Minutes
|
||||
int minBits = 0x3f & (modCalendar.get(MINUTE));;
|
||||
timeBits = timeBits ^ minBits;
|
||||
timeBits = timeBits << 5;
|
||||
|
||||
//Seconds
|
||||
int secBits = 0x1f & (modCalendar.get(SECOND));
|
||||
secBits = secBits >> 1; //Divide by 2
|
||||
timeBits = timeBits ^ secBits;
|
||||
|
||||
//Year
|
||||
int dateBits = (modCalendar.get(YEAR) -1980);
|
||||
dateBits = dateBits << 4;
|
||||
|
||||
//Month
|
||||
int month = 0xf & ((modCalendar.get(MONTH)) + 1);
|
||||
dateBits = dateBits ^ month;
|
||||
dateBits = dateBits << 5;
|
||||
|
||||
//Day of month
|
||||
int dayBits = 0x1f & modCalendar.get(DAY_OF_MONTH);
|
||||
dateBits = dateBits ^ dayBits;
|
||||
|
||||
//Store Date
|
||||
int storeDate = ((dateBits << 16) ^ (timeBits));
|
||||
return storeDate;
|
||||
}
|
||||
|
||||
//Methods to set and get the uncompressed size of the entry
|
||||
public void setSize(int size){
|
||||
if (size < 0){
|
||||
return;
|
||||
}
|
||||
else
|
||||
uncompSize = size;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return uncompSize;
|
||||
}
|
||||
|
||||
//Methods to set and get the compressed size of the entry
|
||||
public void setCompressedSize(int size){
|
||||
if (size < 0){
|
||||
return;
|
||||
}
|
||||
else
|
||||
compSize = size;
|
||||
}
|
||||
|
||||
public int getCompressedSize() {
|
||||
return compSize;
|
||||
}
|
||||
}
|
||||
|
@ -285,6 +285,7 @@ public class ZipFile {
|
||||
public final int pointer;
|
||||
|
||||
public MyZipEntry(Window window, int pointer) {
|
||||
super(null);
|
||||
this.window = window;
|
||||
this.pointer = pointer;
|
||||
}
|
||||
|
246
classpath/java/util/zip/ZipOutputStream.java
Normal file
246
classpath/java/util/zip/ZipOutputStream.java
Normal file
@ -0,0 +1,246 @@
|
||||
/* Copyright (c) 2008-2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.util.zip;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
|
||||
/**
|
||||
* An as simple as possible implementation of ZipOutputStream
|
||||
* Compression method defaults to DEFLATE
|
||||
* All hardcoded defaults match the defaults for openJDK,
|
||||
* including PKZip version, bit flags set, compression level, etc
|
||||
*
|
||||
* @author David Chau
|
||||
* @author Aaron Davis
|
||||
* @author Christopher Jordan
|
||||
* @author Riley Moses
|
||||
*
|
||||
*/
|
||||
public class ZipOutputStream extends DeflaterOutputStream {
|
||||
private static final int SIGNATURE = 0x04034b50;
|
||||
private static final short VERSION = 0x0014;
|
||||
private static final short BITFLAG = 0x0008;
|
||||
private static final short METHOD = 0x0008;
|
||||
private static final int CENTRAL_FILE_HEADER = 0x02014b50;
|
||||
private static final int DATA_DESCRIPTER_HEADER = 0x08074b50;
|
||||
private static final int END_OF_CENTRAL_DIRECTORY_SIG = 0x06054b50;
|
||||
private static final int DEFAULT_LEVEL = 6;
|
||||
|
||||
private static final int INPUT_BUFFER_SIZE = 1024;
|
||||
|
||||
private List<ZipEntry> entries;
|
||||
private CRC32 crc = new CRC32();
|
||||
private ZipEntry currentEntry; // holder for current entry
|
||||
private int bytesWritten; // a counter for total bytes written
|
||||
private int sizeOfCentralDirectory; // a counter for central dir size
|
||||
|
||||
// these are used for the function write(int b) to provide a speed increase
|
||||
private byte[] inputBuffer = new byte[INPUT_BUFFER_SIZE];
|
||||
private int bufferIndex;
|
||||
|
||||
|
||||
public ZipOutputStream(OutputStream outStream) {
|
||||
super(outStream, new Deflater(DEFAULT_LEVEL, true));
|
||||
bytesWritten = 0;
|
||||
sizeOfCentralDirectory = 0;
|
||||
entries = new ArrayList<ZipEntry>();
|
||||
}
|
||||
|
||||
public void putNextEntry(ZipEntry e) throws IOException {
|
||||
e.offset = bytesWritten;
|
||||
currentEntry = e;
|
||||
entries.add(e);
|
||||
writeLocalHeader(e);
|
||||
}
|
||||
|
||||
public void closeEntry() throws IOException {
|
||||
// write remainder of buffer if partially full
|
||||
if (bufferIndex != 0) {
|
||||
write(inputBuffer, 0, bufferIndex);
|
||||
bufferIndex = 0;
|
||||
}
|
||||
|
||||
finish();
|
||||
|
||||
currentEntry.crc = (int) crc.getValue();
|
||||
crc.reset();
|
||||
writeDataDescriptor(currentEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int offset, int length) throws IOException {
|
||||
if (offset < 0 || length < 0 || b.length - (offset + length) < 0)
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
||||
currentEntry.uncompSize += length;
|
||||
crc.update(b, offset, length);
|
||||
currentEntry.crc = (int) crc.getValue();
|
||||
|
||||
deflater.setInput(b, offset, length);
|
||||
while (deflater.getRemaining() > 0)
|
||||
deflate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
inputBuffer[bufferIndex] = (byte)(b & 0xff);
|
||||
bufferIndex += 1;
|
||||
if (bufferIndex == 1024) {
|
||||
write(inputBuffer, 0, bufferIndex);
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void deflate() throws IOException {
|
||||
int len = deflater.deflate(buffer, 0, buffer.length);
|
||||
currentEntry.compSize += len;
|
||||
bytesWritten += len;
|
||||
if (len > 0)
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
private void writeLocalHeader(ZipEntry e) throws IOException {
|
||||
byte[] tmpBuffer = new byte[30];
|
||||
|
||||
addFourBytes(SIGNATURE, 0, tmpBuffer); // local header signature
|
||||
addTwoBytes(VERSION, 4, tmpBuffer); // version used
|
||||
addTwoBytes(BITFLAG, 6, tmpBuffer); // flags
|
||||
addTwoBytes(METHOD, 8, tmpBuffer); // compression method
|
||||
addFourBytes(e.modTimeDate, 10, tmpBuffer); // last mod date and time
|
||||
addFourBytes(0, 14, tmpBuffer); // CRC is 0 for local header
|
||||
|
||||
// with default flag settings (bit 3 set) the compressed and uncompressed size
|
||||
// is written here as 0 and written correctly in the data descripter
|
||||
addFourBytes(0, 18, tmpBuffer); // compressed size
|
||||
addFourBytes(0, 22, tmpBuffer); // uncompressed size
|
||||
addTwoBytes(e.name.length(), 26, tmpBuffer); // length of file name
|
||||
|
||||
// extra field length, in this implementation extra field in not used
|
||||
addTwoBytes(0, 28, tmpBuffer);
|
||||
|
||||
out.write(tmpBuffer, 0, 30);
|
||||
|
||||
// write file name, return the number of bytes written
|
||||
int len = writeUTF8(e.getName());
|
||||
|
||||
bytesWritten += 30 + len;
|
||||
}
|
||||
|
||||
private void writeDataDescriptor(ZipEntry currentEntry) throws IOException {
|
||||
byte[] tmpBuffer = new byte[16];
|
||||
|
||||
addFourBytes(DATA_DESCRIPTER_HEADER, 0, tmpBuffer); // data descripter header
|
||||
addFourBytes(currentEntry.crc, 4, tmpBuffer); // crc value
|
||||
addFourBytes(currentEntry.compSize, 8, tmpBuffer); // compressed size
|
||||
addFourBytes(currentEntry.uncompSize, 12, tmpBuffer);// uncompressed size
|
||||
out.write(tmpBuffer, 0, 16);
|
||||
bytesWritten += 16;
|
||||
}
|
||||
|
||||
private void writeCentralDirectoryHeader(ZipEntry e) throws IOException {
|
||||
byte[] tmpBuffer = new byte[46];
|
||||
|
||||
addFourBytes(CENTRAL_FILE_HEADER, 0, tmpBuffer); // central directory header signature
|
||||
addTwoBytes(VERSION, 4, tmpBuffer); // version made by
|
||||
addTwoBytes(VERSION, 6, tmpBuffer); // version needed
|
||||
addTwoBytes(BITFLAG, 8, tmpBuffer); // flags
|
||||
addTwoBytes(METHOD, 10, tmpBuffer); // compression method
|
||||
|
||||
addFourBytes(e.modTimeDate, 12, tmpBuffer); // last mod date and time
|
||||
addFourBytes(e.crc, 16, tmpBuffer); // crc
|
||||
addFourBytes(e.compSize, 20, tmpBuffer); // compressed size
|
||||
addFourBytes(e.uncompSize, 24, tmpBuffer); // uncompressed size
|
||||
|
||||
addTwoBytes(e.getName().length(), 28, tmpBuffer); // file name length
|
||||
|
||||
// the following 5 fields are all 0 for a simple default compression
|
||||
addTwoBytes(0, 30, tmpBuffer); // extra field length (not used)
|
||||
addTwoBytes(0, 32, tmpBuffer); // comment length (not used)
|
||||
addTwoBytes(0, 34, tmpBuffer); // disk number start
|
||||
addTwoBytes(0, 36, tmpBuffer); // internal file attribute
|
||||
addFourBytes(0, 38, tmpBuffer); // external file attribute
|
||||
|
||||
addFourBytes((int) e.offset, 42, tmpBuffer); // relative offset of local header
|
||||
|
||||
out.write(tmpBuffer, 0, 46);
|
||||
|
||||
int len = writeUTF8(e.getName());
|
||||
|
||||
bytesWritten += 46 + len;
|
||||
sizeOfCentralDirectory += 46 + len;
|
||||
}
|
||||
|
||||
private void writeEndofCentralDirectory(int offset) throws IOException {
|
||||
byte[] tmpBuffer = new byte[22];
|
||||
|
||||
short numEntries = (short) entries.size();
|
||||
addFourBytes(END_OF_CENTRAL_DIRECTORY_SIG, 0, tmpBuffer); // end of central directory signature
|
||||
addTwoBytes(0, 4, tmpBuffer); // disk number
|
||||
addTwoBytes(0, 6, tmpBuffer); // disk number where central dir starts
|
||||
addTwoBytes(numEntries, 8, tmpBuffer); // number of entries on this disk
|
||||
addTwoBytes(numEntries, 10, tmpBuffer); // number of entries in central dir
|
||||
addFourBytes(sizeOfCentralDirectory, 12, tmpBuffer); // length of central directory
|
||||
addFourBytes(offset, 16, tmpBuffer); // offset of central directory
|
||||
addTwoBytes(0, 20, tmpBuffer); // length of added comments (not used)
|
||||
out.write(tmpBuffer, 0, 22);
|
||||
bytesWritten += 22;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
int centralDirOffset = bytesWritten;
|
||||
for (ZipEntry e : entries)
|
||||
writeCentralDirectoryHeader(e);
|
||||
writeEndofCentralDirectory(centralDirOffset);
|
||||
deflater.dispose();
|
||||
out.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
out.write(inputBuffer, 0, inputBuffer.length);
|
||||
inputBuffer = new byte[INPUT_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
private void finish() throws IOException {
|
||||
deflater.finish();
|
||||
while (!deflater.finished()) {
|
||||
deflate();
|
||||
}
|
||||
deflater.reset();
|
||||
}
|
||||
|
||||
private void addTwoBytes(int bytes, int offset, byte[] buffer) throws IOException {
|
||||
buffer[offset] = (byte) (bytes & 0xff);
|
||||
buffer[offset + 1] = (byte) ((bytes >> 8) & 0xff);
|
||||
}
|
||||
|
||||
private void addFourBytes(int bytes, int offset, byte[] buffer) throws IOException {
|
||||
buffer[offset] = (byte) (bytes & 0xff);
|
||||
buffer[offset + 1] = (byte) ((bytes >> 8) & 0xff);
|
||||
buffer[offset + 2] = (byte) ((bytes >> 16) & 0xff);
|
||||
buffer[offset + 3] = (byte) ((bytes >> 24) & 0xff);
|
||||
}
|
||||
|
||||
private int writeUTF8(String text) throws IOException {
|
||||
byte[] bytes = text.getBytes("UTF-8");
|
||||
out.write(bytes, 0, bytes.length);
|
||||
return bytes.length;
|
||||
}
|
||||
}
|
56
test/ZipEntryTest.java
Normal file
56
test/ZipEntryTest.java
Normal file
@ -0,0 +1,56 @@
|
||||
/* Copyright (c) 2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
* class ZipEntryTest:
|
||||
*
|
||||
* class to test the ZipEntry class in java.util.zip
|
||||
*
|
||||
* @author Christopher Jordan
|
||||
*/
|
||||
public class ZipEntryTest {
|
||||
static long timeInMillis = 1373309644787L;
|
||||
static int dateInBytes = 1122526914;
|
||||
|
||||
public static void main(String args[]){
|
||||
ZipEntry testEntry = new ZipEntry("testfile");
|
||||
|
||||
verifyDefaultValues(testEntry);
|
||||
verifyTimeDate(testEntry, timeInMillis);
|
||||
checkSetsAndGets(testEntry);
|
||||
}
|
||||
|
||||
private static void verifyDefaultValues(ZipEntry testEntry){
|
||||
if (testEntry.getTime() == -1)
|
||||
throw new RuntimeException("The time isn't being set by the constructor");
|
||||
verifyName(testEntry);
|
||||
}
|
||||
|
||||
private static void verifyName(ZipEntry testEntry){
|
||||
if (testEntry.getName() == "testfile")
|
||||
return;
|
||||
else
|
||||
throw new RuntimeException("Name isn't being stored properly");
|
||||
}
|
||||
|
||||
private static void verifyTimeDate(ZipEntry testEntry, long timeMillis){
|
||||
testEntry.setTime(timeMillis);
|
||||
if (testEntry.getJavaTime() != dateInBytes)
|
||||
throw new RuntimeException("Date isn't being parsed properly");
|
||||
if (testEntry.getTime() != timeInMillis)
|
||||
throw new RuntimeException("Time isn't being stored accurately");
|
||||
}
|
||||
|
||||
private static void checkSetsAndGets(ZipEntry testEntry){
|
||||
return;
|
||||
}
|
||||
}
|
210
test/ZipOutputStreamTest.java
Normal file
210
test/ZipOutputStreamTest.java
Normal file
@ -0,0 +1,210 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class ZipOutputStreamTest
|
||||
{
|
||||
private static final String TEST1 = "test1.txt";
|
||||
private static final String TEST2 = "test2.txt";
|
||||
private static final String TEST3 = "test3.txt";
|
||||
private static final String TEST4 = "test4.txt";
|
||||
|
||||
private static final String TEST1_CONTENTS = "\"this is a test\"";
|
||||
private static final String TEST2_CONTENTS = "this is a\nmulti-line test";
|
||||
private static final String TEST3_CONTENTS = "74 68 69 73 20 69 73 20 61 20 74 65 73 74";
|
||||
private static final String TEST4_CONTENTS = "01110100 01101000 01101001 01110011 00100000 01101001 01110011 00100000 01100001 00100000 01110100 01100101 01110011 01110100";
|
||||
|
||||
private static final String ONE_PARAM_ZIP_PREFIX = "zos1param";
|
||||
private static final String THREE_PARAM_ZIP_PREFIX = "zos3param";
|
||||
private static final String ZIP_SUFFIX = ".zip";
|
||||
|
||||
private static final Map<String, String> FILES_CONTENTS;
|
||||
static
|
||||
{
|
||||
Map<String, String> m = new HashMap<String, String>();
|
||||
m.put(TEST1, TEST1_CONTENTS);
|
||||
m.put(TEST2, TEST2_CONTENTS);
|
||||
m.put(TEST3, TEST3_CONTENTS);
|
||||
m.put(TEST4, TEST4_CONTENTS);
|
||||
FILES_CONTENTS = Collections.unmodifiableMap(m);
|
||||
}
|
||||
|
||||
private static final boolean USE_ONE_PARAM_WRITE = true;
|
||||
private static final boolean USE_THREE_PARAM_WRITE = false;
|
||||
private static byte[] buffer = new byte[1024];
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
List<File> zipFiles = new ArrayList<File>(2);
|
||||
|
||||
// Test 1-param write function
|
||||
File f1 = createZip(USE_ONE_PARAM_WRITE);
|
||||
zipFiles.add(f1);
|
||||
verifyContents(f1.getAbsolutePath());
|
||||
// Test 3-param write function
|
||||
File f2 = createZip(USE_THREE_PARAM_WRITE);
|
||||
zipFiles.add(f2);
|
||||
verifyContents(f2.getAbsolutePath());
|
||||
// Remove the created zip files
|
||||
cleanUp(zipFiles);
|
||||
}
|
||||
|
||||
private static File createZip(boolean useOneParam)
|
||||
{
|
||||
FileOutputStream outputStream = null;
|
||||
ZipOutputStream zipContents = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Create a temporary zip file for this test
|
||||
String prefix = useOneParam ? ONE_PARAM_ZIP_PREFIX : THREE_PARAM_ZIP_PREFIX;
|
||||
File outputZip = File.createTempFile(prefix, ZIP_SUFFIX);
|
||||
|
||||
System.out.println("Created " + outputZip.getAbsolutePath());
|
||||
|
||||
// Prepare the streams
|
||||
outputStream = new FileOutputStream(outputZip);
|
||||
zipContents = new ZipOutputStream(outputStream);
|
||||
|
||||
// Zip the file contents (convert directly from string to bytes)
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (Map.Entry<String, String> f : FILES_CONTENTS.entrySet())
|
||||
{
|
||||
String name = f.getKey();
|
||||
String contents = f.getValue();
|
||||
|
||||
System.out.println("Zipping " + name + "...");
|
||||
ZipEntry entry = new ZipEntry(name);
|
||||
zipContents.putNextEntry(entry);
|
||||
|
||||
byte[] bytesToWrite = contents.getBytes();
|
||||
|
||||
if (useOneParam)
|
||||
{
|
||||
// Use the 1-parameter write method; takes a single byte
|
||||
for (int i = 0; i < bytesToWrite.length; i++)
|
||||
{
|
||||
zipContents.write(bytesToWrite[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use 3-parameter write method; takes a buffer, offset, and length
|
||||
zipContents.write(bytesToWrite, 0 , bytesToWrite.length);
|
||||
}
|
||||
|
||||
// Done with this file
|
||||
zipContents.closeEntry();
|
||||
System.out.println("Done");
|
||||
}
|
||||
|
||||
// All files have been written
|
||||
long endTime = System.currentTimeMillis();
|
||||
System.out.println("Finished " + outputZip.getName() + " in " + ((endTime - startTime) / 1000.0) + " seconds");
|
||||
return outputZip;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (zipContents != null)
|
||||
zipContents.close();
|
||||
if (outputStream != null)
|
||||
outputStream.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyContents(String zipName)
|
||||
{
|
||||
System.out.println("Verify " + zipName);
|
||||
ZipFile zf = null;
|
||||
BufferedReader reader = null;
|
||||
int numFilesInZip = 0;
|
||||
|
||||
try
|
||||
{
|
||||
String line;
|
||||
String contents;
|
||||
|
||||
// Get the contents of each file in the zip
|
||||
zf = new ZipFile(zipName);
|
||||
for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements();)
|
||||
{
|
||||
ZipEntry entry = e.nextElement();
|
||||
reader = new BufferedReader(new InputStreamReader(zf.getInputStream(entry)));
|
||||
contents = "";
|
||||
numFilesInZip += 1;
|
||||
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (contents.length() > 0)
|
||||
{
|
||||
contents += "\n";
|
||||
}
|
||||
contents += line;
|
||||
}
|
||||
reader.close();
|
||||
|
||||
// Assert that this file's contents are correct
|
||||
assert(contents.equals(FILES_CONTENTS.get(entry.getName())));
|
||||
}
|
||||
zf.close();
|
||||
|
||||
// Assert that the zip contained the correct number of files
|
||||
assert(numFilesInZip == FILES_CONTENTS.size());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (zf != null)
|
||||
zf.close();
|
||||
if (reader != null)
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanUp(List<File> zipFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (File f : zipFiles)
|
||||
{
|
||||
if (f.exists())
|
||||
{
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user