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
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.
19 * Boston, MA 02111-1307
23 package org
.de
.metux
.util
;
26 import java
.util
.zip
.*;
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,
35 byte[] _gzTest
= new byte[2];
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
)
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
86 return(a
+ b
<< 8 + c
<< 16 + d
<< 24);
89 public void load(File fp
) throws IOException
91 FileInputStream fis
= new FileInputStream(fp
);
94 // If it's a 'real' GZipped file...
95 if(_gzTest
[0] == 0x1f && _gzTest
[1] == -117)
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
);
109 _data
= new byte[(int)fp
.length()];
110 System
.arraycopy(_gzTest
, 0, _data
, 0, 2);
112 fis
.read(_data
, 2, _data
.length
-2);
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;
128 if(_byteHold
== null || _byteHold
.length
< inBytes
.length
) {
129 _byteHold
= new byte[inBytes
.length
* 2];
132 df
.setInput(inBytes
);
134 deflatedBytes
= df
.deflate(_byteHold
);
138 newData
= new byte[deflatedBytes
];
139 System
.arraycopy(_byteHold
, 0, newData
, 0, deflatedBytes
);
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;
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
);
164 inflatedBytes
= infl
.inflate(_byteHold
);
165 accumOutputBytes
= inflatedBytes
;
166 while(!infl
.finished() && inflatedBytes
!= 0) {
168 prevLength
= _byteHold
.length
;
169 if(accumOutputBytes
>= (prevLength
- 2048)) {
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);
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);
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);
210 public void save(String fileName
)
211 throws FileNotFoundException
, IOException
213 File fp
= new File(fileName
);
217 File oldFP
= new File(fileName
+ "~");
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
);
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);