/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.io.converters;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import xxl.core.io.DataInputInputStream;
import xxl.core.io.DataOutputOutputStream;
/**
* This class provides a converter that converts a byte array into a zip
* compressed byte array representation and vice versa. Only big byte arrays
* (>256 Bytes) are worth compressing!
*
* @see DataInput
* @see DataOutput
* @see IOException
*/
public class ByteArrayZipConverter extends Converter<byte[]> {
/**
* This instance can be used for getting a default instance of a byte array
* zip converter. It is similar to the <i>Singleton Design Pattern</i> (for
* further details see Creational Patterns, Prototype in <i>Design
* Patterns: Elements of Reusable Object-Oriented Software</i> by Erich
* Gamma, Richard Helm, Ralph Johnson, and John Vlissides) except that
* there are no mechanisms to avoid the creation of other instances of a
* byte array zip converter.
*/
public static final ByteArrayZipConverter DEFAULT_INSTANCE = new ByteArrayZipConverter();
/**
* Reads in a zip compressed byte array for the specified from the
* specified data input and returns the decompressed byte array.
*
* <p>When the specified <code>byte</code> array is <code>null</code> or
* the size of the specified byte array is not sufficient, this
* implementation returns a new array of <code>byte</code> values.</p>
*
* @param dataInput the stream to read a string from in order to return an
* decompressed byte array.
* @param object the byte array to be decompressed.
* @return the read decompressed byte array.
* @throws IOException if I/O errors occur.
*/
@Override
public byte[] read(DataInput dataInput, byte[] object) throws IOException {
// decompresses the data from dataInput and returns the decompressed byte array
ZipInputStream zis = new ZipInputStream(new DataInputInputStream(dataInput));
// ZipEntry entry
zis.getNextEntry();
if (object != null && zis.read(object) < object.length)
// the decompressed data fit into the given byte array
return object;
// collect the decompressed data into a byte array output stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (object != null)
// write the read data
baos.write(object);
if (object == null || object.length < 512)
// get a well-sized buffer
object = new byte[512];
int read;
do {
read = zis.read(object);
baos.write(object, 0, Math.max(0, read));
}
while (read == object.length);
return baos.toByteArray();
}
/**
* Writes the specified <code>byte</code> array compressed to the specified
* data output.
*
* @param dataOutput the stream to write the string representation of the
* specified object to.
* @param object the byte array object that string representation should be
* written to the data output.
* @throws IOException includes any I/O exceptions that may occur.
*/
@Override
public void write(DataOutput dataOutput, byte[] object) throws IOException {
// compressed the byte array object to DataOutput.
ZipOutputStream zos = new ZipOutputStream(new DataOutputOutputStream(dataOutput));
zos.setMethod(ZipOutputStream.DEFLATED);
zos.putNextEntry(new ZipEntry("a"));
zos.write(object, 0, object.length);
zos.finish();
zos.close();
}
}