1 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 ; 36 import java.io.InputStream ; 37 import java.util.zip.ZipEntry ; 38 39 42 public class ZipDirectory 43 { 44 private BinaryInput _oldIn; 45 private ReadStreamInput _in; 46 private byte[] _tmpBuf; 47 private ZipEntry _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 65 public QuercusZipEntry zip_read() 66 throws IOException 67 { 68 closeEntry(); 69 70 long position = _in.getPosition(); 71 ZipEntry entry = readEntry(); 72 73 77 if (entry == null) 78 return null; 79 else 80 return new QuercusZipEntry(position, entry); 81 } 82 83 86 protected ZipEntry readEntry() 87 throws IOException 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 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 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 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 String name; 139 if (filenameLength <= _tmpBuf.length) { 140 sublen = _in.read(_tmpBuf, 0, filenameLength); 141 if (sublen < filenameLength) 142 return null; 143 name = new String (_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 (buffer, 0, sublen); 151 } 152 153 if (extraLength > 0) 154 _in.skip(extraLength); 155 156 ZipEntry entry = new ZipEntry (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 169 protected void closeEntry() 170 throws IOException 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 187 protected InputStream openInputStream(QuercusZipEntry entry) 188 throws IOException 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 toString() 202 { 203 return "ZipDirectory[]"; 204 } 205 } 206 | Popular Tags |