001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    
019    package org.activemq.io.util;
020    import java.io.IOException;
021    import java.util.zip.Deflater;
022    import java.util.zip.GZIPInputStream;
023    
024    /**
025     * Compression stream
026     * 
027     * @version $Revision: 1.1.1.1 $
028     */
029    public class ByteArrayCompression{
030        
031        /**
032         * Data size above which compression will be used
033         */
034        public static final int DEFAULT_COMPRESSION_LIMIT = 32 * 1024;
035        
036        /**
037         * Default compression level - 0 being none, 9 being best
038         */
039        public static final int DEFAULT_COMPRESSION_LEVEL = Deflater.BEST_SPEED;
040        
041        /**
042         * Default Compression Strategy
043         */
044        public static final int DEFAULT_COMPRESSION_STRATEGY = Deflater.DEFAULT_STRATEGY;
045        
046        private int compressionLimit = DEFAULT_COMPRESSION_LIMIT;
047        private int compressionLevel = DEFAULT_COMPRESSION_LEVEL;
048        private int compressionStrategy = DEFAULT_COMPRESSION_STRATEGY;//default compression strategy
049        
050        /**
051         * @return Returns the compressionLevel.
052         */
053        public int getCompressionLevel() {
054            return compressionLevel;
055        }
056        /**
057         * @param compressionLevel The compressionLevel to set.
058         */
059        public void setCompressionLevel(int compressionLevel) {
060            this.compressionLevel = compressionLevel;
061        }
062        /**
063         * @return Returns the compressionLimit.
064         */
065        public int getCompressionLimit() {
066            return compressionLimit;
067        }
068        /**
069         * @param compressionLimit The compressionLimit to set.
070         */
071        public void setCompressionLimit(int compressionLimit) {
072            this.compressionLimit = compressionLimit;
073        }
074        /**
075         * @return Returns the compressionStrategy.
076         */
077        public int getCompressionStrategy() {
078            return compressionStrategy;
079        }
080        /**
081         * @param compressionStrategy The compressionStrategy to set.
082         */
083        public void setCompressionStrategy(int compressionStrategy) {
084            this.compressionStrategy = compressionStrategy;
085        }
086        /**
087         * test for compressed data
088         * @param ba
089         * @return true if the data in the ByteArray is compressed
090         */
091        public static boolean isCompressed(ByteArray ba){
092            boolean answer = false;
093            if (ba != null && ba.getLength() > 2){
094               answer = ((int)(ba.get(0) & 0xff) | (int)((ba.get(1) & 0xff)<< 8)) == GZIPInputStream.GZIP_MAGIC;
095            }
096            return answer; 
097        }
098        
099        /**
100         * Deflate the data in the ByteArray
101         * @param ba
102         * @return the passed in ba if data is not compressed else a new ByteArray
103         * @throws IOException
104         */
105        public ByteArray deflate(ByteArray ba) throws IOException{
106            ByteArray answer = ba;
107            if (ba != null && ba.getLength() > compressionLimit && !ByteArrayCompression.isCompressed(ba)){
108                WireByteArrayOutputStream bytesOut = new WireByteArrayOutputStream();
109                WireGZIPOutputStream gzipOut = new WireGZIPOutputStream(bytesOut);
110                gzipOut.getDeflater().setStrategy(compressionStrategy);
111                gzipOut.getDeflater().setLevel(compressionLevel);
112                gzipOut.write(ba.getBuf(),ba.getOffset(),ba.getLength());
113                gzipOut.close();
114                bytesOut.close();
115                answer = new ByteArray(bytesOut.getData(),0,bytesOut.size());
116            }
117            return answer;
118        }
119        
120        /**
121         * Inflate a ByteArray (if it contains compressed data)
122         * @param ba
123         * @return the inflated ByteArray
124         * @throws IOException
125         */
126        public ByteArray inflate(ByteArray ba) throws IOException {
127            ByteArray answer = ba;
128            if (ba != null && ByteArrayCompression.isCompressed(ba)){
129                WireByteArrayInputStream bytesIn = new WireByteArrayInputStream(ba);
130                GZIPInputStream gzipIn = new GZIPInputStream(bytesIn);
131                WireByteArrayOutputStream bytesOut = new WireByteArrayOutputStream();
132                byte[] buffer = new byte[1024];
133                int count = 0;
134                while ((count = gzipIn.read(buffer)) > 0 ){
135                    bytesOut.write(buffer,0,count);
136                }
137                bytesOut.close();
138                answer = new ByteArray(bytesOut.getData(),0,bytesOut.size());
139            }
140            return answer;
141        }
142            
143    }