imported from svn
[metux-java.git] / util / GZip.java
blobbdb392d73a183b4ccf8f2feec2cd082ebcd343ec
1 /*
2 * Copyright (c) 2000-2005 CyberFOX Software, Inc. All Rights Reserved.
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
12 * details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; if not, write to the
16 * Free Software Foundation, Inc.
17 * 59 Temple Place
18 * Suite 330
19 * Boston, MA 02111-1307
20 * USA
23 package org.de.metux.util;
25 import java.io.*;
26 import java.util.zip.*;
28 public class GZip
30 private static byte[] _byteHold = new byte[1];
31 private static final Boolean _sync = Boolean.TRUE;
32 private static final byte[] gzipHdrData = { 0x1f, -117, 0x08, 0x00,
33 0x00, 0x00, 0x00, 0x00,
34 0x02, -1 };
35 byte[] _gzTest = new byte[2];
36 byte[] _data;
37 int _uclength;
38 int _uccrc32;
39 boolean nowrap = true;
40 CRC32 _crc32Calculator = new CRC32();
41 static int incrementme;
43 public byte[] getCompressedData() { return _data; }
45 public StringBuffer getUncompressedData()
46 throws FileNotFoundException, DataFormatException, IOException
48 return uncompress(_data, nowrap);
51 public StringBuffer getUncompressedData(boolean xt_nowrap)
52 throws DataFormatException, FileNotFoundException, IOException
54 return uncompress(_data, xt_nowrap);
57 public long getLength() { return _uclength; }
58 public long getCRC() { return _uccrc32; }
59 public void reset() { _data = null; _uclength = 0; _uccrc32 = 0; _crc32Calculator.reset(); }
61 public void setData(byte[] newData, int len, int crc)
63 _data = newData;
64 _uclength = len;
65 _uccrc32 = crc;
68 public void setData(byte[] newData)
70 _crc32Calculator.reset();
71 _crc32Calculator.update(newData);
72 _uccrc32 = (int) _crc32Calculator.getValue();
73 _uclength = newData.length;
74 _data = compress(newData);
77 public int readInt(FileInputStream fis) throws IOException
79 int a, b, c, d;
81 a = fis.read();
82 b = fis.read();
83 c = fis.read();
84 d = fis.read();
86 return(a + b << 8 + c << 16 + d << 24);
89 public void load(File fp) throws IOException
91 FileInputStream fis = new FileInputStream(fp);
93 fis.read(_gzTest);
94 // If it's a 'real' GZipped file...
95 if(_gzTest[0] == 0x1f && _gzTest[1] == -117)
97 if(fis.skip(8)==8)
99 _data = new byte[(int)fp.length() - 18 + 16];
100 fis.read(_data, 0, (int)fp.length() - 18);
102 _uccrc32 = readInt(fis);
103 _uclength= readInt(fis);
104 nowrap = true;
107 else
109 _data = new byte[(int)fp.length()];
110 System.arraycopy(_gzTest, 0, _data, 0, 2);
111 nowrap = false;
112 fis.read(_data, 2, _data.length-2);
114 fis.close();
117 private byte[] compress(byte[] inBytes)
119 Deflater df = new Deflater(9);
120 byte[] newData = null;
121 int deflatedBytes = 0;
123 // We can't compress null.
124 if(inBytes == null) return null;
126 synchronized(_sync)
128 if(_byteHold == null || _byteHold.length < inBytes.length) {
129 _byteHold = new byte[inBytes.length * 2];
132 df.setInput(inBytes);
133 df.finish();
134 deflatedBytes = df.deflate(_byteHold);
136 deflatedBytes -= 4;
138 newData = new byte[deflatedBytes];
139 System.arraycopy(_byteHold, 0, newData, 0, deflatedBytes);
141 return newData;
144 public static StringBuffer uncompress(byte[] curPage, boolean nowrap)
145 throws DataFormatException, FileNotFoundException, IOException
147 Inflater infl = new Inflater(nowrap);
148 byte[] outdata = null;
149 StringBuffer sb = null;
150 int accumOutputBytes=0, inflatedBytes=0;
151 int prevLength;
153 // We can't uncompress null.
154 if(curPage == null) return null;
156 synchronized(_sync) {
157 prevLength = _byteHold.length;
159 if(prevLength < curPage.length) {
160 _byteHold = new byte[curPage.length];
162 infl.setInput(curPage);
163 // try {
164 inflatedBytes = infl.inflate(_byteHold);
165 accumOutputBytes = inflatedBytes;
166 while(!infl.finished() && inflatedBytes != 0) {
167 outdata = _byteHold;
168 prevLength = _byteHold.length;
169 if(accumOutputBytes >= (prevLength - 2048)) {
170 // try {
171 inflatedBytes = 0;
172 _byteHold = new byte[_byteHold.length * 3];
173 System.arraycopy(outdata, 0, _byteHold, 0, accumOutputBytes);
174 inflatedBytes = infl.inflate(_byteHold, accumOutputBytes, prevLength * 2);
175 // } catch(OutOfMemoryError oome) {
176 // ErrorManagement.handleException("FAILING to allocate more bytes @ " + _byteHold.length * 3, oome);
177 // }
178 } else {
179 inflatedBytes = infl.inflate(_byteHold, accumOutputBytes, prevLength - accumOutputBytes);
181 accumOutputBytes += inflatedBytes;
183 return new StringBuffer(new String(_byteHold, 0, accumOutputBytes));
184 // } catch(DataFormatException dfe) {
185 // ErrorManagement.handleException("Failed to uncompress data: " + dfe, dfe);
186 // return null;
187 // }
191 /**
192 * Write out the given int in LSB->MSB format.
194 * @param fos - Output stream to write to.
195 * @param outie - Int value to write out in LSB->MSB format.
197 private void writeInt(FileOutputStream fos, int outie) throws IOException
199 byte a = (byte) ((outie & 0xff000000) >> 24);
200 byte b = (byte) ((outie & 0x00ff0000) >> 16);
201 byte c = (byte) ((outie & 0x0000ff00) >> 8);
202 byte d = (byte) (outie & 0x000000ff);
204 fos.write(d);
205 fos.write(c);
206 fos.write(b);
207 fos.write(a);
210 public void save(String fileName)
211 throws FileNotFoundException, IOException
213 File fp = new File(fileName);
215 if (fp.exists())
217 File oldFP = new File(fileName + "~");
218 if(oldFP.exists())
219 oldFP.delete();
221 fp.renameTo(oldFP);
224 // try {
225 FileOutputStream fos = new FileOutputStream(fp);
226 // Write 0x1f,0x8b,0x8,0x0,0x00000000,2,255,{Data},crc32,{datalen}
227 fos.write(gzipHdrData, 0, gzipHdrData.length);
228 fos.write(_data, 2, _data.length-2);
229 writeInt(fos, _uccrc32);
230 writeInt(fos, _uclength);
231 fos.close();
232 // } catch(IOException ioe) {
233 // We dont throw the exception back up the chain, and let
234 // something with UI put up a display box because this can
235 // happen during unattended operation.
237 // In fact, this can occur because the user deleted the
238 // directory, and many other reasons, so we do NOT report the
239 // error anymore, unless debugging. This caused one user
240 // to have >28 megs of error logs. Stop that!
241 // if(JConfig.debugging) {
242 // ErrorManagement.handleException("Error writing " + fileName, ioe);
243 // }
244 // }