All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.util.io.GZIPCompressInputStream Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
package com.hfg.util.io;

import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;
import java.util.zip.Deflater;

//------------------------------------------------------------------------------
/**
 Provides an InputStream that applies GZIP compression.

 
Based on discussion at http://stackoverflow.com/questions/11036280/compress-an-inputstream-with-gzip.
@author J. Alex Taylor, hairyfatguy.com
*/ //------------------------------------------------------------------------------ // com.hfg XML/HTML Coding Library // // 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 2.1 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, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com // [email protected] //------------------------------------------------------------------------------ public class GZIPCompressInputStream extends FilterInputStream { private byte[] mBuffer = new byte[8196]; private byte[] mInputBuffer = new byte[4096]; private int mBufferLimit; private int mBufferIndex; private boolean mEndOfStreamReached; private long mBytesRead = 0; private enum State { HEADER, DATA, FINALIZATION, TRAILER, FINISH } // GZIP header magic number private final static int GZIP_MAGIC = 0x8b1f; private static final byte[] GZIP_HEADER = new byte[] { (byte) GZIP_MAGIC, // Magic number (short) (byte)(GZIP_MAGIC >> 8), // Magic number (short) Deflater.DEFLATED, // Compression method (CM) 0, // Flags (FLG) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Extra flags (XFLG) 0 // Operating system (OS) }; // Set the initial state private State mCurrentState = State.HEADER; private final Deflater mDeflater = new Deflater(Deflater.DEFLATED, true); private final CRC32 mChecksum = new CRC32(); private ByteArrayInputStream mTrailer; //########################################################################## // CONSTRUCTORS //########################################################################## //-------------------------------------------------------------------------- public GZIPCompressInputStream(InputStream inValue) { super(inValue); mChecksum.reset(); } //########################################################################## // PUBLIC METHODS //########################################################################## //--------------------------------------------------------------------------- @Override public int read() throws IOException { while (mBufferIndex >= mBufferLimit && ! mEndOfStreamReached) { fillBuffer(); } return (mEndOfStreamReached ? -1 : mBuffer[mBufferIndex++]); } //--------------------------------------------------------------------------- @Override public int read(byte[] inBuffer, int inOffset, int inMaxReadLength) throws IOException { int numCharsRead = 0; do { byte theByte= (byte) read(); if (! mEndOfStreamReached) { inBuffer[inOffset++] = theByte; numCharsRead++; } } while (! mEndOfStreamReached && numCharsRead < inMaxReadLength); return (mEndOfStreamReached && 0 == numCharsRead ? -1 : numCharsRead); } //-------------------------------------------------------------------------- @Override public void close() throws IOException { super.close(); mDeflater.end(); if(mTrailer != null) { mTrailer.close(); } } //--------------------------------------------------------------------------- private void fillBuffer() throws IOException { switch(mCurrentState) { case HEADER: System.arraycopy(GZIP_HEADER, 0, mBuffer, 0, GZIP_HEADER.length); mBufferLimit = GZIP_HEADER.length; mCurrentState = State.DATA; break; case DATA: mBufferLimit = 0; int inputBufferLimit = 0; while (mBufferLimit < mBuffer.length && inputBufferLimit >= 0) { while (mDeflater.needsInput() && inputBufferLimit >= 0) { inputBufferLimit = super.in.read(mInputBuffer, 0, mInputBuffer.length); if (inputBufferLimit > 0) { mBytesRead += inputBufferLimit; mDeflater.setInput(mInputBuffer, 0, inputBufferLimit); mChecksum.update(mInputBuffer, 0, inputBufferLimit); } } while (! mDeflater.needsInput() && mBufferLimit < mBuffer.length) { mBufferLimit += mDeflater.deflate(mBuffer, mBufferLimit, mBuffer.length - mBufferLimit, Deflater.NO_FLUSH); } } if (-1 == inputBufferLimit) { mCurrentState = State.FINALIZATION; mDeflater.finish(); } break; case FINALIZATION: if (mDeflater.finished()) { long checksumValue = mChecksum.getValue(); long compressionInputLength = mDeflater.getBytesRead(); mTrailer = new ByteArrayInputStream( new byte[] { (byte) (checksumValue >> 0), (byte) (checksumValue >> 8), (byte) (checksumValue >> 16), (byte) (checksumValue >> 24), (byte) (compressionInputLength >> 0), (byte) (compressionInputLength >> 8), (byte) (compressionInputLength >> 16), (byte) (compressionInputLength >> 24), }); mCurrentState = State.TRAILER; mBufferLimit = 0; } else { mBufferLimit = mDeflater.deflate(mBuffer, 0, mBuffer.length, Deflater.FULL_FLUSH); } break; case TRAILER: mBufferLimit = mTrailer.read(mBuffer, 0, mBuffer.length); if (mTrailer.available() == 0) { mCurrentState = State.FINISH; } break; case FINISH: mEndOfStreamReached = true; break; } // Reset the index mBufferIndex = 0; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy