internal ZipDirEntry(ZipEntry ze) { }
internal static ZipEntry Create(String filename) { ZipEntry entry = new ZipEntry(); entry._FileName = filename; entry._LastModified = System.IO.File.GetLastWriteTime(filename); // adjust the time if the .NET BCL thinks it is in DST. // see the note elsewhere in this file for more info. if (entry._LastModified.IsDaylightSavingTime()) { System.DateTime AdjustedTime = entry._LastModified - new System.TimeSpan(1, 0, 0); entry._LastModDateTime = GodLesZ.Library.Xna.WindowLibrary.External.Zip.Shared.DateTimeToPacked(AdjustedTime); } else entry._LastModDateTime = GodLesZ.Library.Xna.WindowLibrary.External.Zip.Shared.DateTimeToPacked(entry._LastModified); // we don't actually slurp in the file until the caller invokes Write on this entry. return entry; }
private static bool ReadHeader(System.IO.Stream s, ZipEntry ze) { int signature = GodLesZ.Library.Xna.WindowLibrary.External.Zip.Shared.ReadSignature(s); // return null if this is not a local file header signature if (SignatureIsNotValid(signature)) { s.Seek(-4, System.IO.SeekOrigin.Current); if (ze._Debug) System.Console.WriteLine(" ZipEntry::Read(): Bad signature ({0:X8}) at position {1}", signature, s.Position); return false; } byte[] block = new byte[26]; int n = s.Read(block, 0, block.Length); if (n != block.Length) return false; int i = 0; ze._VersionNeeded = (short)(block[i++] + block[i++] * 256); ze._BitField = (short)(block[i++] + block[i++] * 256); ze._CompressionMethod = (short)(block[i++] + block[i++] * 256); ze._LastModDateTime = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; // the PKZIP spec says that if bit 3 is set (0x0008), then the CRC, Compressed size, and uncompressed size // come directly after the file data. The only way to find it is to scan the zip archive for the signature of // the Data Descriptor, and presume that that signature does not appear in the (compressed) data of the compressed file. if ((ze._BitField & 0x0008) != 0x0008) { ze._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze._CompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze._UncompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; } else { // the CRC, compressed size, and uncompressed size are stored later in the stream. // here, we advance the pointer. i += 12; } Int16 filenameLength = (short)(block[i++] + block[i++] * 256); Int16 extraFieldLength = (short)(block[i++] + block[i++] * 256); block = new byte[filenameLength]; n = s.Read(block, 0, block.Length); ze._FileName = GodLesZ.Library.Xna.WindowLibrary.External.Zip.Shared.StringFromBuffer(block, 0, block.Length); ze._Extra = new byte[extraFieldLength]; n = s.Read(ze._Extra, 0, ze._Extra.Length); // transform the time data into something usable ze._LastModified = GodLesZ.Library.Xna.WindowLibrary.External.Zip.Shared.PackedToDateTime(ze._LastModDateTime); // actually get the compressed size and CRC if necessary if ((ze._BitField & 0x0008) == 0x0008) { long posn = s.Position; long SizeOfDataRead = GodLesZ.Library.Xna.WindowLibrary.External.Zip.Shared.FindSignature(s, ZipEntryDataDescriptorSignature); if (SizeOfDataRead == -1) return false; // read 3x 4-byte fields (CRC, Compressed Size, Uncompressed Size) block = new byte[12]; n = s.Read(block, 0, block.Length); if (n != 12) return false; i = 0; ze._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze._CompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze._UncompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; if (SizeOfDataRead != ze._CompressedSize) throw new Exception("Data format error (bit 3 is set)"); // seek back to previous position, to read file data s.Seek(posn, System.IO.SeekOrigin.Begin); } return true; }
internal static ZipEntry Read(System.IO.Stream s, bool TurnOnDebug) { ZipEntry entry = new ZipEntry(); entry._Debug = TurnOnDebug; if (!ReadHeader(s, entry)) return null; entry.__filedata = new byte[entry.CompressedSize]; int n = s.Read(entry._FileData, 0, entry._FileData.Length); if (n != entry._FileData.Length) { throw new Exception("badly formatted zip file."); } // finally, seek past the (already read) Data descriptor if necessary if ((entry._BitField & 0x0008) == 0x0008) { s.Seek(16, System.IO.SeekOrigin.Current); } return entry; }