/* * end of central dir signature 4 bytes (0x06054b50) * number of this disk 2 bytes * number of the disk with the start of the central directory 2 bytes * total number of entries in the central directory on this disk 2 bytes * total number of entries in the central directory 2 bytes * size of the central directory 4 bytes * offset of start of central directory * with respect to the starting disk number 4 bytes * .ZIP file comment length 2 bytes * .ZIP file comment (variable size) */ /// <summary> /// TODO: case when the whole file is smaller than 64K /// TODO: handle non HTTP case /// </summary> /// <param name="url"></param> /// <returns></returns> public bool Load() { int CentralOffset, CentralSize; int TotalEntries; if (!FindCentralDirectory(out CentralOffset, out CentralSize, out TotalEntries)) { return(false); } MaxFileOffset = CentralOffset; // now retrieve the Central Directory entries = new ZipEntry[TotalEntries]; //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); //req.AddRange(CentralOffset, CentralOffset+CentralSize); //HttpWebResponse res = (HttpWebResponse)req.GetResponse(); using (Stream s = protocolProvider.CreateStream(this.url, CentralOffset, CentralOffset + CentralSize)) { // code taken from SharpZipLib with modification for not seekable stream // and adjustement for Central Directory entry for (int i = 0; i < TotalEntries; i++) { if (ReadLeInt(s) != ZipConstants.CentralHeaderSignature) { throw new ZipException("Wrong Central Directory signature"); } // skip 6 bytes: version made (W), version ext (W), flags (W) ReadLeInt(s); ReadLeShort(s); int method = ReadLeShort(s); int dostime = ReadLeInt(s); int crc = ReadLeInt(s); int csize = ReadLeInt(s); int size = ReadLeInt(s); int nameLen = ReadLeShort(s); int extraLen = ReadLeShort(s); int commentLen = ReadLeShort(s); // skip 8 bytes: disk number start, internal file attribs, external file attribs (DW) ReadLeInt(s); ReadLeInt(s); int offset = ReadLeInt(s); byte[] buffer = new byte[Math.Max(nameLen, commentLen)]; StreamHelper.ReadAll(buffer, 0, nameLen, s); string name = ZipConstants.ConvertToString(buffer); ZipEntry entry = new ZipEntry(name); entry.CompressionMethod = (CompressionMethod)method; entry.Crc = crc & 0xffffffffL; entry.Size = size & 0xffffffffL; entry.CompressedSize = csize & 0xffffffffL; entry.DosTime = (uint)dostime; if (extraLen > 0) { byte[] extra = new byte[extraLen]; StreamHelper.ReadAll(extra, 0, extraLen, s); entry.ExtraData = extra; } if (commentLen > 0) { StreamHelper.ReadAll(buffer, 0, commentLen, s); entry.Comment = ZipConstants.ConvertToString(buffer); } entry.ZipFileIndex = i; entry.Offset = offset; entries[i] = entry; OnProgress((i * 100) / TotalEntries); } } OnProgress(100); return(true); }