1 29 30 package com.caucho.quercus.lib.zlib; 31 32 import java.io.IOException ; 33 import java.io.OutputStream ; 34 import java.util.zip.CRC32 ; 35 import java.util.zip.Deflater ; 36 import java.util.zip.DeflaterOutputStream ; 37 38 44 public class GZIPOutputStream extends DeflaterOutputStream { 45 private CRC32 _crc32; 46 47 private byte[] _header = { 48 (byte) 0x1f, (byte) 0x8b, 8, 0, 0, 0, 0, 0, 0, 0 }; 55 56 private int _encodingMode; 57 private boolean _isGzip; 58 59 66 private GZIPOutputStream(OutputStream out, Deflater def) 67 throws IOException 68 { 69 super(out, def); 70 71 out.write(_header, 0, _header.length); 72 } 73 74 80 public GZIPOutputStream(OutputStream out, 81 int compressionLevel, 82 int strategy, 83 int encodingMode) 84 throws IOException 85 { 86 this(out, createDeflater(compressionLevel, strategy, encodingMode)); 87 88 _isGzip = (encodingMode == ZlibModule.FORCE_GZIP); 89 90 if (_isGzip) 91 _crc32 = new CRC32 (); 92 93 _encodingMode = encodingMode; 94 } 95 96 99 private static Deflater createDeflater(int compressionLevel, 100 int strategy, 101 int encodingMode) 102 { 103 Deflater defl; 104 105 if (encodingMode == ZlibModule.FORCE_GZIP) 106 defl = new Deflater (compressionLevel, true); 107 else 108 defl = new Deflater (compressionLevel, false); 109 110 defl.setStrategy(strategy); 111 112 return defl; 113 } 114 115 120 public GZIPOutputStream(OutputStream out, int compressionLevel, int strategy) 121 throws IOException 122 { 123 this(out, compressionLevel, strategy, ZlibModule.FORCE_GZIP); 124 } 125 126 129 public GZIPOutputStream(OutputStream out) 130 throws IOException 131 { 132 this(out, Deflater.DEFAULT_COMPRESSION, Deflater.DEFAULT_STRATEGY); 133 } 134 135 140 public void write(int v) 141 throws IOException 142 { 143 super.write(v); 144 145 if (_isGzip) 146 _crc32.update(v); 147 } 148 149 154 public void write(byte[] buffer, int offset, int length) 155 throws IOException 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 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 198 public void close() 199 throws IOException 200 { 201 if (! def.finished()) 202 finish(); 203 204 super.close(); 205 } 206 } 207 | Popular Tags |