diff --git a/SabreTools.Helper/Objects/ZipFIle.cs b/SabreTools.Helper/Objects/ZipFIle.cs index 688181e3..654cf5f0 100644 --- a/SabreTools.Helper/Objects/ZipFIle.cs +++ b/SabreTools.Helper/Objects/ZipFIle.cs @@ -574,7 +574,7 @@ namespace SabreTools.Helper { continue; } - if (TorrentZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) = 0) + if (TorrentZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) == 0) { continue; } @@ -899,5 +899,104 @@ namespace SabreTools.Helper zfe.Check(); } } + + /// + /// Get the text associated with a return status + /// + /// ZipReturn status to parse + /// String associated with the ZipReturn + public static string ZipErrorMessageText(ZipReturn zr) + { + string ret = "Unknown"; + switch (zr) + { + case ZipReturn.ZipGood: + ret = ""; + break; + case ZipReturn.ZipFileCountError: + ret = "The number of file in the Zip does not mach the number of files in the Zips Centeral Directory"; + break; + case ZipReturn.ZipSignatureError: + ret = "An unknown Signature Block was found in the Zip"; + break; + case ZipReturn.ZipExtraDataOnEndOfZip: + ret = "Extra Data was found on the end of the Zip"; + break; + case ZipReturn.ZipUnsupportedCompression: + ret = "An unsupported Compression method was found in the Zip, if you recompress this zip it will be usable"; + break; + case ZipReturn.ZipLocalFileHeaderError: + ret = "Error reading a zipped file header information"; + break; + case ZipReturn.ZipCentralDirError: + ret = "There is an error in the Zip Centeral Directory"; + break; + case ZipReturn.ZipReadingFromOutputFile: + ret = "Trying to write to a Zip file open for output only"; + break; + case ZipReturn.ZipWritingToInputFile: + ret = "Tring to read from a Zip file open for input only"; + break; + case ZipReturn.ZipErrorGettingDataStream: + ret = "Error creating Data Stream"; + break; + case ZipReturn.ZipCRCDecodeError: + ret = "CRC error"; + break; + case ZipReturn.ZipDecodeError: + ret = "Error unzipping a file"; + break; + } + + return ret; + } + + /// + /// Compare two strings in TorrentZip format + /// + /// + /// + /// + private static int TorrentZipStringCompare(string string1, string string2) + { + char[] bytes1 = string1.ToCharArray(); + char[] bytes2 = string2.ToCharArray(); + + int pos1 = 0; + int pos2 = 0; + + for (;;) + { + if (pos1 == bytes1.Length) + { + return ((pos2 == bytes2.Length) ? 0 : -1); + } + if (pos2 == bytes2.Length) + { + return 1; + } + + int byte1 = bytes1[pos1++]; + int byte2 = bytes2[pos2++]; + + if (byte1 >= 65 && byte1 <= 90) + { + byte1 += 0x20; + } + if (byte2 >= 65 && byte2 <= 90) + { + byte2 += 0x20; + } + + if (byte1 < byte2) + { + return -1; + } + if (byte1 > byte2) + { + return 1; + } + } + } } } diff --git a/SabreTools.Helper/Objects/ZipFileEntry.cs b/SabreTools.Helper/Objects/ZipFileEntry.cs index 7f638900..d9f54ffb 100644 --- a/SabreTools.Helper/Objects/ZipFileEntry.cs +++ b/SabreTools.Helper/Objects/ZipFileEntry.cs @@ -1018,104 +1018,5 @@ namespace SabreTools.Helper ds.WriteByte(03); ds.WriteByte(00); } - - /// - /// Get the text associated with a return status - /// - /// ZipReturn status to parse - /// String associated with the ZipReturn - public static string ZipErrorMessageText(ZipReturn zr) - { - string ret = "Unknown"; - switch (zr) - { - case ZipReturn.ZipGood: - ret = ""; - break; - case ZipReturn.ZipFileCountError: - ret = "The number of file in the Zip does not mach the number of files in the Zips Centeral Directory"; - break; - case ZipReturn.ZipSignatureError: - ret = "An unknown Signature Block was found in the Zip"; - break; - case ZipReturn.ZipExtraDataOnEndOfZip: - ret = "Extra Data was found on the end of the Zip"; - break; - case ZipReturn.ZipUnsupportedCompression: - ret = "An unsupported Compression method was found in the Zip, if you recompress this zip it will be usable"; - break; - case ZipReturn.ZipLocalFileHeaderError: - ret = "Error reading a zipped file header information"; - break; - case ZipReturn.ZipCentralDirError: - ret = "There is an error in the Zip Centeral Directory"; - break; - case ZipReturn.ZipReadingFromOutputFile: - ret = "Trying to write to a Zip file open for output only"; - break; - case ZipReturn.ZipWritingToInputFile: - ret = "Tring to read from a Zip file open for input only"; - break; - case ZipReturn.ZipErrorGettingDataStream: - ret = "Error creating Data Stream"; - break; - case ZipReturn.ZipCRCDecodeError: - ret = "CRC error"; - break; - case ZipReturn.ZipDecodeError: - ret = "Error unzipping a file"; - break; - } - - return ret; - } - - /// - /// Compare two strings in TorrentZip format - /// - /// - /// - /// - private static int TorrentZipStringCompare(string string1, string string2) - { - char[] bytes1 = string1.ToCharArray(); - char[] bytes2 = string2.ToCharArray(); - - int pos1 = 0; - int pos2 = 0; - - for (;;) - { - if (pos1 == bytes1.Length) - { - return ((pos2 == bytes2.Length) ? 0 : -1); - } - if (pos2 == bytes2.Length) - { - return 1; - } - - int byte1 = bytes1[pos1++]; - int byte2 = bytes2[pos2++]; - - if (byte1 >= 65 && byte1 <= 90) - { - byte1 += 0x20; - } - if (byte2 >= 65 && byte2 <= 90) - { - byte2 += 0x20; - } - - if (byte1 < byte2) - { - return -1; - } - if (byte1 > byte2) - { - return 1; - } - } - } } } diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs index 58f6f0ed..4f882ee3 100644 --- a/SabreTools.Helper/Tools/FileTools.cs +++ b/SabreTools.Helper/Tools/FileTools.cs @@ -801,122 +801,6 @@ namespace SabreTools.Helper } } - /// - /// 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 - /// - /// This does not do any handling for Zip64 currently - /// https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT - /// - public static ZipArchiveStruct GetZipFileInfo(string input, Logger logger) - { - // Create the zip archive struct to hold all of the information - ZipArchiveStruct zas = new ZipArchiveStruct - { - FileName = Path.GetFileNameWithoutExtension(input), - Entries = new List(), - }; - - int position = -1; - - // Seek backwards to find the EOCD pattern - using (BinaryReader br = new BinaryReader(File.OpenRead(input))) - { - int sig = 101010256; - int read = 0; - int index = -5; - while (sig != read && (-index) < new FileInfo(input).Length) - { - br.BaseStream.Seek(index, SeekOrigin.End); - read = br.ReadInt32(); - index--; - } - - // If we found the signature, then set the correct position - if (sig == read) - { - position = (int)br.BaseStream.Position - 4; - } - } - - // If we found the EOCD, get all of the information out of that area - if (position != -1) - { - zas.EOCDOffset = (int)position; - using (BinaryReader br = new BinaryReader(File.OpenRead(input))) - { - br.BaseStream.Seek(position, SeekOrigin.Begin); - br.ReadInt32(); // end of central dir signature - br.ReadInt16(); // number of this disk - br.ReadInt16(); // number of the disk with the start of the central directory - br.ReadInt16(); // total number of entries in the central directory on this disk - br.ReadInt16(); // total number of entries in the central directory - br.ReadInt32(); // size of the central directory - position = br.ReadInt32(); // offset of start of central directory with respect to the starting disk number - int commentlength = br.ReadInt16(); - zas.Comment = Style.ConvertHexToAscii(BitConverter.ToString(br.ReadBytes(commentlength))); - } - } - - // If we found the SOCD, get all of the information out of that area - if (position != -1 && position != zas.EOCDOffset) - { - zas.SOCDOffset = position; - using (BinaryReader br = new BinaryReader(File.OpenRead(input))) - { - int temp = 0; - while (temp != 84233040 /* digital signature */ && temp != 101010256 /* eocd */) - { - ZipArchiveEntryStruct zaes = new ZipArchiveEntryStruct(); - - br.BaseStream.Seek(position, SeekOrigin.Begin); - br.ReadInt32(); // central file header signature - zaes.VersionMadeBy = (ArchiveVersion)br.ReadInt16(); - zaes.VersionNeeded = (ArchiveVersion)br.ReadInt16(); - zaes.GeneralPurposeBitFlag = (GeneralPurposeBitFlag)br.ReadInt16(); - zaes.CompressionMethod = (CompressionMethod)br.ReadInt16(); - zaes.LastModFileTime = br.ReadUInt16(); - zaes.LastModFileDate = br.ReadUInt16(); - zaes.CRC = br.ReadUInt32(); - zaes.CompressedSize = br.ReadUInt32(); - zaes.UncompressedSize = br.ReadUInt32(); - int fileNameLength = br.ReadInt16(); - int extraFieldLength = br.ReadInt16(); - int fileCommentLength = br.ReadInt16(); - br.ReadInt16(); // disk number start - zaes.InternalFileAttributes = (InternalFileAttributes)br.ReadInt16(); - zaes.ExternalFileAttributes = br.ReadInt32(); - zaes.RelativeOffset = br.ReadInt32(); - zaes.FileName = br.ReadBytes(fileNameLength); - zaes.ExtraField = br.ReadBytes(extraFieldLength); - zaes.Comment = br.ReadBytes(fileCommentLength); - zaes.Data = new byte[zaes.CompressedSize]; - position += 46 + fileNameLength + extraFieldLength + fileCommentLength; - temp = br.ReadInt32(); - zas.Entries.Add(zaes); - } - } - } - - // Finally, get a hash of the entire central directory (between SOCD and EOCD) - if (zas.SOCDOffset > 0 && zas.EOCDOffset > 0) - { - using (BinaryReader br = new BinaryReader(File.OpenRead(input))) - { - br.BaseStream.Seek(zas.SOCDOffset, SeekOrigin.Begin); - byte[] cd = br.ReadBytes(zas.EOCDOffset - zas.SOCDOffset); - - OptimizedCRC ocrc = new OptimizedCRC(); - ocrc.Update(cd, 0, cd.Length); - zas.CentralDirectoryCRC = ocrc.Value; - } - } - - return zas; - } - /// /// Read the information from an input 7z file /// @@ -1091,199 +975,5 @@ namespace SabreTools.Helper } #endregion - - #region TorrentZip - - /// - /// Write an existing zip archive construct to a torrent zip file - /// - /// 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: - /// Get rid of redundant directories (ones that are implied by files inside them) - /// - public static void WriteTorrentZip(ZipArchiveStruct zae, string output, Logger logger) - { - // First, rearrange entries by name - List entries = zae.Entries; - - using (BinaryWriter bw = new BinaryWriter(File.Open(output, FileMode.Create))) - { - List offsets = new List(); - - // First, write out entries - foreach (ZipArchiveEntryStruct zaes in zae.Entries) - { - offsets.Add(bw.BaseStream.Position); - bw.Write(Constants.LocalFileHeaderSignature); - bw.Write((ushort)20); - bw.Write((ushort)GeneralPurposeBitFlag.DeflatingMaximumCompression); - bw.Write((ushort)CompressionMethod.Deflated); - bw.Write((ushort)48128); - bw.Write((ushort)8600); - bw.Write(zaes.CRC); - bw.Write(zaes.CompressedSize); - bw.Write(zaes.UncompressedSize); - bw.Write((ushort)zaes.FileName.Length); - bw.Write((ushort)0); - bw.Write(zaes.FileName); - bw.Write(zaes.Data); - if ((zaes.GeneralPurposeBitFlag & GeneralPurposeBitFlag.ZeroedCRCAndSize) != 0) - { - bw.Write(zaes.CRC); - bw.Write(zaes.CompressedSize); - bw.Write(zaes.UncompressedSize); - } - } - - // Then write out the central directory - int index = 0; - zae.SOCDOffset = (int)bw.BaseStream.Position; - foreach (ZipArchiveEntryStruct zaes in zae.Entries) - { - bw.Write(Constants.CentralDirectoryHeaderSignature); - bw.Write((ushort)ArchiveVersion.MSDOSandOS2); - bw.Write((ushort)20); - bw.Write((ushort)GeneralPurposeBitFlag.DeflatingMaximumCompression); - bw.Write((ushort)CompressionMethod.Deflated); - bw.Write((ushort)48128); - bw.Write((ushort)8600); - bw.Write(zaes.CRC); - bw.Write(zaes.CompressedSize); - bw.Write(zaes.UncompressedSize); - bw.Write((short)zaes.FileName.Length); - bw.Write((short)0); - bw.Write((short)0); - bw.Write((short)0); - bw.Write((short)0); - bw.Write(0); - bw.Write((int)offsets[index]); - bw.Write(zaes.FileName); - bw.Write(zaes.ExtraField); - bw.Write(zaes.Comment); - index++; - } - zae.EOCDOffset = (int)bw.BaseStream.Position; - - // Finally, write out the end record - bw.Write(new byte[] { 0x50, 0x4b, 0x05, 0x06 }); // end of central dir signature - bw.Write((short)0); - bw.Write((short)0); - bw.Write((short)zae.Entries.Count); - bw.Write((short)zae.Entries.Count); - bw.Write(zae.EOCDOffset - zae.SOCDOffset); - bw.Write(zae.SOCDOffset); - bw.Write((short)22); - bw.Write("TORRENTZIPPED-".ToCharArray()); - } - - using (BinaryReader br = new BinaryReader(File.OpenRead(output))) - { - br.BaseStream.Seek(zae.SOCDOffset, SeekOrigin.Begin); - byte[] cd = br.ReadBytes(zae.EOCDOffset - zae.SOCDOffset); - - OptimizedCRC ocrc = new OptimizedCRC(); - ocrc.Update(cd, 0, cd.Length); - zae.CentralDirectoryCRC = ocrc.Value; - } - - using (BinaryWriter bw = new BinaryWriter(File.Open(output, FileMode.Append))) - { - bw.Write(zae.CentralDirectoryCRC.ToString("X8").ToCharArray()); - } - } - - /// - /// Reorder all of the files in the archive based on lowercase filename - /// - /// Source archive name - /// Logger object for file and console output - /// True if the operation succeeded, false otherwise - public static bool TorrentZipArchive(string inputArchive, Logger logger) - { - bool success = false; - - // If the input file doesn't exist, return - if (!File.Exists(inputArchive)) - { - return success; - } - - // Make sure the file is a zip file to begin with - if (GetCurrentArchiveType(inputArchive, logger) != ArchiveType.Zip) - { - return success; - } - - ZipArchiveStruct zas = GetZipFileInfo(inputArchive, logger); - - for (int i = 0; i < zas.Entries.Count; i++) - { - 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(); - - 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 } } diff --git a/SimpleSort/SimpleSortApp.cs b/SimpleSort/SimpleSortApp.cs index a1011744..cc6edaae 100644 --- a/SimpleSort/SimpleSortApp.cs +++ b/SimpleSort/SimpleSortApp.cs @@ -195,12 +195,6 @@ namespace SabreTools return; } - // TorrentZip a folder - if (tzip) - { - InitTorrentZip(inputs, outdir, tempdir, logger); - } - // If we are converting the folder to TGZ else if (convert) { @@ -234,24 +228,6 @@ namespace SabreTools return; } - private static void InitTorrentZip(List inputs, string outdir, string tempdir, Logger logger) - { - foreach (string input in inputs) - { - if (File.Exists(input)) - { - FileTools.TorrentZipArchive(input, logger); - } - else if (Directory.Exists(input)) - { - foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories)) - { - FileTools.TorrentZipArchive(file, logger); - } - } - } - } - /// /// Wrap sorting files using an input DAT ///