KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > zip > ZipDirectory


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  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Charles Reich
27  */

28
29 package com.caucho.quercus.lib.zip;
30
31 import com.caucho.quercus.lib.file.BinaryInput;
32 import com.caucho.quercus.lib.file.ReadStreamInput;
33 import com.caucho.vfs.*;
34
35 import java.io.IOException JavaDoc;
36 import java.io.InputStream JavaDoc;
37 import java.util.zip.ZipEntry JavaDoc;
38
39 /**
40  * Reads the zip header and prepares zip entries.
41  */

42 public class ZipDirectory
43 {
44   private BinaryInput _oldIn;
45   private ReadStreamInput _in;
46   private byte[] _tmpBuf;
47   private ZipEntry JavaDoc _currentEntry;
48
49   private boolean _eof;
50   private boolean _ddescriptor;
51
52   public ZipDirectory(BinaryInput in)
53   {
54     _oldIn = in;
55     
56     VfsStream s = new VfsStream(in.getInputStream(), null);
57     _in = new ReadStreamInput(new ReadStream(s));
58     _tmpBuf = new byte[32];
59     _eof = false;
60   }
61
62   /**
63    * Closes the previous entry and returns the next entry's metadata.
64    */

65   public QuercusZipEntry zip_read()
66     throws IOException JavaDoc
67   {
68     closeEntry();
69
70     long position = _in.getPosition();
71     ZipEntry JavaDoc entry = readEntry();
72
73     // If not using ZipInputStream to decompress,
74
// then get entry's position AFTER readEntry() to skip over zip header
75
//long position = _in.getPosition();
76

77     if (entry == null)
78       return null;
79     else
80       return new QuercusZipEntry(position, entry);
81   }
82
83   /**
84    * Reads the next entry's metadata from the current stream position.
85    */

86   protected ZipEntry JavaDoc readEntry()
87     throws IOException JavaDoc
88   {
89     if (_eof || _currentEntry != null)
90       return null;
91
92     int sublen = _in.read(_tmpBuf, 0, 30);
93     if (sublen < 30) {
94       _eof = true;
95       return null;
96     }
97
98     // Zip file signature check
99
if ((((_tmpBuf[3] & 0xff) << 24) | ((_tmpBuf[2] & 0xff) << 16) |
100           ((_tmpBuf[1] & 0xff) << 8) | (_tmpBuf[0] & 0xff)) != 0x04034b50) {
101       _eof = true;
102       return null;
103     }
104
105     // Extra data descriptors after the compressed data
106
if ((_tmpBuf[6] & 0x04) == 0x04)
107       _ddescriptor = true;
108     else
109       _ddescriptor = false;
110
111     int compressionMethod = (_tmpBuf[8] & 0xff) | ((_tmpBuf[9] & 0xff) << 8);
112
113     //if (compressionMethod != 0 && compressionMethod != 8)
114
// throw new IOException("Unsupported zip compression method (" + compressionMethod + ").");
115

116     long crc32 = _tmpBuf[14] & 0xff;
117     crc32 |= (_tmpBuf[15] & 0xff) << 8;
118     crc32 |= (_tmpBuf[16] & 0xff) << 16;
119     crc32 |= ((long)_tmpBuf[17] & 0xff) << 24;
120
121     long compressedSize = _tmpBuf[18] & 0xff;
122     compressedSize |= (_tmpBuf[19] & 0xff) << 8;
123     compressedSize |= (_tmpBuf[20] & 0xff) << 16;
124     compressedSize |= ((long)_tmpBuf[21] & 0xff) << 24;
125
126     long uncompressedSize = _tmpBuf[22] & 0xff;
127     uncompressedSize |= (_tmpBuf[23] & 0xff) << 8;
128     uncompressedSize |= (_tmpBuf[24] & 0xff) << 16;
129     uncompressedSize |= ((long)_tmpBuf[25] & 0xff) << 24;
130
131     int filenameLength = _tmpBuf[26] & 0xff;
132     filenameLength |= (_tmpBuf[27] & 0xff) << 8;
133
134     int extraLength = _tmpBuf[28] & 0xff;
135     extraLength |= (_tmpBuf[29] & 0xff) << 8;
136
137     // XXX: correct char encoding?
138
String JavaDoc name;
139     if (filenameLength <= _tmpBuf.length) {
140       sublen = _in.read(_tmpBuf, 0, filenameLength);
141       if (sublen < filenameLength)
142         return null;
143       name = new String JavaDoc(_tmpBuf, 0, sublen);
144     }
145     else {
146       byte[] buffer = new byte[filenameLength];
147       sublen = _in.read(buffer, 0, buffer.length);
148       if (sublen < filenameLength)
149         return null;
150       name = new String JavaDoc(buffer, 0, sublen);
151     }
152
153     if (extraLength > 0)
154       _in.skip(extraLength);
155
156     ZipEntry JavaDoc entry = new ZipEntry JavaDoc(name);
157     entry.setMethod(compressionMethod);
158     entry.setCrc(crc32);
159     entry.setCompressedSize(compressedSize);
160     entry.setSize(uncompressedSize);
161
162     _currentEntry = entry;
163     return entry;
164   }
165
166   /**
167    * Positions stream to beginning of next entry
168    */

169   protected void closeEntry()
170     throws IOException JavaDoc
171   {
172     if (_currentEntry == null)
173       return;
174
175     long length = _currentEntry.getCompressedSize();
176
177     if (_ddescriptor)
178       length += 12;
179
180     _in.skip(length);
181     _currentEntry = null;
182   }
183
184   /**
185    * Opens a decompressed stream positioned at this entry's position.
186    */

187   protected InputStream JavaDoc openInputStream(QuercusZipEntry entry)
188     throws IOException JavaDoc
189   {
190     return new ZipEntryInputStream(_in.openCopy(), entry);
191   }
192
193   public boolean zip_close()
194   {
195     _in.close();
196     _oldIn.close();
197
198     return true;
199   }
200
201   public String JavaDoc toString()
202   {
203     return "ZipDirectory[]";
204   }
205 }
206
Popular Tags