KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > zlib > GZIPOutputStream


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Nam Nguyen
28  */

29
30 package com.caucho.quercus.lib.zlib;
31
32 import java.io.IOException JavaDoc;
33 import java.io.OutputStream JavaDoc;
34 import java.util.zip.CRC32 JavaDoc;
35 import java.util.zip.Deflater JavaDoc;
36 import java.util.zip.DeflaterOutputStream JavaDoc;
37
38 /**
39  * As opposed to java's GZIPOutputStream, this class allows for more control on
40  * what is written to the underlying OutputStream.
41  *
42  * @see java.util.zip.GZIPOutputStream
43  */

44 public class GZIPOutputStream extends DeflaterOutputStream JavaDoc {
45   private CRC32 JavaDoc _crc32;
46
47   private byte[] _header = {
48     (byte) 0x1f, (byte) 0x8b, // gzip file identifier (ID1, ID2)
49
8, // Deflate compression method (CM)
50
0, // optional flags (FLG)
51
0, 0, 0, 0, // modification time (MTIME)
52
0, // extra optional flags (XFL)
53
0 // operating system (OS)
54
};
55
56   private int _encodingMode;
57   private boolean _isGzip;
58
59   /**
60    * Writes gzip header to OutputStream upon construction.
61    * XXX: set operating system (file architecure) header.
62    *
63    * @param out
64    * @param def
65    */

66   private GZIPOutputStream(OutputStream JavaDoc out, Deflater JavaDoc def)
67     throws IOException JavaDoc
68   {
69     super(out, def);
70     
71     out.write(_header, 0, _header.length);
72   }
73
74   /**
75    * @param out
76    * @param compressionLevel
77    * @param strategy Deflate compression strategy
78    * @param encodingMode FORCE_GZIP to write gzwrite compatible output; FORCE_DEFLATE to write gzip header and zlib header, but do not write crc32 trailer
79    */

80   public GZIPOutputStream(OutputStream JavaDoc out,
81               int compressionLevel,
82               int strategy,
83               int encodingMode)
84     throws IOException JavaDoc
85   {
86     this(out, createDeflater(compressionLevel, strategy, encodingMode));
87
88     _isGzip = (encodingMode == ZlibModule.FORCE_GZIP);
89
90     if (_isGzip)
91       _crc32 = new CRC32 JavaDoc();
92
93     _encodingMode = encodingMode;
94   }
95
96   /**
97    * Creates a deflater based on the Zlib arguments.
98    */

99   private static Deflater JavaDoc createDeflater(int compressionLevel,
100                      int strategy,
101                      int encodingMode)
102   {
103     Deflater JavaDoc defl;
104
105     if (encodingMode == ZlibModule.FORCE_GZIP)
106       defl = new Deflater JavaDoc(compressionLevel, true);
107     else
108       defl = new Deflater JavaDoc(compressionLevel, false);
109
110     defl.setStrategy(strategy);
111
112     return defl;
113   }
114
115   /**
116    * @param out
117    * @param compressionLevel
118    * @param strategy Deflate compression strategy
119    */

120   public GZIPOutputStream(OutputStream JavaDoc out, int compressionLevel, int strategy)
121     throws IOException JavaDoc
122   {
123     this(out, compressionLevel, strategy, ZlibModule.FORCE_GZIP);
124   }
125
126   /**
127    * @param out
128    */

129   public GZIPOutputStream(OutputStream JavaDoc out)
130     throws IOException JavaDoc
131   {
132     this(out, Deflater.DEFAULT_COMPRESSION, Deflater.DEFAULT_STRATEGY);
133   }
134
135   /**
136    * Writes a byte.
137    *
138    * @param input
139    */

140   public void write(int v)
141     throws IOException JavaDoc
142   {
143     super.write(v);
144
145     if (_isGzip)
146       _crc32.update(v);
147   }
148
149   /**
150    * @param input
151    * @param offset
152    * @param length
153    */

154   public void write(byte[] buffer, int offset, int length)
155     throws IOException JavaDoc
156   {
157     super.write(buffer, offset, length);
158     
159     if (_isGzip)
160       _crc32.update(buffer, offset, length);
161   }
162
163   public void finish()
164     throws IOException JavaDoc
165   {
166     super.finish();
167
168     if (_isGzip) {
169       long crcValue = _crc32.getValue();
170       
171       byte[] trailerCRC = new byte[4];
172       
173       trailerCRC[0] = (byte) crcValue;
174       trailerCRC[1] = (byte) (crcValue >> 8);
175       trailerCRC[2] = (byte) (crcValue >> 16);
176       trailerCRC[3] = (byte) (crcValue >> 24);
177       
178       out.write(trailerCRC, 0, trailerCRC.length);
179     }
180
181     long inputSize = def.getBytesRead();
182     
183     byte[] trailerInputSize = new byte[4];
184
185     trailerInputSize[0] = (byte) inputSize;
186     trailerInputSize[1] = (byte) (inputSize >> 8);
187     trailerInputSize[2] = (byte) (inputSize >> 16);
188     trailerInputSize[3] = (byte) (inputSize >> 24);
189     
190     out.write(trailerInputSize, 0, trailerInputSize.length);
191
192     out.flush();
193   }
194
195   /**
196    * Calls super function, which in turn closes the underlying 'in' stream
197    */

198   public void close()
199     throws IOException JavaDoc
200   {
201     if (! def.finished())
202       finish();
203     
204     super.close();
205   }
206 }
207
Popular Tags