Files
Brainstorm/Common/src/com/common/io/CompressionOutputStream.java
2014-05-30 10:31:51 -07:00

153 lines
4.7 KiB
Java

/*
* Copyright (c) 2003,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.common.io;
import java.io.OutputStream;
import java.io.IOException;
import java.util.zip.*;
public class CompressionOutputStream extends OutputStream implements IOutputStream {
public static final int DEFAULT_BUFFER_SIZE = 301;
public static final int MAX_BUFFER_SIZE = 65535;
protected OutputStream stream = null;
protected Deflater deflater = null;
protected byte[] outputBuffer = null;
/**
* CompressionOutputStream constructor.
* @param stream The stream that will handle all output from this stream.
*/
public CompressionOutputStream(OutputStream stream) {
this(stream, null, DEFAULT_BUFFER_SIZE);
}//CompressionOutputStream()//
/**
* CompressionOutputStream constructor.
* @param stream The stream that will handle all output from this stream.
* @param deflater The deflater to be used.
*/
public CompressionOutputStream(OutputStream stream, Deflater deflater) {
this(stream, deflater, DEFAULT_BUFFER_SIZE);
}//CompressionOutputStream()//
/**
* CompressionOutputStream constructor.
* @param stream The stream that will handle all output from this stream.
* @param deflater The deflater to be used.
* @param bufferSize The size of the buffer used to read from the deflater.
*/
public CompressionOutputStream(OutputStream stream, Deflater deflater, int bufferSize) {
//Validate the inputs.//
if(bufferSize < 1) {
throw new IllegalArgumentException("Buffer size must be greater than zero.");
}//if//
else if(bufferSize > MAX_BUFFER_SIZE) {
throw new IllegalArgumentException("Buffer size must be less than " + MAX_BUFFER_SIZE + ".");
}//else if//
else if(stream == null) {
throw new IllegalArgumentException("A non-null output stream must be provided.");
}//else if//
else if(deflater == null) {
deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
}//else if//
this.stream = stream;
this.deflater = deflater;
this.outputBuffer = new byte[bufferSize];
}//CompressionOutputStream()//
/* (non-Javadoc)
* @see java.io.IOutputStream#canEncrypt()
*/
public boolean canEncrypt() {
return (stream instanceof IOutputStream) && (((IOutputStream) stream).canEncrypt());
}//canEncrypt()//
/* (non-Javadoc)
* @see java.io.OutputStream#close()
*/
public void close() throws IOException {
deflater.finish();
deflate();
super.close();
}//close()//
/**
* Deflates the cached data.
*/
private void deflate() throws IOException {
int count = 0;
while((count = deflater.deflate(outputBuffer, 2, outputBuffer.length - 2)) > 0) {
StreamSupport.writeShort((short) count, outputBuffer, 0); //Note: count should never exceed the buffer length and thus should stay within two bytes in size.//
stream.write(outputBuffer, 0, count + 2);
}//while//
/* Another way of doing the same thing I think.
while(!deflater.needsInput()) {
int count = deflater.deflate(outputBuffer);
if(count > 0) {
stream.write(outputBuffer, 0, count);
}//if//
}//while//
*/
}//deflate()//
/* (non-Javadoc)
* @see java.io.IOutputStream#encrypt(boolean)
*/
public void encrypt(boolean encrypt) throws IOException {
if(stream instanceof IOutputStream) {
if(((IOutputStream) stream).canEncrypt()) {
flush();
((IOutputStream) stream).encrypt(encrypt);
}//if//
else {
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
}//else//
}//if//
else {
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
}//else//
}//encrypt()//
/* (non-Javadoc)
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException {
if(deflater.getTotalIn() > 0) {
deflater.finish();
deflate();
deflater.reset();
}//if//
stream.flush();
}//flush()//
/* (non-Javadoc)
* @see java.io.IOutputStream#isEncrypting()
*/
public boolean isEncrypting() {
return (stream instanceof IOutputStream) && (((IOutputStream) stream).isEncrypting());
}//isEncrypting()//
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[])
*/
public void write(byte[] buffer) throws IOException {
write(buffer, 0, buffer.length);
}//write()//
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte[] buffer, int offset, int length) throws IOException {
deflater.setInput(buffer, offset, length);
deflate();
}//write()//
/* (non-Javadoc)
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException {
outputBuffer[0] = (byte) (b & 0xFF);
write(outputBuffer, 0, 1);
}//write()//
}//CompressionOutputStream//