View Javadoc
1   package org.apache.commons.jcs.utils.zip;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  import java.io.ByteArrayInputStream;
26  import java.io.ByteArrayOutputStream;
27  import java.io.IOException;
28  import java.util.zip.DataFormatException;
29  import java.util.zip.Deflater;
30  import java.util.zip.GZIPInputStream;
31  import java.util.zip.Inflater;
32  
33  /** Compress / Decompress. */
34  public final class CompressionUtil
35  {
36      /** The logger */
37      private static final Log log = LogFactory.getLog( CompressionUtil.class );
38  
39      /**
40       * no instances.
41       */
42      private CompressionUtil()
43      {
44          // NO OP
45      }
46  
47      /**
48       * Decompress the byte array passed using a default buffer length of 1024.
49       * <p>
50       * @param input compressed byte array webservice response
51       * @return uncompressed byte array
52       */
53      public static byte[] decompressByteArray( final byte[] input )
54      {
55          return decompressByteArray( input, 1024 );
56      }
57  
58      /**
59       * Decompress the byte array passed
60       * <p>
61       * @param input compressed byte array webservice response
62       * @param bufferLength buffer length
63       * @return uncompressed byte array
64       */
65      public static byte[] decompressByteArray( final byte[] input, final int bufferLength )
66      {
67          if ( null == input )
68          {
69              throw new IllegalArgumentException( "Input was null" );
70          }
71  
72          // Create the decompressor and give it the data to compress
73          final Inflater decompressor = new Inflater();
74  
75          decompressor.setInput( input );
76  
77          // Create an expandable byte array to hold the decompressed data
78          final ByteArrayOutputStream baos = new ByteArrayOutputStream( input.length );
79  
80          // Decompress the data
81          final byte[] buf = new byte[bufferLength];
82  
83          try
84          {
85              while ( !decompressor.finished() )
86              {
87                  int count = decompressor.inflate( buf );
88                  baos.write( buf, 0, count );
89              }
90          }
91          catch ( DataFormatException ex )
92          {
93              log.error( "Problem decompressing.", ex );
94          }
95  
96          decompressor.end();
97  
98          try
99          {
100             baos.close();
101         }
102         catch ( IOException ex )
103         {
104             log.error( "Problem closing stream.", ex );
105         }
106 
107         return baos.toByteArray();
108     }
109 
110     /**
111      * Compress the byte array passed
112      * <p>
113      * @param input byte array
114      * @return compressed byte array
115      * @throws IOException thrown if we can't close the output stream
116      */
117     public static byte[] compressByteArray( byte[] input )
118         throws IOException
119     {
120         return compressByteArray( input, 1024 );
121     }
122 
123     /**
124      * Compress the byte array passed
125      * <p>
126      * @param input byte array
127      * @param bufferLength buffer length
128      * @return compressed byte array
129      * @throws IOException thrown if we can't close the output stream
130      */
131     public static byte[] compressByteArray( byte[] input, int bufferLength )
132         throws IOException
133     {
134         // Compressor with highest level of compression
135         Deflater compressor = new Deflater();
136         compressor.setLevel( Deflater.BEST_COMPRESSION );
137 
138         // Give the compressor the data to compress
139         compressor.setInput( input );
140         compressor.finish();
141 
142         // Create an expandable byte array to hold the compressed data.
143         // It is not necessary that the compressed data will be smaller than
144         // the uncompressed data.
145         ByteArrayOutputStream bos = new ByteArrayOutputStream( input.length );
146 
147         // Compress the data
148         byte[] buf = new byte[bufferLength];
149         while ( !compressor.finished() )
150         {
151             int count = compressor.deflate( buf );
152             bos.write( buf, 0, count );
153         }
154 
155         // JCS-136 ( Details here : http://www.devguli.com/blog/eng/java-deflater-and-outofmemoryerror/ )
156         compressor.end();
157         bos.close();
158 
159         // Get the compressed data
160         return bos.toByteArray();
161 
162     }
163 
164     /**
165      * decompress a gzip byte array, using a default buffer length of 1024
166      * <p>
167      * @param compressedByteArray gzip-compressed byte array
168      * @return decompressed byte array
169      * @throws IOException thrown if there was a failure to construct the GzipInputStream
170      */
171     public static byte[] decompressGzipByteArray( byte[] compressedByteArray )
172         throws IOException
173     {
174         return decompressGzipByteArray( compressedByteArray, 1024 );
175     }
176 
177     /**
178      * decompress a gzip byte array, using a default buffer length of 1024
179      * <p>
180      * @param compressedByteArray gzip-compressed byte array
181      * @param bufferlength size of the buffer in bytes
182      * @return decompressed byte array
183      * @throws IOException thrown if there was a failure to construct the GzipInputStream
184      */
185     public static byte[] decompressGzipByteArray( byte[] compressedByteArray, int bufferlength )
186         throws IOException
187     {
188         ByteArrayOutputStream uncompressedStream = new ByteArrayOutputStream();
189 
190         GZIPInputStream compressedStream = new GZIPInputStream( new ByteArrayInputStream( compressedByteArray ) );
191 
192         byte[] buffer = new byte[bufferlength];
193 
194         int index = -1;
195 
196         while ( ( index = compressedStream.read( buffer ) ) != -1 )
197         {
198             uncompressedStream.write( buffer, 0, index );
199         }
200 
201         return uncompressedStream.toByteArray();
202     }
203 }