/* * 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//