From f2b71c9df25266b294d2a477b8bda4fd1871ec27 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 14 Sep 2016 18:10:09 -0700 Subject: [PATCH] [FileTools] Get more TZIP stuff there --- .../Objects/ZipArchiveEntryExtension.cs | 18 ++ SabreTools.Helper/SabreTools.Helper.csproj | 1 + SabreTools.Helper/Tools/FileTools.cs | 154 +++++++----------- 3 files changed, 79 insertions(+), 94 deletions(-) create mode 100644 SabreTools.Helper/Objects/ZipArchiveEntryExtension.cs diff --git a/SabreTools.Helper/Objects/ZipArchiveEntryExtension.cs b/SabreTools.Helper/Objects/ZipArchiveEntryExtension.cs new file mode 100644 index 00000000..94096c9a --- /dev/null +++ b/SabreTools.Helper/Objects/ZipArchiveEntryExtension.cs @@ -0,0 +1,18 @@ +using SabreTools.Helper; + +namespace System.IO.Compression +{ + public class ZipArchiveEntry + { + public ArchiveVersion VersionMadeBy; + public ArchiveVersion VersionNeeded; + public GeneralPurposeBitFlag GeneralPurposeBitFlag; + public CompressionMethod CompressionMethod; + public uint CRC; + public byte[] ExtraField; + public byte[] Comment; + public InternalFileAttributes InternalFileAttributes; + public int ExternalFileAttributes; + public int RelativeOffset; + } +} diff --git a/SabreTools.Helper/SabreTools.Helper.csproj b/SabreTools.Helper/SabreTools.Helper.csproj index a597a267..0c9c2b42 100644 --- a/SabreTools.Helper/SabreTools.Helper.csproj +++ b/SabreTools.Helper/SabreTools.Helper.csproj @@ -94,6 +94,7 @@ + True True diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs index 28b2a1bc..9dd04667 100644 --- a/SabreTools.Helper/Tools/FileTools.cs +++ b/SabreTools.Helper/Tools/FileTools.cs @@ -183,12 +183,11 @@ namespace SabreTools.Helper /// /// Write an existing zip archive construct to a torrent zip file /// - /// ZipArchiveStruct representing the zipfile + /// ZipArchiveStruct representing the zipfile with compressed data /// Name of the file to write out to /// Logger object for file and console output /// /// Things that need to be done: - /// Compress data instead of just writing it /// Get rid of redundant directories (ones that are implied by files inside them) /// public static void WriteTorrentZip(ZipArchiveStruct zae, string output, Logger logger) @@ -534,93 +533,72 @@ namespace SabreTools.Helper } ZipArchiveStruct zas = GetZipFileInfo(inputArchive, logger); - Console.WriteLine("Archive Filename: " + zas.FileName); - Console.WriteLine("Archive Comment: " + zas.Comment.Length + " " + zas.Comment); - Console.WriteLine("Archive Central Directory CRC: " + zas.CentralDirectoryCRC.ToString("X8")); - Console.WriteLine(); - Console.WriteLine("Entries:"); - foreach (ZipArchiveEntryStruct zaes in zas.Entries) + + for (int i = 0; i < zas.Entries.Count; i++) { - Console.WriteLine("Entry Filename: " + zaes.FileName.Length + " " + Style.ConvertHex(BitConverter.ToString(zaes.FileName))); - Console.WriteLine("Entry Comment: " + zaes.Comment.Length + " " + Style.ConvertHex(BitConverter.ToString(zaes.Comment))); - Console.WriteLine("Entry Compressed Size: " + zaes.CompressedSize); - Console.WriteLine("Entry Compression Method: " + zaes.CompressionMethod); - Console.WriteLine("Entry CRC: " + zaes.CRC.ToString("X8")); - Console.WriteLine("Entry External File Attributes: " + zaes.ExternalFileAttributes); - Console.WriteLine("Entry Extra Field: " + zaes.ExtraField.Length + " " + Style.ConvertHex(BitConverter.ToString(zaes.ExtraField))); - Console.WriteLine("Entry General Purpose Flag: " + zaes.GeneralPurposeBitFlag); - Console.WriteLine("Entry Internal File Attributes: " + zaes.InternalFileAttributes); - Console.WriteLine("Entry Last Modification File Date: " + zaes.LastModFileDate); - Console.WriteLine("Entry Last Modification File Time: " + zaes.LastModFileTime); - Console.WriteLine("Entry Relative Offset: " + zaes.RelativeOffset); - Console.WriteLine("Entry Uncompressed Size: " + zaes.UncompressedSize); - Console.WriteLine("Entry Version Made By: " + zaes.VersionMadeBy); - Console.WriteLine("Entry Version Needed: " + zaes.VersionNeeded); - Console.WriteLine(); + zas.Entries[i] = PopulateEntry(zas.Entries[i], inputArchive); + zas.Entries[i] = DecompressEntry(zas.Entries[i], inputArchive); + zas.Entries[i] = CompressEntry(zas.Entries[i]); } + WriteTorrentZip(zas, inputArchive + ".new", logger); Console.ReadLine(); - /* - ZipArchive outarchive = null; - try - { - // If the archive doesn't exist, create it - if (!File.Exists(inputArchive)) - { - outarchive = ZipFile.Open(inputArchive, ZipArchiveMode.Create); - outarchive.Dispose(); - } - - // Open the archive for sorting - Dictionary entries = new Dictionary(); - using (outarchive = ZipFile.Open(inputArchive, ZipArchiveMode.Update)) - { - // Get and sort the entries - foreach (ZipArchiveEntry entry in outarchive.Entries) - { - entries.Add(entry.Name.ToLowerInvariant(), entry.Name); - } - } - - // Now write out the entries by name - List keys = entries.Keys.ToList(); - keys.Sort(Style.CompareNumeric); - - foreach (string key in keys) - { - Rom temp = new Rom - { - Machine = new Machine - { - Name = Path.GetFileNameWithoutExtension(inputArchive) + ".new", - }, - Name = entries[key], - Date = "12/24/1996 11:32 PM", - }; - CopyFileBetweenArchives(inputArchive, Path.GetDirectoryName(inputArchive), entries[key], temp, logger); - } - - string newfile = Path.Combine(Path.GetDirectoryName(inputArchive), Path.GetFileNameWithoutExtension(inputArchive) + ".new.zip"); - File.Delete(inputArchive); - File.Move(newfile, inputArchive); - - success = true; - } - catch (Exception ex) - { - Console.WriteLine(ex); - success = false; - } - finally - { - outarchive?.Dispose(); - } - */ - return success; } + /// + /// Convert uncompressed data in entry to compressed data + /// + /// Does not seem to create TZIP compatible streams + private static ZipArchiveEntryStruct CompressEntry(ZipArchiveEntryStruct zaes) + { + byte[] uncompressedData = zaes.Data; + using (MemoryStream cms = new MemoryStream()) + using (MemoryStream ums = new MemoryStream(uncompressedData)) + using (DeflateStream ds = new DeflateStream(cms, CompressionMode.Compress)) + { + ums.CopyTo(ds); + ds.Flush(); + zaes.Data = cms.ToArray(); + } + return zaes; + } + + /// + /// Populate an archive entry struct with uncompressed data from an input zip archive + /// + private static ZipArchiveEntryStruct DecompressEntry(ZipArchiveEntryStruct zaes, string input) + { + using (BinaryReader br = new BinaryReader(File.OpenRead(input))) + { + br.BaseStream.Seek(zaes.RelativeOffset + 30 + zaes.FileName.Length, SeekOrigin.Begin); + byte[] compressedData = br.ReadBytes((int)zaes.CompressedSize); + using (MemoryStream ums = new MemoryStream()) + using (MemoryStream cms = new MemoryStream(compressedData)) + using (DeflateStream ds = new DeflateStream(cms, CompressionMode.Decompress)) + { + ds.CopyTo(ums); + ums.Flush(); + zaes.Data = ums.ToArray(); + } + } + return zaes; + } + + /// + /// Populate an archive entry struct with data from an input zip archive + /// + private static ZipArchiveEntryStruct PopulateEntry(ZipArchiveEntryStruct zaes, string input) + { + using (BinaryReader br = new BinaryReader(File.OpenRead(input))) + { + br.BaseStream.Seek(zaes.RelativeOffset + 30 + zaes.FileName.Length, SeekOrigin.Begin); + zaes.Data = br.ReadBytes((int)zaes.CompressedSize); + } + return zaes; + } + #endregion #region File Information @@ -999,7 +977,7 @@ namespace SabreTools.Helper } /// - /// Read the information from an input zip file + /// Read the information from an input zip file and does not populate data /// /// Name of the input file to check /// Logger object for file and console output @@ -1097,18 +1075,6 @@ namespace SabreTools.Helper } } - // Next, use the entries, if any, to get the uncompressed data - using (BinaryReader br = new BinaryReader(File.OpenRead(input))) - { - for (int i = 0; i < zas.Entries.Count; i++) - { - ZipArchiveEntryStruct zaes = zas.Entries[i]; - br.BaseStream.Seek(zaes.RelativeOffset + 30 + zaes.FileName.Length, SeekOrigin.Begin); - zaes.Data = br.ReadBytes((int)zaes.CompressedSize); - zas.Entries[i] = zaes; - } - } - // Finally, get a hash of the entire central directory (between SOCD and EOCD) if (zas.SOCDOffset > 0 && zas.EOCDOffset > 0) {