From cd3cbd2b3272f002693aad84a79da145604e9618 Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Thu, 9 Mar 2017 23:18:57 +0100 Subject: [PATCH 01/49] Support for writing zip64 headers in the unused code --- .../Zip/Headers/DirectoryEntryHeader.cs | 32 +++++++++++++---- .../Common/Zip/Headers/LocalEntryHeader.cs | 35 ++++++++++++++++--- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs index 3b50d118..b7d3d5c7 100644 --- a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs @@ -63,6 +63,10 @@ namespace SharpCompress.Common.Zip.Headers internal override void Write(BinaryWriter writer) { + var zip64 = CompressedSize >= uint.MaxValue || UncompressedSize >= uint.MaxValue || RelativeOffsetOfEntryHeader >= uint.MaxValue; + if (zip64) + Version = (ushort)(Version > 45 ? Version : 45); + writer.Write(Version); writer.Write(VersionNeededToExtract); writer.Write((ushort)Flags); @@ -70,24 +74,40 @@ namespace SharpCompress.Common.Zip.Headers writer.Write(LastModifiedTime); writer.Write(LastModifiedDate); writer.Write(Crc); - writer.Write((uint)CompressedSize); - writer.Write((uint)UncompressedSize); + writer.Write(zip64 ? uint.MaxValue : CompressedSize); + writer.Write(zip64 ? uint.MaxValue : UncompressedSize); byte[] nameBytes = EncodeString(Name); writer.Write((ushort)nameBytes.Length); - //writer.Write((ushort)Extra.Length); - writer.Write((ushort)0); + if (zip64) + { + writer.Write((ushort)(2 + 2 + 8 + 8 + 8 + 4)); + } + else + { + //writer.Write((ushort)Extra.Length); + writer.Write((ushort)0); + } writer.Write((ushort)Comment.Length); writer.Write(DiskNumberStart); writer.Write(InternalFileAttributes); writer.Write(ExternalFileAttributes); - writer.Write(RelativeOffsetOfEntryHeader); + writer.Write(zip64 ? uint.MaxValue : RelativeOffsetOfEntryHeader); writer.Write(nameBytes); - // writer.Write(Extra); + if (zip64) + { + writer.Write((ushort)0x0001); + writer.Write((ushort)((8 + 8 + 8 + 4))); + + writer.Write((ulong)UncompressedSize); + writer.Write((ulong)CompressedSize); + writer.Write((ulong)RelativeOffsetOfEntryHeader); + writer.Write((uint)0); // VolumeNumber = 0 + } writer.Write(Comment); } diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs index 2e311cc8..fe539406 100644 --- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs @@ -49,25 +49,52 @@ namespace SharpCompress.Common.Zip.Headers internal override void Write(BinaryWriter writer) { - writer.Write(Version); + if (IsZip64) + Version = (ushort)(Version > 45 ? Version : 45); + + writer.Write(Version); + writer.Write((ushort)Flags); writer.Write((ushort)CompressionMethod); writer.Write(LastModifiedTime); writer.Write(LastModifiedDate); writer.Write(Crc); - writer.Write((uint)CompressedSize); - writer.Write((uint)UncompressedSize); + + if (IsZip64) + { + writer.Write(uint.MaxValue); + writer.Write(uint.MaxValue); + } + else + { + writer.Write(CompressedSize); + writer.Write(UncompressedSize); + } byte[] nameBytes = EncodeString(Name); writer.Write((ushort)nameBytes.Length); - writer.Write((ushort)0); + if (IsZip64) + { + writer.Write((ushort)(2 + 2 + (2 * 8))); + } + else + { + writer.Write((ushort)0); + } //if (Extra != null) //{ // writer.Write(Extra); //} writer.Write(nameBytes); + if (IsZip64) + { + writer.Write((ushort)0x0001); + writer.Write((ushort)(2 * 8)); + writer.Write((ulong)CompressedSize); + writer.Write((ulong)UncompressedSize); + } } internal ushort Version { get; private set; } From 1263c0d97601e509c1aab0bfe31ba089d74b5a9e Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Thu, 9 Mar 2017 23:19:41 +0100 Subject: [PATCH 02/49] Added support for writing zip64 headers --- .../Zip/Headers/DirectoryEntryHeader.cs | 44 +++--- .../Common/Zip/Headers/LocalEntryHeader.cs | 58 ++++---- .../IO/CountingWritableSubStream.cs | 2 +- .../Writers/Zip/ZipCentralDirectoryEntry.cs | 48 ++++-- src/SharpCompress/Writers/Zip/ZipWriter.cs | 137 +++++++++++++++--- .../Writers/Zip/ZipWriterEntryOptions.cs | 5 + .../Writers/Zip/ZipWriterOptions.cs | 7 + 7 files changed, 219 insertions(+), 82 deletions(-) diff --git a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs index b7d3d5c7..acca3bb1 100644 --- a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs @@ -63,9 +63,9 @@ namespace SharpCompress.Common.Zip.Headers internal override void Write(BinaryWriter writer) { - var zip64 = CompressedSize >= uint.MaxValue || UncompressedSize >= uint.MaxValue || RelativeOffsetOfEntryHeader >= uint.MaxValue; - if (zip64) - Version = (ushort)(Version > 45 ? Version : 45); + var zip64 = CompressedSize >= uint.MaxValue || UncompressedSize >= uint.MaxValue || RelativeOffsetOfEntryHeader >= uint.MaxValue; + if (zip64) + Version = (ushort)(Version > 45 ? Version : 45); writer.Write(Version); writer.Write(VersionNeededToExtract); @@ -74,21 +74,21 @@ namespace SharpCompress.Common.Zip.Headers writer.Write(LastModifiedTime); writer.Write(LastModifiedDate); writer.Write(Crc); - writer.Write(zip64 ? uint.MaxValue : CompressedSize); + writer.Write(zip64 ? uint.MaxValue : CompressedSize); writer.Write(zip64 ? uint.MaxValue : UncompressedSize); byte[] nameBytes = EncodeString(Name); writer.Write((ushort)nameBytes.Length); - if (zip64) - { - writer.Write((ushort)(2 + 2 + 8 + 8 + 8 + 4)); - } - else - { - //writer.Write((ushort)Extra.Length); - writer.Write((ushort)0); - } + if (zip64) + { + writer.Write((ushort)(2 + 2 + 8 + 8 + 8 + 4)); + } + else + { + //writer.Write((ushort)Extra.Length); + writer.Write((ushort)0); + } writer.Write((ushort)Comment.Length); writer.Write(DiskNumberStart); @@ -98,16 +98,16 @@ namespace SharpCompress.Common.Zip.Headers writer.Write(nameBytes); - if (zip64) - { - writer.Write((ushort)0x0001); - writer.Write((ushort)((8 + 8 + 8 + 4))); + if (zip64) + { + writer.Write((ushort)0x0001); + writer.Write((ushort)((8 + 8 + 8 + 4))); - writer.Write((ulong)UncompressedSize); - writer.Write((ulong)CompressedSize); - writer.Write((ulong)RelativeOffsetOfEntryHeader); - writer.Write((uint)0); // VolumeNumber = 0 - } + writer.Write((ulong)UncompressedSize); + writer.Write((ulong)CompressedSize); + writer.Write((ulong)RelativeOffsetOfEntryHeader); + writer.Write((uint)0); // VolumeNumber = 0 + } writer.Write(Comment); } diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs index fe539406..40e2a662 100644 --- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs @@ -49,52 +49,52 @@ namespace SharpCompress.Common.Zip.Headers internal override void Write(BinaryWriter writer) { - if (IsZip64) - Version = (ushort)(Version > 45 ? Version : 45); + if (IsZip64) + Version = (ushort)(Version > 45 ? Version : 45); - writer.Write(Version); - + writer.Write(Version); + writer.Write((ushort)Flags); writer.Write((ushort)CompressionMethod); writer.Write(LastModifiedTime); writer.Write(LastModifiedDate); writer.Write(Crc); - if (IsZip64) - { - writer.Write(uint.MaxValue); - writer.Write(uint.MaxValue); - } - else - { - writer.Write(CompressedSize); - writer.Write(UncompressedSize); - } + if (IsZip64) + { + writer.Write(uint.MaxValue); + writer.Write(uint.MaxValue); + } + else + { + writer.Write(CompressedSize); + writer.Write(UncompressedSize); + } byte[] nameBytes = EncodeString(Name); writer.Write((ushort)nameBytes.Length); - if (IsZip64) - { - writer.Write((ushort)(2 + 2 + (2 * 8))); - } - else - { - writer.Write((ushort)0); - } + if (IsZip64) + { + writer.Write((ushort)(2 + 2 + (2 * 8))); + } + else + { + writer.Write((ushort)0); + } //if (Extra != null) //{ // writer.Write(Extra); //} writer.Write(nameBytes); - if (IsZip64) - { - writer.Write((ushort)0x0001); - writer.Write((ushort)(2 * 8)); - writer.Write((ulong)CompressedSize); - writer.Write((ulong)UncompressedSize); - } + if (IsZip64) + { + writer.Write((ushort)0x0001); + writer.Write((ushort)(2 * 8)); + writer.Write((ulong)CompressedSize); + writer.Write((ulong)UncompressedSize); + } } internal ushort Version { get; private set; } diff --git a/src/SharpCompress/IO/CountingWritableSubStream.cs b/src/SharpCompress/IO/CountingWritableSubStream.cs index 17313612..51989b75 100644 --- a/src/SharpCompress/IO/CountingWritableSubStream.cs +++ b/src/SharpCompress/IO/CountingWritableSubStream.cs @@ -12,7 +12,7 @@ namespace SharpCompress.IO writableStream = stream; } - public uint Count { get; private set; } + public ulong Count { get; private set; } public override bool CanRead { get { return false; } } diff --git a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs index 28b9aa63..03f1ee5a 100644 --- a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs +++ b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs @@ -13,36 +13,51 @@ namespace SharpCompress.Writers.Zip internal DateTime? ModificationTime { get; set; } internal string Comment { get; set; } internal uint Crc { get; set; } - internal uint HeaderOffset { get; set; } - internal uint Compressed { get; set; } - internal uint Decompressed { get; set; } + internal ulong HeaderOffset { get; set; } + internal ulong Compressed { get; set; } + internal ulong Decompressed { get; set; } + internal ushort Zip64HeaderOffset { get; set; } internal uint Write(Stream outputStream, ZipCompressionMethod compression) { byte[] encodedFilename = Encoding.UTF8.GetBytes(FileName); byte[] encodedComment = Encoding.UTF8.GetBytes(Comment); - //constant sig, then version made by, compabitility, then version to extract - outputStream.Write(new byte[] {80, 75, 1, 2, 0x14, 0, 0x0A, 0}, 0, 8); + var zip64 = Compressed >= uint.MaxValue || Decompressed >= uint.MaxValue || HeaderOffset >= uint.MaxValue || Zip64HeaderOffset != 0; + + var compressedvalue = zip64 ? uint.MaxValue : (uint)Compressed; + var decompressedvalue = zip64 ? uint.MaxValue : (uint)Decompressed; + var headeroffsetvalue = zip64 ? uint.MaxValue : (uint)HeaderOffset; + var extralength = zip64 ? (2 + 2 + 8 + 8 + 8 + 4) : 0; + var version = (byte)(zip64 ? 45 : 10); + HeaderFlags flags = HeaderFlags.UTF8; if (!outputStream.CanSeek) { - flags |= HeaderFlags.UsePostDataDescriptor; + // Cannot use data descriptors with zip64: + // https://blogs.oracle.com/xuemingshen/entry/is_zipinput_outputstream_handling_of + if (!zip64) + flags |= HeaderFlags.UsePostDataDescriptor; + if (compression == ZipCompressionMethod.LZMA) { flags |= HeaderFlags.Bit1; // eos marker } } + + //constant sig, then version made by, compabitility, then version to extract + outputStream.Write(new byte[] { 80, 75, 1, 2, 0x14, 0, version, 0 }, 0, 8); + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)flags), 0, 2); outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)compression), 0, 2); // zipping method outputStream.Write(DataConverter.LittleEndian.GetBytes(ModificationTime.DateTimeToDosTime()), 0, 4); // zipping date and time outputStream.Write(DataConverter.LittleEndian.GetBytes(Crc), 0, 4); // file CRC - outputStream.Write(DataConverter.LittleEndian.GetBytes(Compressed), 0, 4); // compressed file size - outputStream.Write(DataConverter.LittleEndian.GetBytes(Decompressed), 0, 4); // uncompressed file size + outputStream.Write(DataConverter.LittleEndian.GetBytes(compressedvalue), 0, 4); // compressed file size + outputStream.Write(DataConverter.LittleEndian.GetBytes(decompressedvalue), 0, 4); // uncompressed file size outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedFilename.Length), 0, 2); // Filename in zip - outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0), 0, 2); // extra length + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)extralength), 0, 2); // extra length outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedComment.Length), 0, 2); outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0), 0, 2); // disk=0 @@ -51,13 +66,24 @@ namespace SharpCompress.Writers.Zip outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0x8100), 0, 2); // External file attributes (normal/readable) - outputStream.Write(DataConverter.LittleEndian.GetBytes(HeaderOffset), 0, 4); // Offset of header + outputStream.Write(DataConverter.LittleEndian.GetBytes(headeroffsetvalue), 0, 4); // Offset of header outputStream.Write(encodedFilename, 0, encodedFilename.Length); + if (zip64) + { + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0x0001), 0, 2); + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)(extralength - 4)), 0, 2); + + outputStream.Write(DataConverter.LittleEndian.GetBytes(Decompressed), 0, 8); + outputStream.Write(DataConverter.LittleEndian.GetBytes(Compressed), 0, 8); + outputStream.Write(DataConverter.LittleEndian.GetBytes(HeaderOffset), 0, 8); + outputStream.Write(DataConverter.LittleEndian.GetBytes(0), 0, 4); // VolumeNumber = 0 + } + outputStream.Write(encodedComment, 0, encodedComment.Length); return (uint)(8 + 2 + 2 + 4 + 4 + 4 + 4 + 2 + 2 + 2 - + 2 + 2 + 2 + 2 + 4 + encodedFilename.Length + encodedComment.Length); + + 2 + 2 + 2 + 2 + 4 + encodedFilename.Length + extralength + encodedComment.Length); } } } \ No newline at end of file diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index d89294b5..f40726c6 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -23,11 +23,13 @@ namespace SharpCompress.Writers.Zip private readonly string zipComment; private long streamPosition; private PpmdProperties ppmdProps; + private bool isZip64; public ZipWriter(Stream destination, ZipWriterOptions zipWriterOptions) : base(ArchiveType.Zip) { zipComment = zipWriterOptions.ArchiveComment ?? string.Empty; + isZip64 = zipWriterOptions.UseZip64; compressionType = zipWriterOptions.CompressionType; compressionLevel = zipWriterOptions.DeflateCompressionLevel; @@ -50,7 +52,7 @@ namespace SharpCompress.Writers.Zip { if (isDisposing) { - uint size = 0; + ulong size = 0; foreach (ZipCentralDirectoryEntry entry in entries) { size += entry.Write(OutputStream, ToZipCompressionMethod(compressionType)); @@ -117,7 +119,14 @@ namespace SharpCompress.Writers.Zip HeaderOffset = (uint)streamPosition }; - var headersize = (uint)WriteHeader(entryPath, options); + // Switch to allocating space for zip64, if the archive is larger than 2GB + var useZip64 = (OutputStream.CanSeek && OutputStream.Length > int.MaxValue) || isZip64; + + // Allow direct disabling + if (options.EnableZip64.HasValue) + useZip64 = options.EnableZip64.Value; + + var headersize = (uint)WriteHeader(entryPath, options, entry, useZip64); streamPosition += headersize; return new ZipWritingStream(this, OutputStream, entry, ToZipCompressionMethod(options.CompressionType ?? compressionType), @@ -137,7 +146,7 @@ namespace SharpCompress.Writers.Zip return filename.Trim('/'); } - private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions) + private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions, ZipCentralDirectoryEntry entry, bool useZip64) { var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType); byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename); @@ -145,16 +154,21 @@ namespace SharpCompress.Writers.Zip OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4); if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate) { - OutputStream.Write(new byte[] {20, 0}, 0, 2); //older version which is more compatible + if (OutputStream.CanSeek && useZip64) + OutputStream.Write(new byte[] { 45, 0 }, 0, 2); //smallest allowed version for zip64 + else + OutputStream.Write(new byte[] { 20, 0 }, 0, 2); //older version which is more compatible } else { - OutputStream.Write(new byte[] {63, 0}, 0, 2); //version says we used PPMd or LZMA + OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA } HeaderFlags flags = ArchiveEncoding.Default == Encoding.UTF8 ? HeaderFlags.UTF8 : 0; if (!OutputStream.CanSeek) { + // We cannot really use post data with zip64, but we have nothing else flags |= HeaderFlags.UsePostDataDescriptor; + if (explicitZipCompressionInfo == ZipCompressionMethod.LZMA) { flags |= HeaderFlags.Bit1; // eos marker @@ -165,14 +179,25 @@ namespace SharpCompress.Writers.Zip OutputStream.Write(DataConverter.LittleEndian.GetBytes(zipWriterEntryOptions.ModificationDateTime.DateTimeToDosTime()), 0, 4); // zipping date and time - OutputStream.Write(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 12); + OutputStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12); // unused CRC, un/compressed size, updated later OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedFilename.Length), 0, 2); // filename length - OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0), 0, 2); // extra length + + var extralength = 0; + if (OutputStream.CanSeek && useZip64) + extralength = 2 + 2 + 8 + 8; + + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)extralength), 0, 2); // extra length OutputStream.Write(encodedFilename, 0, encodedFilename.Length); - return 6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length; + if (extralength != 0) + { + OutputStream.Write(new byte[extralength], 0, extralength); // reserve space for zip64 data + entry.Zip64HeaderOffset = (ushort)(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length); + } + + return 6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length + extralength; } private void WriteFooter(uint crc, uint compressed, uint uncompressed) @@ -182,15 +207,58 @@ namespace SharpCompress.Writers.Zip OutputStream.Write(DataConverter.LittleEndian.GetBytes(uncompressed), 0, 4); } - private void WriteEndRecord(uint size) + private void WritePostdataDescriptor(uint crc, ulong compressed, ulong uncompressed) + { + OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.POST_DATA_DESCRIPTOR), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(crc), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint)compressed), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint)uncompressed), 0, 4); + } + + private void WriteEndRecord(ulong size) { byte[] encodedComment = ArchiveEncoding.Default.GetBytes(zipComment); + var zip64 = isZip64 || entries.Count > ushort.MaxValue || streamPosition >= uint.MaxValue || size >= uint.MaxValue; + var sizevalue = size >= uint.MaxValue ? uint.MaxValue : (uint)size; + var streampositionvalue = streamPosition >= uint.MaxValue ? uint.MaxValue : (uint)streamPosition; + + if (zip64) + { + var recordlen = 4 + 8 + 2 + 2 + 4 + 4 + 8 + 8 + 8 + 8; + + // Write zip64 end of central directory record + OutputStream.Write(new byte[] { 80, 75, 6, 6 }, 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ulong)recordlen), 0, 8); // Size of zip64 end of central directory record + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0), 0, 2); // Made by + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)45), 0, 2); // Version needed + + OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint)0), 0, 4); // Disk number + OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint)0), 0, 4); // Central dir disk + + // TODO: entries.Count is int, so max 2^31 files + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ulong)entries.Count), 0, 8); // Entries in this disk + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ulong)entries.Count), 0, 8); // Total entries + OutputStream.Write(DataConverter.LittleEndian.GetBytes(size), 0, 8); // Central Directory size + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ulong)streamPosition), 0, 8); // Disk offset + + // Write zip64 end of central directory locator + OutputStream.Write(new byte[] { 80, 75, 6, 7 }, 0, 4); + + OutputStream.Write(DataConverter.LittleEndian.GetBytes(0uL), 0, 4); // Entry disk + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ulong)streamPosition + size), 0, 8); // Offset to the zip64 central directory + OutputStream.Write(DataConverter.LittleEndian.GetBytes(0u), 0, 4); // Number of disks + + streamPosition += recordlen + (4 + 4 + 8 + 4); + streampositionvalue = streamPosition >= uint.MaxValue ? uint.MaxValue : (uint)streampositionvalue; + } + + // Write normal end of central directory record OutputStream.Write(new byte[] {80, 75, 5, 6, 0, 0, 0, 0}, 0, 8); OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)entries.Count), 0, 2); OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)entries.Count), 0, 2); - OutputStream.Write(DataConverter.LittleEndian.GetBytes(size), 0, 4); - OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint)streamPosition), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(sizevalue), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint)streampositionvalue), 0, 4); OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedComment.Length), 0, 2); OutputStream.Write(encodedComment, 0, encodedComment.Length); } @@ -207,7 +275,7 @@ namespace SharpCompress.Writers.Zip private readonly ZipCompressionMethod zipCompressionMethod; private readonly CompressionLevel compressionLevel; private CountingWritableSubStream counting; - private uint decompressed; + private ulong decompressed; internal ZipWritingStream(ZipWriter writer, Stream originalStream, ZipCentralDirectoryEntry entry, ZipCompressionMethod zipCompressionMethod, CompressionLevel compressionLevel) @@ -283,20 +351,51 @@ namespace SharpCompress.Writers.Zip entry.Crc = (uint)crc.Crc32Result; entry.Compressed = counting.Count; entry.Decompressed = decompressed; + + var zip64 = entry.Compressed >= uint.MaxValue || entry.Decompressed >= uint.MaxValue || entry.HeaderOffset >= uint.MaxValue; + + writer.isZip64 |= zip64; + + var compressedvalue = zip64 ? uint.MaxValue : (uint)counting.Count; + var decompressedvalue = zip64 ? uint.MaxValue : (uint)entry.Decompressed; + if (originalStream.CanSeek) { - originalStream.Position = entry.HeaderOffset + 6; + originalStream.Position = (long)(entry.HeaderOffset + 6); originalStream.WriteByte(0); - originalStream.Position = entry.HeaderOffset + 14; - writer.WriteFooter(entry.Crc, counting.Count, decompressed); - originalStream.Position = writer.streamPosition + entry.Compressed; - writer.streamPosition += entry.Compressed; + + originalStream.Position = (long)(entry.HeaderOffset + 14); + + writer.WriteFooter(entry.Crc, compressedvalue, decompressedvalue); + + // If we have pre-allocated space for zip64 data, fill it out + if (entry.Zip64HeaderOffset != 0) + { + originalStream.Position = (long)(entry.HeaderOffset + entry.Zip64HeaderOffset); + originalStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0x0001), 0, 2); + originalStream.Write(DataConverter.LittleEndian.GetBytes((ushort)(8 + 8)), 0, 2); + + originalStream.Write(DataConverter.LittleEndian.GetBytes(entry.Decompressed), 0, 8); + originalStream.Write(DataConverter.LittleEndian.GetBytes(entry.Compressed), 0, 8); + } + + originalStream.Position = writer.streamPosition + (long)entry.Compressed; + writer.streamPosition += (long)entry.Compressed; + } else { + // Bit unclear what happens here, with zip64 + // We have a streaming archive, so we should add a post-data-descriptor, + // but we cannot as it does not hold the zip64 values + + // The current implementation writes 0xffffffff in the fields here, and the + // the central directory has the extra data required if the fields are overflown originalStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.POST_DATA_DESCRIPTOR), 0, 4); - writer.WriteFooter(entry.Crc, counting.Count, decompressed); - writer.streamPosition += entry.Compressed + 16; + writer.WriteFooter(entry.Crc, + (uint)(counting.Count >= uint.MaxValue ? uint.MaxValue : counting.Count), + (uint)(entry.Decompressed >= uint.MaxValue ? uint.MaxValue : entry.Decompressed)); + writer.streamPosition += (long)entry.Compressed + 16; } writer.entries.Add(entry); } diff --git a/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs b/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs index 81f1d1c0..40609098 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs @@ -15,5 +15,10 @@ namespace SharpCompress.Writers.Zip public string EntryComment { get; set; } public DateTime? ModificationDateTime { get; set; } + + /// + /// Allocate space for storing values if the file is larger than 4GiB + /// + public bool? EnableZip64 { get; set; } } } \ No newline at end of file diff --git a/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs b/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs index 662a50d4..1cad53d4 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs @@ -15,6 +15,8 @@ namespace SharpCompress.Writers.Zip : base(options.CompressionType) { LeaveStreamOpen = options.LeaveStreamOpen; + if (options is ZipWriterOptions) + UseZip64 = ((ZipWriterOptions)options).UseZip64; } /// /// When CompressionType.Deflate is used, this property is referenced. Defaults to CompressionLevel.Default. @@ -22,5 +24,10 @@ namespace SharpCompress.Writers.Zip public CompressionLevel DeflateCompressionLevel { get; set; } = CompressionLevel.Default; public string ArchiveComment { get; set; } + + /// + /// Sets a value indicating if zip64 support is enabled. If this is not set, zip64 will be enabled once the file is larger than 2GB + /// + public bool UseZip64 { get; set; } } } \ No newline at end of file From d7f4c0ee323b60cf7845e19e611cbfdd4381e79b Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Fri, 10 Mar 2017 23:10:06 +0100 Subject: [PATCH 03/49] Fixed an error in the zip64 central end of header: the signature + length (12 bytes) are not included in the reported length. --- src/SharpCompress/Writers/Zip/ZipWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index f40726c6..6f38a28d 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -225,7 +225,7 @@ namespace SharpCompress.Writers.Zip if (zip64) { - var recordlen = 4 + 8 + 2 + 2 + 4 + 4 + 8 + 8 + 8 + 8; + var recordlen = 2 + 2 + 4 + 4 + 8 + 8 + 8 + 8; // Write zip64 end of central directory record OutputStream.Write(new byte[] { 80, 75, 6, 6 }, 0, 4); From 85280f6f4fcf7e845330755f5f12b567f83eb3f1 Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Fri, 10 Mar 2017 23:18:26 +0100 Subject: [PATCH 04/49] Changed the logic to throw exceptions when sizes exceed the zip archive limits, and zip64 is not enabled. This changes the logic, such that archives larger than 4GiB are still automatically written correct (only the central header is special). Archives with individual streams larger than 4 GiB must set the zip64 flag, either on the archive or the individual streams. --- .../Writers/Zip/ZipCentralDirectoryEntry.cs | 9 +- src/SharpCompress/Writers/Zip/ZipWriter.cs | 105 ++++++++++++------ .../Writers/Zip/ZipWriterEntryOptions.cs | 5 +- .../Writers/Zip/ZipWriterOptions.cs | 6 +- 4 files changed, 90 insertions(+), 35 deletions(-) diff --git a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs index 03f1ee5a..3e29a0f5 100644 --- a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs +++ b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs @@ -23,7 +23,8 @@ namespace SharpCompress.Writers.Zip byte[] encodedFilename = Encoding.UTF8.GetBytes(FileName); byte[] encodedComment = Encoding.UTF8.GetBytes(Comment); - var zip64 = Compressed >= uint.MaxValue || Decompressed >= uint.MaxValue || HeaderOffset >= uint.MaxValue || Zip64HeaderOffset != 0; + var zip64_stream = Compressed >= uint.MaxValue || Decompressed >= uint.MaxValue; + var zip64 = zip64_stream || HeaderOffset >= uint.MaxValue || Zip64HeaderOffset != 0; var compressedvalue = zip64 ? uint.MaxValue : (uint)Compressed; var decompressedvalue = zip64 ? uint.MaxValue : (uint)Decompressed; @@ -36,7 +37,11 @@ namespace SharpCompress.Writers.Zip { // Cannot use data descriptors with zip64: // https://blogs.oracle.com/xuemingshen/entry/is_zipinput_outputstream_handling_of - if (!zip64) + + // We check that streams are not written too large in the ZipWritingStream, + // so this extra guard is not required, but kept to simplify changing the code + // once the zip64 post-data issue is resolved + if (!zip64_stream) flags |= HeaderFlags.UsePostDataDescriptor; if (compression == ZipCompressionMethod.LZMA) diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index 6f38a28d..e1a001b5 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -116,13 +116,11 @@ namespace SharpCompress.Writers.Zip Comment = options.EntryComment, FileName = entryPath, ModificationTime = options.ModificationDateTime, - HeaderOffset = (uint)streamPosition - }; + HeaderOffset = (ulong)streamPosition + }; - // Switch to allocating space for zip64, if the archive is larger than 2GB - var useZip64 = (OutputStream.CanSeek && OutputStream.Length > int.MaxValue) || isZip64; - - // Allow direct disabling + // Use the archive default setting for zip64 and allow overrides + var useZip64 = isZip64; if (options.EnableZip64.HasValue) useZip64 = options.EnableZip64.Value; @@ -148,6 +146,10 @@ namespace SharpCompress.Writers.Zip private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions, ZipCentralDirectoryEntry entry, bool useZip64) { + // We err on the side of caution until the zip specification clarifies how to support this + if (!OutputStream.CanSeek && useZip64) + throw new NotSupportedException("Zip64 extensions are not supported on non-seekable streams"); + var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType); byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename); @@ -166,7 +168,6 @@ namespace SharpCompress.Writers.Zip HeaderFlags flags = ArchiveEncoding.Default == Encoding.UTF8 ? HeaderFlags.UTF8 : 0; if (!OutputStream.CanSeek) { - // We cannot really use post data with zip64, but we have nothing else flags |= HeaderFlags.UsePostDataDescriptor; if (explicitZipCompressionInfo == ZipCompressionMethod.LZMA) @@ -277,6 +278,9 @@ namespace SharpCompress.Writers.Zip private CountingWritableSubStream counting; private ulong decompressed; + // Flag to prevent throwing exceptions on Dispose + private bool limitsExceeded; + internal ZipWritingStream(ZipWriter writer, Stream originalStream, ZipCentralDirectoryEntry entry, ZipCompressionMethod zipCompressionMethod, CompressionLevel compressionLevel) { @@ -348,16 +352,23 @@ namespace SharpCompress.Writers.Zip if (disposing) { writeStream.Dispose(); + + if (limitsExceeded) + { + // We have written invalid data into the archive, + // so we destroy it now, instead of allowing the user to continue + // with a defunct archive + originalStream.Dispose(); + return; + } + entry.Crc = (uint)crc.Crc32Result; entry.Compressed = counting.Count; entry.Decompressed = decompressed; - var zip64 = entry.Compressed >= uint.MaxValue || entry.Decompressed >= uint.MaxValue || entry.HeaderOffset >= uint.MaxValue; - - writer.isZip64 |= zip64; - - var compressedvalue = zip64 ? uint.MaxValue : (uint)counting.Count; - var decompressedvalue = zip64 ? uint.MaxValue : (uint)entry.Decompressed; + var zip64 = entry.Compressed >= uint.MaxValue || entry.Decompressed >= uint.MaxValue; + var compressedvalue = zip64 ? uint.MaxValue : (uint)counting.Count; + var decompressedvalue = zip64 ? uint.MaxValue : (uint)entry.Decompressed; if (originalStream.CanSeek) { @@ -368,33 +379,41 @@ namespace SharpCompress.Writers.Zip writer.WriteFooter(entry.Crc, compressedvalue, decompressedvalue); - // If we have pre-allocated space for zip64 data, fill it out - if (entry.Zip64HeaderOffset != 0) - { - originalStream.Position = (long)(entry.HeaderOffset + entry.Zip64HeaderOffset); - originalStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0x0001), 0, 2); - originalStream.Write(DataConverter.LittleEndian.GetBytes((ushort)(8 + 8)), 0, 2); + // Ideally, we should not throw from Dispose() + // We should not get here as the Write call checks the limits + if (zip64 && entry.Zip64HeaderOffset == 0) + throw new NotSupportedException("Attempted to write a stream that is larger than 4GiB without setting the zip64 option"); - originalStream.Write(DataConverter.LittleEndian.GetBytes(entry.Decompressed), 0, 8); - originalStream.Write(DataConverter.LittleEndian.GetBytes(entry.Compressed), 0, 8); - } + // If we have pre-allocated space for zip64 data, + // fill it out, even if it is not required + if (entry.Zip64HeaderOffset != 0) + { + originalStream.Position = (long)(entry.HeaderOffset + entry.Zip64HeaderOffset); + originalStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0x0001), 0, 2); + originalStream.Write(DataConverter.LittleEndian.GetBytes((ushort)(8 + 8)), 0, 2); + + originalStream.Write(DataConverter.LittleEndian.GetBytes(entry.Decompressed), 0, 8); + originalStream.Write(DataConverter.LittleEndian.GetBytes(entry.Compressed), 0, 8); + } originalStream.Position = writer.streamPosition + (long)entry.Compressed; writer.streamPosition += (long)entry.Compressed; - } else { - // Bit unclear what happens here, with zip64 - // We have a streaming archive, so we should add a post-data-descriptor, - // but we cannot as it does not hold the zip64 values + // We have a streaming archive, so we should add a post-data-descriptor, + // but we cannot as it does not hold the zip64 values + // Throwing an exception until the zip specification is clarified - // The current implementation writes 0xffffffff in the fields here, and the - // the central directory has the extra data required if the fields are overflown - originalStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.POST_DATA_DESCRIPTOR), 0, 4); + // Ideally, we should not throw from Dispose() + // We should not get here as the Write call checks the limits + if (zip64) + throw new NotSupportedException("Streams larger than 4GiB are not supported for non-seekable streams"); + + originalStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.POST_DATA_DESCRIPTOR), 0, 4); writer.WriteFooter(entry.Crc, - (uint)(counting.Count >= uint.MaxValue ? uint.MaxValue : counting.Count), - (uint)(entry.Decompressed >= uint.MaxValue ? uint.MaxValue : entry.Decompressed)); + (uint)compressedvalue, + (uint)decompressedvalue); writer.streamPosition += (long)entry.Compressed + 16; } writer.entries.Add(entry); @@ -423,9 +442,33 @@ namespace SharpCompress.Writers.Zip public override void Write(byte[] buffer, int offset, int count) { + // We check the limits first, because we can keep the archive consistent + // if we can prevent the writes from happening + if (entry.Zip64HeaderOffset == 0) + { + // Pre-check, the counting.Count is not exact, as we do not know the size before having actually compressed it + if (limitsExceeded || ((decompressed + (uint)count) > uint.MaxValue) || (counting.Count + (uint)count) > uint.MaxValue) + throw new NotSupportedException("Attempted to write a stream that is larger than 4GiB without setting the zip64 option"); + } + decompressed += (uint)count; crc.SlurpBlock(buffer, offset, count); writeStream.Write(buffer, offset, count); + + if (entry.Zip64HeaderOffset == 0) + { + // Post-check, this is accurate + if ((decompressed > uint.MaxValue) || counting.Count > uint.MaxValue) + { + // We have written the data, so the archive is now broken + // Throwing the exception here, allows us to avoid + // throwing an exception in Dispose() which is discouraged + // as it can mask other errors + limitsExceeded = true; + throw new NotSupportedException("Attempted to write a stream that is larger than 4GiB without setting the zip64 option"); + } + } + } } diff --git a/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs b/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs index 40609098..5f1d8152 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriterEntryOptions.cs @@ -17,7 +17,10 @@ namespace SharpCompress.Writers.Zip public DateTime? ModificationDateTime { get; set; } /// - /// Allocate space for storing values if the file is larger than 4GiB + /// Allocate an extra 20 bytes for this entry to store, + /// 64 bit length values, thus enabling streams + /// larger than 4GiB. + /// This option is not supported with non-seekable streams. /// public bool? EnableZip64 { get; set; } } diff --git a/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs b/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs index 1cad53d4..81c2afbe 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriterOptions.cs @@ -26,7 +26,11 @@ namespace SharpCompress.Writers.Zip public string ArchiveComment { get; set; } /// - /// Sets a value indicating if zip64 support is enabled. If this is not set, zip64 will be enabled once the file is larger than 2GB + /// Sets a value indicating if zip64 support is enabled. + /// If this is not set, individual stream lengths cannot exceed 4 GiB. + /// This option is not supported for non-seekable streams. + /// Archives larger than 4GiB are supported as long as all streams + /// are less than 4GiB in length. /// public bool UseZip64 { get; set; } } From 2894711c5128d16a80e70f7e551fe6c16e892b1d Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Sat, 11 Mar 2017 00:54:06 +0100 Subject: [PATCH 05/49] Added a test suite to verify zip64 write support is working, and can be read in both Archive and Stream mode --- test/SharpCompress.Test/Zip/Zip64Tests.cs | 213 ++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 test/SharpCompress.Test/Zip/Zip64Tests.cs diff --git a/test/SharpCompress.Test/Zip/Zip64Tests.cs b/test/SharpCompress.Test/Zip/Zip64Tests.cs new file mode 100644 index 00000000..fb39468d --- /dev/null +++ b/test/SharpCompress.Test/Zip/Zip64Tests.cs @@ -0,0 +1,213 @@ +using System; +using System.IO; +using System.Linq; +using SharpCompress.Archives; +using SharpCompress.Common; +using SharpCompress.Readers; +using SharpCompress.Readers.Zip; +using SharpCompress.Writers; +using SharpCompress.Writers.Zip; +using Xunit; + +namespace SharpCompress.Test +{ + public class Zip64Tests : WriterTests + { + // 4GiB + 1 + const long FOUR_GB_LIMIT = ((long)uint.MaxValue) + 1; + + [Fact] + public void Zip64_Single_Large_File() + { + // One single file, requires zip64 + RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: true, forward_only: false); + } + + [Fact] + public void Zip64_Two_Large_Files() + { + // One single file, requires zip64 + RunSingleTest(2, FOUR_GB_LIMIT, set_zip64: true, forward_only: false); + } + + [Fact] + public void Zip64_Two_Small_files() + { + // Multiple files, does not require zip64 + RunSingleTest(2, FOUR_GB_LIMIT / 2, set_zip64: false, forward_only: false); + } + + [Fact] + public void Zip64_Two_Small_files_stream() + { + // Multiple files, does not require zip64, and works with streams + RunSingleTest(2, FOUR_GB_LIMIT / 2, set_zip64: false, forward_only: true); + } + + [Fact] + public void Zip64_Two_Small_Files_Zip64() + { + // Multiple files, use zip64 even though it is not required + RunSingleTest(2, FOUR_GB_LIMIT / 2, set_zip64: true, forward_only: false); + } + + [Fact] + public void Zip64_Single_Large_File_Fail() + { + try + { + // One single file, should fail + RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: false, forward_only: false); + throw new Exception("Test did not fail?"); + } + catch (NotSupportedException) + { + } + } + + [Fact] + public void Zip64_Single_Large_File_Zip64_Streaming_Fail() + { + try + { + // One single file, should fail (fast) with zip64 + RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: true, forward_only: true); + throw new Exception("Test did not fail?"); + } + catch (NotSupportedException) + { + } + } + + [Fact] + public void Zip64_Single_Large_File_Streaming_Fail() + { + try + { + // One single file, should fail once the write discovers the problem + RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: false, forward_only: true); + throw new Exception("Test did not fail?"); + } + catch (NotSupportedException) + { + } + } + + public void RunSingleTest(long files, long filesize, bool set_zip64, bool forward_only, long write_chunk_size = 1024 * 1024, string filename = "zip64-test.zip") + { + ResetScratch(); + filename = Path.Combine(SCRATCH2_FILES_PATH, filename); + + if (File.Exists(filename)) + File.Delete(filename); + + if (!File.Exists(filename)) + CreateZipArchive(filename, files, filesize, write_chunk_size, set_zip64, forward_only); + + var resForward = ReadForwardOnly(filename); + if (resForward.Item1 != files) + throw new Exception($"Incorrect number of items reported: {resForward.Item1}, should have been {files}"); + + if (resForward.Item2 != files * filesize) + throw new Exception($"Incorrect combined size reported: {resForward.Item2}, should have been {files * filesize}"); + + var resArchive = ReadArchive(filename); + if (resArchive.Item1 != files) + throw new Exception($"Incorrect number of items reported: {resArchive.Item1}, should have been {files}"); + if (resArchive.Item2 != files * filesize) + throw new Exception($"Incorrect number of items reported: {resArchive.Item2}, should have been {files * filesize}"); + } + + public void CreateZipArchive(string filename, long files, long filesize, long chunksize, bool set_zip64, bool forward_only) + { + var data = new byte[chunksize]; + + // Use deflate for speed + var opts = new ZipWriterOptions(CompressionType.Deflate) { UseZip64 = set_zip64 }; + + // Use no compression to ensure we hit the limits (actually inflates a bit, but seems better than using method==Store) + var eo = new ZipWriterEntryOptions() { DeflateCompressionLevel = SharpCompress.Compressors.Deflate.CompressionLevel.None }; + + using (var zip = File.OpenWrite(filename)) + using(var st = forward_only ? (Stream)new NonSeekableStream(zip) : zip) + using (var zipWriter = (ZipWriter)WriterFactory.Open(st, ArchiveType.Zip, opts)) + { + + for (var i = 0; i < files; i++) + using (var str = zipWriter.WriteToStream(i.ToString(), eo)) + { + var left = filesize; + while (left > 0) + { + var b = (int)Math.Min(left, data.Length); + str.Write(data, 0, b); + left -= b; + } + } + } + } + + public Tuple ReadForwardOnly(string filename) + { + long count = 0; + long size = 0; + Common.Zip.ZipEntry prev = null; + using (var fs = File.OpenRead(filename)) + using (var rd = ZipReader.Open(fs, new ReaderOptions() { LookForHeader = false })) + while (rd.MoveToNextEntry()) + { + using (rd.OpenEntryStream()) + { } + + count++; + if (prev != null) + size += prev.Size; + + prev = rd.Entry; + } + + if (prev != null) + size += prev.Size; + + return new Tuple(count, size); + } + + public Tuple ReadArchive(string filename) + { + using (var archive = ArchiveFactory.Open(filename)) + { + return new Tuple( + archive.Entries.Count(), + archive.Entries.Select(x => x.Size).Sum() + ); + } + } + + /// + /// Helper to create non-seekable streams from filestream + /// + private class NonSeekableStream : Stream + { + private readonly Stream stream; + public NonSeekableStream(Stream s) { stream = s; } + public override bool CanRead { get { return stream.CanRead; } } + public override bool CanSeek { get { return false; } } + public override bool CanWrite { get { return stream.CanWrite; } } + public override long Length { get { throw new NotImplementedException(); } } + public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } + public override void Flush() { stream.Flush(); } + + public override int Read(byte[] buffer, int offset, int count) + { return stream.Read(buffer, offset, count); } + + public override long Seek(long offset, SeekOrigin origin) + { throw new NotImplementedException(); } + + public override void SetLength(long value) + { throw new NotImplementedException(); } + + public override void Write(byte[] buffer, int offset, int count) + { stream.Write(buffer, offset, count); } + } + } +} \ No newline at end of file From 726b9c80f6cfed1d677b602209860b076f450d8a Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Sat, 11 Mar 2017 01:05:58 +0100 Subject: [PATCH 06/49] Fixed compiling the unittest --- test/SharpCompress.Test/Zip/Zip64Tests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/SharpCompress.Test/Zip/Zip64Tests.cs b/test/SharpCompress.Test/Zip/Zip64Tests.cs index fb39468d..4a4bf639 100644 --- a/test/SharpCompress.Test/Zip/Zip64Tests.cs +++ b/test/SharpCompress.Test/Zip/Zip64Tests.cs @@ -13,8 +13,13 @@ namespace SharpCompress.Test { public class Zip64Tests : WriterTests { - // 4GiB + 1 - const long FOUR_GB_LIMIT = ((long)uint.MaxValue) + 1; + public Zip64Tests() + : base(ArchiveType.Zip) + { + } + + // 4GiB + 1 + const long FOUR_GB_LIMIT = ((long)uint.MaxValue) + 1; [Fact] public void Zip64_Single_Large_File() From 99d6062376b402ee40854aeb5b48d36f5a9dda46 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 16 Mar 2017 15:55:20 -0700 Subject: [PATCH 07/49] Removed restriction on 7zip file entries --- src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs index e8aac7b7..0aaa9cf5 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs @@ -106,10 +106,7 @@ namespace SharpCompress.Archives.SevenZip for (int i = 0; i < database.Files.Count; i++) { var file = database.Files[i]; - if (!file.IsDir) - { - yield return new SevenZipArchiveEntry(this, new SevenZipFilePart(stream, database, i, file)); - } + yield return new SevenZipArchiveEntry(this, new SevenZipFilePart(stream, database, i, file)); } } @@ -209,4 +206,4 @@ namespace SharpCompress.Archives.SevenZip } } } -} \ No newline at end of file +} From 97d5e0aac40334213c3a5619fee9470cebb01b0b Mon Sep 17 00:00:00 2001 From: Brien Oberstein Date: Tue, 4 Apr 2017 12:20:06 -0400 Subject: [PATCH 08/49] verify rar CRC on header and file data --- .../Common/Rar/Headers/RarHeader.cs | 32 ++++++++++---- .../Common/Rar/Headers/RarHeaderFactory.cs | 4 +- .../Common/Rar/RarCrcBinaryReader.cs | 40 ++++++++++++++++++ .../Common/Rar/RarCryptoBinaryReader.cs | 27 ++++++++++-- .../Rar/MultiVolumeReadOnlyStream.cs | 5 +++ src/SharpCompress/Compressors/Rar/RarCRC.cs | 4 ++ .../Compressors/Rar/RarCrcStream.cs | 42 +++++++++++++++++++ src/SharpCompress/IO/MarkingBinaryReader.cs | 4 +- src/SharpCompress/Readers/Rar/RarReader.cs | 4 +- 9 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs create mode 100644 src/SharpCompress/Compressors/Rar/RarCrcStream.cs diff --git a/src/SharpCompress/Common/Rar/Headers/RarHeader.cs b/src/SharpCompress/Common/Rar/Headers/RarHeader.cs index ecfaad65..02658389 100644 --- a/src/SharpCompress/Common/Rar/Headers/RarHeader.cs +++ b/src/SharpCompress/Common/Rar/Headers/RarHeader.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using SharpCompress.IO; namespace SharpCompress.Common.Rar.Headers @@ -18,14 +19,14 @@ namespace SharpCompress.Common.Rar.Headers ReadBytes = baseHeader.ReadBytes; } - internal static RarHeader Create(MarkingBinaryReader reader) + internal static RarHeader Create(RarCrcBinaryReader reader) { try { RarHeader header = new RarHeader(); reader.Mark(); - header.ReadFromReader(reader); + header.ReadStartFromReader(reader); header.ReadBytes += reader.CurrentReadByteCount; return header; @@ -36,9 +37,10 @@ namespace SharpCompress.Common.Rar.Headers } } - protected virtual void ReadFromReader(MarkingBinaryReader reader) + private void ReadStartFromReader(RarCrcBinaryReader reader) { - HeadCRC = reader.ReadInt16(); + HeadCRC = reader.ReadUInt16(); + reader.ResetCrc(); HeaderType = (HeaderType)(reader.ReadByte() & 0xff); Flags = reader.ReadInt16(); HeaderSize = reader.ReadInt16(); @@ -48,7 +50,11 @@ namespace SharpCompress.Common.Rar.Headers } } - internal T PromoteHeader(MarkingBinaryReader reader) + protected virtual void ReadFromReader(MarkingBinaryReader reader) { + throw new NotImplementedException(); + } + + internal T PromoteHeader(RarCrcBinaryReader reader) where T : RarHeader, new() { T header = new T(); @@ -65,9 +71,21 @@ namespace SharpCompress.Common.Rar.Headers reader.ReadBytes(headerSizeDiff); } + VerifyHeaderCrc(reader.GetCrc()); + return header; } + private void VerifyHeaderCrc(ushort crc) { + if (HeaderType != HeaderType.MarkHeader) + { + if (crc != HeadCRC) + { + throw new InvalidFormatException("rar header crc mismatch"); + } + } + } + protected virtual void PostReadingBytes(MarkingBinaryReader reader) { } @@ -77,7 +95,7 @@ namespace SharpCompress.Common.Rar.Headers /// protected long ReadBytes { get; private set; } - protected short HeadCRC { get; private set; } + protected ushort HeadCRC { get; private set; } internal HeaderType HeaderType { get; private set; } diff --git a/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs b/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs index 8d9f2412..13e02722 100644 --- a/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs +++ b/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs @@ -129,7 +129,7 @@ namespace SharpCompress.Common.Rar.Headers reader.InitializeAes(salt); } #else - var reader = new MarkingBinaryReader(stream); + var reader = new RarCrcBinaryReader(stream); #endif @@ -247,4 +247,4 @@ namespace SharpCompress.Common.Rar.Headers } } } -} \ No newline at end of file +} diff --git a/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs b/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs new file mode 100644 index 00000000..fe15e517 --- /dev/null +++ b/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs @@ -0,0 +1,40 @@ +using System.IO; +using SharpCompress.Compressors.Rar; +using SharpCompress.IO; + +namespace SharpCompress.Common.Rar { + internal class RarCrcBinaryReader : MarkingBinaryReader { + private uint currentCrc; + + public RarCrcBinaryReader(Stream stream) : base(stream) + { + } + + public ushort GetCrc() + { + return (ushort)~this.currentCrc; + } + + public void ResetCrc() + { + this.currentCrc = 0xffffffff; + } + + protected void UpdateCrc(byte b) + { + this.currentCrc = RarCRC.CheckCrc(this.currentCrc, b); + } + + protected byte[] ReadBytesNoCrc(int count) + { + return base.ReadBytes(count); + } + + public override byte[] ReadBytes(int count) + { + var result = base.ReadBytes(count); + this.currentCrc = RarCRC.CheckCrc(this.currentCrc, result, 0, result.Length); + return result; + } + } +} \ No newline at end of file diff --git a/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs b/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs index 40f64d19..9635375b 100644 --- a/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs +++ b/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs @@ -6,12 +6,13 @@ using SharpCompress.IO; namespace SharpCompress.Common.Rar { - internal class RarCryptoBinaryReader : MarkingBinaryReader + internal class RarCryptoBinaryReader : RarCrcBinaryReader { private RarRijndael rijndael; private byte[] salt; private readonly string password; private readonly Queue data = new Queue(); + private long readCount; public RarCryptoBinaryReader(Stream stream, string password ) : base(stream) @@ -19,6 +20,22 @@ namespace SharpCompress.Common.Rar this.password = password; } + // track read count ourselves rather than using the underlying stream since we buffer + public override long CurrentReadByteCount { + get + { + return this.readCount; + } + protected set + { + // ignore + } + } + + public override void Mark() { + this.readCount = 0; + } + protected bool UseEncryption { get { return salt != null; } @@ -36,6 +53,7 @@ namespace SharpCompress.Common.Rar { return ReadAndDecryptBytes(count); } + this.readCount += count; return base.ReadBytes(count); } @@ -50,7 +68,7 @@ namespace SharpCompress.Common.Rar for (int i = 0; i < alignedSize / 16; i++) { //long ax = System.currentTimeMillis(); - byte[] cipherText = base.ReadBytes(16); + byte[] cipherText = base.ReadBytesNoCrc(16); var readBytes = rijndael.ProcessBlock(cipherText); foreach (var readByte in readBytes) data.Enqueue(readByte); @@ -63,8 +81,11 @@ namespace SharpCompress.Common.Rar for (int i = 0; i < count; i++) { - decryptedBytes[i] = data.Dequeue(); + var b = data.Dequeue(); + decryptedBytes[i] = b; + UpdateCrc(b); } + this.readCount += count; return decryptedBytes; } diff --git a/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs b/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs index 5c221a4f..90a823a6 100644 --- a/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs +++ b/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs @@ -19,6 +19,7 @@ namespace SharpCompress.Compressors.Rar private long currentPartTotalReadBytes; private long currentEntryTotalReadBytes; + private uint currentCrc; internal MultiVolumeReadOnlyStream(IEnumerable parts, IExtractionListener streamListener) { @@ -59,6 +60,8 @@ namespace SharpCompress.Compressors.Rar currentPartTotalReadBytes = 0; + currentCrc = filePartEnumerator.Current.FileHeader.FileCRC; + streamListener.FireFilePartExtractionBegin(filePartEnumerator.Current.FilePartName, filePartEnumerator.Current.FileHeader.CompressedSize, filePartEnumerator.Current.FileHeader.UncompressedSize); @@ -119,6 +122,8 @@ namespace SharpCompress.Compressors.Rar public override bool CanWrite { get { return false; } } + public uint CurrentCrc { get { return this.currentCrc; } } + public override void Flush() { throw new NotSupportedException(); diff --git a/src/SharpCompress/Compressors/Rar/RarCRC.cs b/src/SharpCompress/Compressors/Rar/RarCRC.cs index 0bf20009..077b2f46 100644 --- a/src/SharpCompress/Compressors/Rar/RarCRC.cs +++ b/src/SharpCompress/Compressors/Rar/RarCRC.cs @@ -6,6 +6,10 @@ namespace SharpCompress.Compressors.Rar { private static readonly uint[] crcTab; + public static uint CheckCrc(uint startCrc, byte b) { + return (crcTab[((int) ((int) startCrc ^ (int) b)) & 0xff] ^ (startCrc >> 8)); + } + public static uint CheckCrc(uint startCrc, byte[] data, int offset, int count) { int size = Math.Min(data.Length - offset, count); diff --git a/src/SharpCompress/Compressors/Rar/RarCrcStream.cs b/src/SharpCompress/Compressors/Rar/RarCrcStream.cs new file mode 100644 index 00000000..9922d967 --- /dev/null +++ b/src/SharpCompress/Compressors/Rar/RarCrcStream.cs @@ -0,0 +1,42 @@ +using System.IO; +using SharpCompress.Common; +using SharpCompress.Common.Rar.Headers; + +namespace SharpCompress.Compressors.Rar { + internal class RarCrcStream : RarStream { + private readonly MultiVolumeReadOnlyStream readStream; + private uint currentCrc; + + public RarCrcStream(Unpack unpack, FileHeader fileHeader, MultiVolumeReadOnlyStream readStream) : base(unpack, fileHeader, readStream) + { + this.readStream = readStream; + ResetCrc(); + } + + public uint GetCrc() + { + return ~this.currentCrc; + } + + public void ResetCrc() + { + this.currentCrc = 0xffffffff; + } + + + public override int Read(byte[] buffer, int offset, int count) + { + var result = base.Read(buffer, offset, count); + if (result != 0) + { + this.currentCrc = RarCRC.CheckCrc(this.currentCrc, buffer, offset, result); + } + else if (GetCrc() != this.readStream.CurrentCrc) + { + // NOTE: we use the last FileHeader in a multipart volume to check CRC + throw new InvalidFormatException("file crc mismatch"); + } + return result; + } + } +} \ No newline at end of file diff --git a/src/SharpCompress/IO/MarkingBinaryReader.cs b/src/SharpCompress/IO/MarkingBinaryReader.cs index 6732b9c0..aa7c820b 100644 --- a/src/SharpCompress/IO/MarkingBinaryReader.cs +++ b/src/SharpCompress/IO/MarkingBinaryReader.cs @@ -12,9 +12,9 @@ namespace SharpCompress.IO { } - public long CurrentReadByteCount { get; private set; } + public virtual long CurrentReadByteCount { get; protected set; } - public void Mark() + public virtual void Mark() { CurrentReadByteCount = 0; } diff --git a/src/SharpCompress/Readers/Rar/RarReader.cs b/src/SharpCompress/Readers/Rar/RarReader.cs index 5c1f59d0..5ac7d2e2 100644 --- a/src/SharpCompress/Readers/Rar/RarReader.cs +++ b/src/SharpCompress/Readers/Rar/RarReader.cs @@ -69,9 +69,9 @@ namespace SharpCompress.Readers.Rar protected override EntryStream GetEntryStream() { - return CreateEntryStream(new RarStream(pack, Entry.FileHeader, + return CreateEntryStream(new RarCrcStream(pack, Entry.FileHeader, new MultiVolumeReadOnlyStream( CreateFilePartEnumerableForCurrentEntry().Cast(), this))); } } -} \ No newline at end of file +} From 467fc2d03dc4f0710761d17e6728c68b73b65d79 Mon Sep 17 00:00:00 2001 From: Anders Gardebring Date: Thu, 20 Apr 2017 11:45:53 +0200 Subject: [PATCH 09/49] Add new feature to allow injection of an action into the extraction process. This allows for showing or logging progress of the extraction process, especially useful for large files that might take a long time to extract. --- .../Archives/IArchiveEntryExtensions.cs | 7 ++++--- src/SharpCompress/Readers/AbstractReader.cs | 11 +++++----- src/SharpCompress/Readers/IReader.cs | 3 ++- .../Readers/IReaderExtensions.cs | 21 +++++++++++++------ src/SharpCompress/Utility.cs | 5 ++++- src/SharpCompress/Writers/AbstractWriter.cs | 2 +- src/SharpCompress/Writers/GZip/GZipWriter.cs | 4 ++-- src/SharpCompress/Writers/IWriter.cs | 2 +- src/SharpCompress/Writers/Tar/TarWriter.cs | 8 +++---- src/SharpCompress/Writers/Zip/ZipWriter.cs | 8 +++---- 10 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs index f4f8cb6b..878ad797 100644 --- a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs +++ b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using SharpCompress.Common; using SharpCompress.IO; using SharpCompress.Readers; @@ -7,7 +8,7 @@ namespace SharpCompress.Archives { public static class IArchiveEntryExtensions { - public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo) + public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo, Action partTransferredAction = null) { if (archiveEntry.Archive.Type == ArchiveType.Rar && archiveEntry.Archive.IsSolid) { @@ -32,7 +33,7 @@ namespace SharpCompress.Archives { using (Stream s = new ListeningStream(streamListener, entryStream)) { - s.TransferTo(streamToWriteTo); + s.TransferTo(streamToWriteTo, partTransferredAction); } } streamListener.FireEntryExtractionEnd(archiveEntry); diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index 380e8df5..a055c17f 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -167,7 +167,7 @@ namespace SharpCompress.Readers } } - public void WriteEntryTo(Stream writableStream) + public void WriteEntryTo(Stream writableStream, Action partTransferredAction = null) { if (wroteCurrentEntry) { @@ -175,22 +175,21 @@ namespace SharpCompress.Readers } if ((writableStream == null) || (!writableStream.CanWrite)) { - throw new ArgumentNullException( - "A writable Stream was required. Use Cancel if that was intended."); + throw new ArgumentNullException("A writable Stream was required. Use Cancel if that was intended."); } var streamListener = this as IReaderExtractionListener; streamListener.FireEntryExtractionBegin(Entry); - Write(writableStream); + Write(writableStream, partTransferredAction); streamListener.FireEntryExtractionEnd(Entry); wroteCurrentEntry = true; } - internal void Write(Stream writeStream) + internal void Write(Stream writeStream, Action partTransferredAction = null) { using (Stream s = OpenEntryStream()) { - s.TransferTo(writeStream); + s.TransferTo(writeStream, partTransferredAction); } } diff --git a/src/SharpCompress/Readers/IReader.cs b/src/SharpCompress/Readers/IReader.cs index 0df03177..6b1a7818 100644 --- a/src/SharpCompress/Readers/IReader.cs +++ b/src/SharpCompress/Readers/IReader.cs @@ -20,7 +20,8 @@ namespace SharpCompress.Readers /// Decompresses the current entry to the stream. This cannot be called twice for the current entry. /// /// - void WriteEntryTo(Stream writableStream); + /// + void WriteEntryTo(Stream writableStream, Action partTransferredAction = null); bool Cancelled { get; } void Cancel(); diff --git a/src/SharpCompress/Readers/IReaderExtensions.cs b/src/SharpCompress/Readers/IReaderExtensions.cs index 4100a607..2fdeb1d9 100644 --- a/src/SharpCompress/Readers/IReaderExtensions.cs +++ b/src/SharpCompress/Readers/IReaderExtensions.cs @@ -1,4 +1,5 @@ #if !NO_FILE +using System; using System.IO; using SharpCompress.Common; #endif @@ -39,8 +40,12 @@ namespace SharpCompress.Readers /// /// Extract to specific directory, retaining filename /// - public static void WriteEntryToDirectory(this IReader reader, string destinationDirectory, - ExtractionOptions options = null) + public static void WriteEntryToDirectory( + this IReader reader, + string destinationDirectory, + ExtractionOptions options = null, + Action partTransferredAction = null + ) { string destinationFileName = string.Empty; string file = Path.GetFileName(reader.Entry.Key); @@ -66,7 +71,7 @@ namespace SharpCompress.Readers if (!reader.Entry.IsDirectory) { - reader.WriteEntryToFile(destinationFileName, options); + reader.WriteEntryToFile(destinationFileName, options, partTransferredAction); } else if (options.ExtractFullPath && !Directory.Exists(destinationFileName)) { @@ -77,8 +82,12 @@ namespace SharpCompress.Readers /// /// Extract to specific file /// - public static void WriteEntryToFile(this IReader reader, string destinationFileName, - ExtractionOptions options = null) + public static void WriteEntryToFile( + this IReader reader, + string destinationFileName, + ExtractionOptions options = null, + Action partTransferredAction = null + ) { FileMode fm = FileMode.Create; options = options ?? new ExtractionOptions() @@ -92,7 +101,7 @@ namespace SharpCompress.Readers } using (FileStream fs = File.Open(destinationFileName, fm)) { - reader.WriteEntryTo(fs); + reader.WriteEntryTo(fs, partTransferredAction); //using (Stream s = reader.OpenEntryStream()) //{ // s.TransferTo(fs); diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 451075f3..253e0e9d 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -229,15 +229,18 @@ namespace SharpCompress return DosDateToDateTime((UInt32)iTime); } - public static long TransferTo(this Stream source, Stream destination) + public static long TransferTo(this Stream source, Stream destination, Action partTransferredAction = null) { byte[] array = new byte[81920]; int count; + var iterations = 0; long total = 0; while ((count = source.Read(array, 0, array.Length)) != 0) { total += count; destination.Write(array, 0, count); + iterations++; + partTransferredAction?.Invoke(total, iterations); } return total; } diff --git a/src/SharpCompress/Writers/AbstractWriter.cs b/src/SharpCompress/Writers/AbstractWriter.cs index dde6892a..79f880b9 100644 --- a/src/SharpCompress/Writers/AbstractWriter.cs +++ b/src/SharpCompress/Writers/AbstractWriter.cs @@ -24,7 +24,7 @@ namespace SharpCompress.Writers public ArchiveType WriterType { get; } - public abstract void Write(string filename, Stream source, DateTime? modificationTime); + public abstract void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null); protected virtual void Dispose(bool isDisposing) { diff --git a/src/SharpCompress/Writers/GZip/GZipWriter.cs b/src/SharpCompress/Writers/GZip/GZipWriter.cs index d9ef3562..48b88a29 100644 --- a/src/SharpCompress/Writers/GZip/GZipWriter.cs +++ b/src/SharpCompress/Writers/GZip/GZipWriter.cs @@ -26,7 +26,7 @@ namespace SharpCompress.Writers.GZip base.Dispose(isDisposing); } - public override void Write(string filename, Stream source, DateTime? modificationTime) + public override void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null) { if (wroteToStream) { @@ -35,7 +35,7 @@ namespace SharpCompress.Writers.GZip GZipStream stream = OutputStream as GZipStream; stream.FileName = filename; stream.LastModified = modificationTime; - source.TransferTo(stream); + source.TransferTo(stream, partTransferredAction); wroteToStream = true; } } diff --git a/src/SharpCompress/Writers/IWriter.cs b/src/SharpCompress/Writers/IWriter.cs index a15225bf..d55e8b74 100644 --- a/src/SharpCompress/Writers/IWriter.cs +++ b/src/SharpCompress/Writers/IWriter.cs @@ -7,6 +7,6 @@ namespace SharpCompress.Writers public interface IWriter : IDisposable { ArchiveType WriterType { get; } - void Write(string filename, Stream source, DateTime? modificationTime); + void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null); } } \ No newline at end of file diff --git a/src/SharpCompress/Writers/Tar/TarWriter.cs b/src/SharpCompress/Writers/Tar/TarWriter.cs index 0dbdb0a2..552b0c93 100644 --- a/src/SharpCompress/Writers/Tar/TarWriter.cs +++ b/src/SharpCompress/Writers/Tar/TarWriter.cs @@ -39,9 +39,9 @@ namespace SharpCompress.Writers.Tar InitalizeStream(destination, !options.LeaveStreamOpen); } - public override void Write(string filename, Stream source, DateTime? modificationTime) + public override void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null) { - Write(filename, source, modificationTime, null); + Write(filename, source, modificationTime, null, partTransferredAction); } private string NormalizeFilename(string filename) @@ -57,7 +57,7 @@ namespace SharpCompress.Writers.Tar return filename.Trim('/'); } - public void Write(string filename, Stream source, DateTime? modificationTime, long? size) + public void Write(string filename, Stream source, DateTime? modificationTime, long? size, Action partTransferredAction = null) { if (!source.CanSeek && size == null) { @@ -71,7 +71,7 @@ namespace SharpCompress.Writers.Tar header.Name = NormalizeFilename(filename); header.Size = realSize; header.Write(OutputStream); - size = source.TransferTo(OutputStream); + size = source.TransferTo(OutputStream, partTransferredAction); PadTo512(size.Value, false); } diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index e1a001b5..96efa0b6 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -90,19 +90,19 @@ namespace SharpCompress.Writers.Zip } } - public override void Write(string entryPath, Stream source, DateTime? modificationTime) + public override void Write(string entryPath, Stream source, DateTime? modificationTime, Action partTransferredAction = null) { Write(entryPath, source, new ZipWriterEntryOptions() { ModificationDateTime = modificationTime - }); + }, partTransferredAction); } - public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions) + public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions, Action partTransferredAction = null) { using (Stream output = WriteToStream(entryPath, zipWriterEntryOptions)) { - source.TransferTo(output); + source.TransferTo(output, partTransferredAction); } } From b8ef1ecafcf61f80d08c5a4678cb4f78370b4e2c Mon Sep 17 00:00:00 2001 From: Anders Gardebring Date: Mon, 24 Apr 2017 10:22:49 +0200 Subject: [PATCH 10/49] Revert "Add new feature to allow injection of an action into the extraction process. This allows for showing or logging progress of the extraction process, especially useful for large files that might take a long time to extract." This reverts commit 467fc2d03dc4f0710761d17e6728c68b73b65d79. --- .../Archives/IArchiveEntryExtensions.cs | 7 +++---- src/SharpCompress/Readers/AbstractReader.cs | 11 +++++----- src/SharpCompress/Readers/IReader.cs | 3 +-- .../Readers/IReaderExtensions.cs | 21 ++++++------------- src/SharpCompress/Utility.cs | 5 +---- src/SharpCompress/Writers/AbstractWriter.cs | 2 +- src/SharpCompress/Writers/GZip/GZipWriter.cs | 4 ++-- src/SharpCompress/Writers/IWriter.cs | 2 +- src/SharpCompress/Writers/Tar/TarWriter.cs | 8 +++---- src/SharpCompress/Writers/Zip/ZipWriter.cs | 8 +++---- 10 files changed, 29 insertions(+), 42 deletions(-) diff --git a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs index 878ad797..f4f8cb6b 100644 --- a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs +++ b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using SharpCompress.Common; using SharpCompress.IO; using SharpCompress.Readers; @@ -8,7 +7,7 @@ namespace SharpCompress.Archives { public static class IArchiveEntryExtensions { - public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo, Action partTransferredAction = null) + public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo) { if (archiveEntry.Archive.Type == ArchiveType.Rar && archiveEntry.Archive.IsSolid) { @@ -33,7 +32,7 @@ namespace SharpCompress.Archives { using (Stream s = new ListeningStream(streamListener, entryStream)) { - s.TransferTo(streamToWriteTo, partTransferredAction); + s.TransferTo(streamToWriteTo); } } streamListener.FireEntryExtractionEnd(archiveEntry); diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index a055c17f..380e8df5 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -167,7 +167,7 @@ namespace SharpCompress.Readers } } - public void WriteEntryTo(Stream writableStream, Action partTransferredAction = null) + public void WriteEntryTo(Stream writableStream) { if (wroteCurrentEntry) { @@ -175,21 +175,22 @@ namespace SharpCompress.Readers } if ((writableStream == null) || (!writableStream.CanWrite)) { - throw new ArgumentNullException("A writable Stream was required. Use Cancel if that was intended."); + throw new ArgumentNullException( + "A writable Stream was required. Use Cancel if that was intended."); } var streamListener = this as IReaderExtractionListener; streamListener.FireEntryExtractionBegin(Entry); - Write(writableStream, partTransferredAction); + Write(writableStream); streamListener.FireEntryExtractionEnd(Entry); wroteCurrentEntry = true; } - internal void Write(Stream writeStream, Action partTransferredAction = null) + internal void Write(Stream writeStream) { using (Stream s = OpenEntryStream()) { - s.TransferTo(writeStream, partTransferredAction); + s.TransferTo(writeStream); } } diff --git a/src/SharpCompress/Readers/IReader.cs b/src/SharpCompress/Readers/IReader.cs index 6b1a7818..0df03177 100644 --- a/src/SharpCompress/Readers/IReader.cs +++ b/src/SharpCompress/Readers/IReader.cs @@ -20,8 +20,7 @@ namespace SharpCompress.Readers /// Decompresses the current entry to the stream. This cannot be called twice for the current entry. /// /// - /// - void WriteEntryTo(Stream writableStream, Action partTransferredAction = null); + void WriteEntryTo(Stream writableStream); bool Cancelled { get; } void Cancel(); diff --git a/src/SharpCompress/Readers/IReaderExtensions.cs b/src/SharpCompress/Readers/IReaderExtensions.cs index 2fdeb1d9..4100a607 100644 --- a/src/SharpCompress/Readers/IReaderExtensions.cs +++ b/src/SharpCompress/Readers/IReaderExtensions.cs @@ -1,5 +1,4 @@ #if !NO_FILE -using System; using System.IO; using SharpCompress.Common; #endif @@ -40,12 +39,8 @@ namespace SharpCompress.Readers /// /// Extract to specific directory, retaining filename /// - public static void WriteEntryToDirectory( - this IReader reader, - string destinationDirectory, - ExtractionOptions options = null, - Action partTransferredAction = null - ) + public static void WriteEntryToDirectory(this IReader reader, string destinationDirectory, + ExtractionOptions options = null) { string destinationFileName = string.Empty; string file = Path.GetFileName(reader.Entry.Key); @@ -71,7 +66,7 @@ namespace SharpCompress.Readers if (!reader.Entry.IsDirectory) { - reader.WriteEntryToFile(destinationFileName, options, partTransferredAction); + reader.WriteEntryToFile(destinationFileName, options); } else if (options.ExtractFullPath && !Directory.Exists(destinationFileName)) { @@ -82,12 +77,8 @@ namespace SharpCompress.Readers /// /// Extract to specific file /// - public static void WriteEntryToFile( - this IReader reader, - string destinationFileName, - ExtractionOptions options = null, - Action partTransferredAction = null - ) + public static void WriteEntryToFile(this IReader reader, string destinationFileName, + ExtractionOptions options = null) { FileMode fm = FileMode.Create; options = options ?? new ExtractionOptions() @@ -101,7 +92,7 @@ namespace SharpCompress.Readers } using (FileStream fs = File.Open(destinationFileName, fm)) { - reader.WriteEntryTo(fs, partTransferredAction); + reader.WriteEntryTo(fs); //using (Stream s = reader.OpenEntryStream()) //{ // s.TransferTo(fs); diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 253e0e9d..451075f3 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -229,18 +229,15 @@ namespace SharpCompress return DosDateToDateTime((UInt32)iTime); } - public static long TransferTo(this Stream source, Stream destination, Action partTransferredAction = null) + public static long TransferTo(this Stream source, Stream destination) { byte[] array = new byte[81920]; int count; - var iterations = 0; long total = 0; while ((count = source.Read(array, 0, array.Length)) != 0) { total += count; destination.Write(array, 0, count); - iterations++; - partTransferredAction?.Invoke(total, iterations); } return total; } diff --git a/src/SharpCompress/Writers/AbstractWriter.cs b/src/SharpCompress/Writers/AbstractWriter.cs index 79f880b9..dde6892a 100644 --- a/src/SharpCompress/Writers/AbstractWriter.cs +++ b/src/SharpCompress/Writers/AbstractWriter.cs @@ -24,7 +24,7 @@ namespace SharpCompress.Writers public ArchiveType WriterType { get; } - public abstract void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null); + public abstract void Write(string filename, Stream source, DateTime? modificationTime); protected virtual void Dispose(bool isDisposing) { diff --git a/src/SharpCompress/Writers/GZip/GZipWriter.cs b/src/SharpCompress/Writers/GZip/GZipWriter.cs index 48b88a29..d9ef3562 100644 --- a/src/SharpCompress/Writers/GZip/GZipWriter.cs +++ b/src/SharpCompress/Writers/GZip/GZipWriter.cs @@ -26,7 +26,7 @@ namespace SharpCompress.Writers.GZip base.Dispose(isDisposing); } - public override void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null) + public override void Write(string filename, Stream source, DateTime? modificationTime) { if (wroteToStream) { @@ -35,7 +35,7 @@ namespace SharpCompress.Writers.GZip GZipStream stream = OutputStream as GZipStream; stream.FileName = filename; stream.LastModified = modificationTime; - source.TransferTo(stream, partTransferredAction); + source.TransferTo(stream); wroteToStream = true; } } diff --git a/src/SharpCompress/Writers/IWriter.cs b/src/SharpCompress/Writers/IWriter.cs index d55e8b74..a15225bf 100644 --- a/src/SharpCompress/Writers/IWriter.cs +++ b/src/SharpCompress/Writers/IWriter.cs @@ -7,6 +7,6 @@ namespace SharpCompress.Writers public interface IWriter : IDisposable { ArchiveType WriterType { get; } - void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null); + void Write(string filename, Stream source, DateTime? modificationTime); } } \ No newline at end of file diff --git a/src/SharpCompress/Writers/Tar/TarWriter.cs b/src/SharpCompress/Writers/Tar/TarWriter.cs index 552b0c93..0dbdb0a2 100644 --- a/src/SharpCompress/Writers/Tar/TarWriter.cs +++ b/src/SharpCompress/Writers/Tar/TarWriter.cs @@ -39,9 +39,9 @@ namespace SharpCompress.Writers.Tar InitalizeStream(destination, !options.LeaveStreamOpen); } - public override void Write(string filename, Stream source, DateTime? modificationTime, Action partTransferredAction = null) + public override void Write(string filename, Stream source, DateTime? modificationTime) { - Write(filename, source, modificationTime, null, partTransferredAction); + Write(filename, source, modificationTime, null); } private string NormalizeFilename(string filename) @@ -57,7 +57,7 @@ namespace SharpCompress.Writers.Tar return filename.Trim('/'); } - public void Write(string filename, Stream source, DateTime? modificationTime, long? size, Action partTransferredAction = null) + public void Write(string filename, Stream source, DateTime? modificationTime, long? size) { if (!source.CanSeek && size == null) { @@ -71,7 +71,7 @@ namespace SharpCompress.Writers.Tar header.Name = NormalizeFilename(filename); header.Size = realSize; header.Write(OutputStream); - size = source.TransferTo(OutputStream, partTransferredAction); + size = source.TransferTo(OutputStream); PadTo512(size.Value, false); } diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index 96efa0b6..e1a001b5 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -90,19 +90,19 @@ namespace SharpCompress.Writers.Zip } } - public override void Write(string entryPath, Stream source, DateTime? modificationTime, Action partTransferredAction = null) + public override void Write(string entryPath, Stream source, DateTime? modificationTime) { Write(entryPath, source, new ZipWriterEntryOptions() { ModificationDateTime = modificationTime - }, partTransferredAction); + }); } - public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions, Action partTransferredAction = null) + public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions) { using (Stream output = WriteToStream(entryPath, zipWriterEntryOptions)) { - source.TransferTo(output, partTransferredAction); + source.TransferTo(output); } } From 683d2714d0b058b570ba4cbcda3e97c2cd4968e4 Mon Sep 17 00:00:00 2001 From: Anders Gardebring Date: Mon, 24 Apr 2017 13:50:45 +0200 Subject: [PATCH 11/49] Add new event to be able to track progress of extraction of individual entry when extracting an archive. This allows for showing or logging progress of the extraction process, especially useful for large files that might take a long time to extract. --- .../Common/ReaderExtractionEventArgs.cs | 4 +++- src/SharpCompress/Readers/AbstractReader.cs | 15 +++++++++--- src/SharpCompress/Readers/IReader.cs | 1 + .../Readers/IReaderExtractionListener.cs | 1 + src/SharpCompress/Readers/ReaderProgress.cs | 24 +++++++++++++++++++ src/SharpCompress/Utility.cs | 5 +++- 6 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/SharpCompress/Readers/ReaderProgress.cs diff --git a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs index b33b8635..fd11e894 100644 --- a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs +++ b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs @@ -4,11 +4,13 @@ namespace SharpCompress.Common { public class ReaderExtractionEventArgs : EventArgs { - internal ReaderExtractionEventArgs(T entry) + internal ReaderExtractionEventArgs(T entry, params object[] paramList) { Item = entry; + ParamList = paramList; } public T Item { get; private set; } + public object[] ParamList { get; private set; } } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index 380e8df5..85289cb4 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -19,6 +19,7 @@ namespace SharpCompress.Readers public event EventHandler> EntryExtractionBegin; public event EventHandler> EntryExtractionEnd; + public event EventHandler> EntryExtractionProgress; public event EventHandler CompressedBytesRead; public event EventHandler FilePartExtractionBegin; @@ -181,16 +182,16 @@ namespace SharpCompress.Readers var streamListener = this as IReaderExtractionListener; streamListener.FireEntryExtractionBegin(Entry); - Write(writableStream); + Write(writableStream, streamListener); streamListener.FireEntryExtractionEnd(Entry); wroteCurrentEntry = true; } - internal void Write(Stream writeStream) + internal void Write(Stream writeStream, IReaderExtractionListener streamListener) { using (Stream s = OpenEntryStream()) { - s.TransferTo(writeStream); + s.TransferTo(writeStream, (sizeTransferred, iterations) => streamListener.FireEntryExtractionProgress(Entry, sizeTransferred, iterations)); } } @@ -255,6 +256,14 @@ namespace SharpCompress.Readers } } + void IReaderExtractionListener.FireEntryExtractionProgress(Entry entry, long bytesTransferred, int iterations) + { + if (EntryExtractionProgress != null) + { + EntryExtractionProgress(this, new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations))); + } + } + void IReaderExtractionListener.FireEntryExtractionEnd(Entry entry) { if (EntryExtractionEnd != null) diff --git a/src/SharpCompress/Readers/IReader.cs b/src/SharpCompress/Readers/IReader.cs index 0df03177..1f8dbdab 100644 --- a/src/SharpCompress/Readers/IReader.cs +++ b/src/SharpCompress/Readers/IReader.cs @@ -8,6 +8,7 @@ namespace SharpCompress.Readers { event EventHandler> EntryExtractionBegin; event EventHandler> EntryExtractionEnd; + event EventHandler> EntryExtractionProgress; event EventHandler CompressedBytesRead; event EventHandler FilePartExtractionBegin; diff --git a/src/SharpCompress/Readers/IReaderExtractionListener.cs b/src/SharpCompress/Readers/IReaderExtractionListener.cs index 226b0944..e00d9801 100644 --- a/src/SharpCompress/Readers/IReaderExtractionListener.cs +++ b/src/SharpCompress/Readers/IReaderExtractionListener.cs @@ -7,5 +7,6 @@ namespace SharpCompress.Readers // void EnsureEntriesLoaded(); void FireEntryExtractionBegin(Entry entry); void FireEntryExtractionEnd(Entry entry); + void FireEntryExtractionProgress(Entry entry, long sizeTransferred, int iterations); } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/ReaderProgress.cs b/src/SharpCompress/Readers/ReaderProgress.cs new file mode 100644 index 00000000..94feb74d --- /dev/null +++ b/src/SharpCompress/Readers/ReaderProgress.cs @@ -0,0 +1,24 @@ + + +using System; +using SharpCompress.Common; + +namespace SharpCompress.Readers +{ + public class ReaderProgress + { + private readonly IEntry _entry; + public long BytesTransferred { get; private set; } + public int Iterations { get; private set; } + + public int PercentageRead => (int)Math.Round(PercentageReadExact); + public double PercentageReadExact => (float)BytesTransferred / _entry.Size * 100; + + public ReaderProgress(IEntry entry, long bytesTransferred, int iterations) + { + _entry = entry; + BytesTransferred = bytesTransferred; + Iterations = iterations; + } + } +} diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 451075f3..00952846 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -229,15 +229,18 @@ namespace SharpCompress return DosDateToDateTime((UInt32)iTime); } - public static long TransferTo(this Stream source, Stream destination) + public static long TransferTo(this Stream source, Stream destination, Action action = null) { byte[] array = new byte[81920]; int count; + var iterations = 0; long total = 0; while ((count = source.Read(array, 0, array.Length)) != 0) { total += count; destination.Write(array, 0, count); + iterations++; + action?.Invoke(total, iterations); } return total; } From e05f9843bada5fa8ef34427a1e2d98ad610ae7bc Mon Sep 17 00:00:00 2001 From: Anders Gardebring Date: Tue, 25 Apr 2017 12:36:32 +0200 Subject: [PATCH 12/49] Use strongly typed ReaderProgress instead of object[] --- src/SharpCompress/Common/ReaderExtractionEventArgs.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs index fd11e894..3b9ac17f 100644 --- a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs +++ b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs @@ -1,16 +1,17 @@ using System; +using SharpCompress.Readers; namespace SharpCompress.Common { public class ReaderExtractionEventArgs : EventArgs { - internal ReaderExtractionEventArgs(T entry, params object[] paramList) + internal ReaderExtractionEventArgs(T entry, ReaderProgress readerProgress = null) { Item = entry; - ParamList = paramList; + ReaderProgress = readerProgress; } public T Item { get; private set; } - public object[] ParamList { get; private set; } + public ReaderProgress ReaderProgress { get; private set; } } } \ No newline at end of file From 0990b06cc9eca5372d0ab03e4df45dfe4ef9921e Mon Sep 17 00:00:00 2001 From: Anders Gardebring Date: Tue, 25 Apr 2017 12:48:56 +0200 Subject: [PATCH 13/49] Create new TransferTo method and pass Entry and IReaderExtractionListener instead of passing an action lambda. --- src/SharpCompress/Readers/AbstractReader.cs | 2 +- src/SharpCompress/Utility.cs | 32 ++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index 85289cb4..ecfeeb4b 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -191,7 +191,7 @@ namespace SharpCompress.Readers { using (Stream s = OpenEntryStream()) { - s.TransferTo(writeStream, (sizeTransferred, iterations) => streamListener.FireEntryExtractionProgress(Entry, sizeTransferred, iterations)); + s.TransferTo(writeStream, Entry, streamListener); } } diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 00952846..0486a5fd 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using SharpCompress.Readers; namespace SharpCompress { @@ -229,22 +230,45 @@ namespace SharpCompress return DosDateToDateTime((UInt32)iTime); } - public static long TransferTo(this Stream source, Stream destination, Action action = null) + public static long TransferTo(this Stream source, Stream destination) { - byte[] array = new byte[81920]; + byte[] array = GetTransferByteArray(); + int count; + long total = 0; + while (ReadTransferBlock(source, array, out count)) + { + total += count; + destination.Write(array, 0, count); + } + return total; + } + + public static long TransferTo(this Stream source, Stream destination, Common.Entry entry, IReaderExtractionListener readerExtractionListener) + { + byte[] array = GetTransferByteArray(); int count; var iterations = 0; long total = 0; - while ((count = source.Read(array, 0, array.Length)) != 0) + while (ReadTransferBlock(source, array, out count)) { total += count; destination.Write(array, 0, count); iterations++; - action?.Invoke(total, iterations); + readerExtractionListener.FireEntryExtractionProgress(entry, total, iterations); } return total; } + private static bool ReadTransferBlock(Stream source, byte[] array, out int count) + { + return (count = source.Read(array, 0, array.Length)) != 0; + } + + private static byte[] GetTransferByteArray() + { + return new byte[81920]; + } + public static bool ReadFully(this Stream stream, byte[] buffer) { int total = 0; From 2aa123ccd7bc8db2c8caa6f1b5c3a4bae7f79ffc Mon Sep 17 00:00:00 2001 From: Anders Gardebring Date: Tue, 25 Apr 2017 13:21:04 +0200 Subject: [PATCH 14/49] Remove begin and end events since this can now be tracked via progress instead --- src/SharpCompress/Readers/AbstractReader.cs | 29 ++++--------------- src/SharpCompress/Readers/IReader.cs | 2 -- .../Readers/IReaderExtractionListener.cs | 3 -- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index ecfeeb4b..af0cbdeb 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -180,15 +180,13 @@ namespace SharpCompress.Readers "A writable Stream was required. Use Cancel if that was intended."); } - var streamListener = this as IReaderExtractionListener; - streamListener.FireEntryExtractionBegin(Entry); - Write(writableStream, streamListener); - streamListener.FireEntryExtractionEnd(Entry); + Write(writableStream); wroteCurrentEntry = true; } - internal void Write(Stream writeStream, IReaderExtractionListener streamListener) + internal void Write(Stream writeStream) { + var streamListener = this as IReaderExtractionListener; using (Stream s = OpenEntryStream()) { s.TransferTo(writeStream, Entry, streamListener); @@ -247,28 +245,13 @@ namespace SharpCompress.Readers }); } } - - void IReaderExtractionListener.FireEntryExtractionBegin(Entry entry) - { - if (EntryExtractionBegin != null) - { - EntryExtractionBegin(this, new ReaderExtractionEventArgs(entry)); - } - } - void IReaderExtractionListener.FireEntryExtractionProgress(Entry entry, long bytesTransferred, int iterations) { if (EntryExtractionProgress != null) { - EntryExtractionProgress(this, new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations))); - } - } - - void IReaderExtractionListener.FireEntryExtractionEnd(Entry entry) - { - if (EntryExtractionEnd != null) - { - EntryExtractionEnd(this, new ReaderExtractionEventArgs(entry)); + EntryExtractionProgress(this, + new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations)) + ); } } } diff --git a/src/SharpCompress/Readers/IReader.cs b/src/SharpCompress/Readers/IReader.cs index 1f8dbdab..db11164d 100644 --- a/src/SharpCompress/Readers/IReader.cs +++ b/src/SharpCompress/Readers/IReader.cs @@ -6,8 +6,6 @@ namespace SharpCompress.Readers { public interface IReader : IDisposable { - event EventHandler> EntryExtractionBegin; - event EventHandler> EntryExtractionEnd; event EventHandler> EntryExtractionProgress; event EventHandler CompressedBytesRead; diff --git a/src/SharpCompress/Readers/IReaderExtractionListener.cs b/src/SharpCompress/Readers/IReaderExtractionListener.cs index e00d9801..4a4adc4e 100644 --- a/src/SharpCompress/Readers/IReaderExtractionListener.cs +++ b/src/SharpCompress/Readers/IReaderExtractionListener.cs @@ -4,9 +4,6 @@ namespace SharpCompress.Readers { internal interface IReaderExtractionListener : IExtractionListener { - // void EnsureEntriesLoaded(); - void FireEntryExtractionBegin(Entry entry); - void FireEntryExtractionEnd(Entry entry); void FireEntryExtractionProgress(Entry entry, long sizeTransferred, int iterations); } } \ No newline at end of file From 65ce91ddf6003616ffc7e82e911ae1242803a0b8 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 08:46:27 +0100 Subject: [PATCH 15/49] Update. Only use net35, net standard 1.0 and net standard 1.3 --- SharpCompress.sln | 13 ++- global.json | 3 - src/SharpCompress/SharpCompress.csproj | 31 +++++++ src/SharpCompress/SharpCompress.xproj | 19 ----- src/SharpCompress/project.json | 82 ------------------- .../SharpCompress.Test.csproj | 29 +++++++ .../SharpCompress.Test.xproj | 22 ----- test/SharpCompress.Test/project.json | 24 ------ 8 files changed, 65 insertions(+), 158 deletions(-) delete mode 100644 global.json create mode 100644 src/SharpCompress/SharpCompress.csproj delete mode 100644 src/SharpCompress/SharpCompress.xproj delete mode 100644 src/SharpCompress/project.json create mode 100644 test/SharpCompress.Test/SharpCompress.Test.csproj delete mode 100644 test/SharpCompress.Test/SharpCompress.Test.xproj delete mode 100644 test/SharpCompress.Test/project.json diff --git a/SharpCompress.sln b/SharpCompress.sln index e82ccc1a..a94d8109 100644 --- a/SharpCompress.sln +++ b/SharpCompress.sln @@ -1,20 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.6 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F18F1765-4A02-42FD-9BEF-F0E2FCBD9D17}" - ProjectSection(SolutionItems) = preProject - global.json = global.json - EndProjectSection -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SharpCompress", "src\SharpCompress\SharpCompress.xproj", "{FD19DDD8-72B2-4024-8665-0D1F7A2AA998}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C5BE746-03E5-4895-9988-0B57F162F86C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0F0901FF-E8D9-426A-B5A2-17C7F47C1529}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SharpCompress.Test", "test\SharpCompress.Test\SharpCompress.Test.xproj", "{3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCompress", "src\SharpCompress\SharpCompress.csproj", "{FD19DDD8-72B2-4024-8665-0D1F7A2AA998}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCompress.Test", "test\SharpCompress.Test\SharpCompress.Test.csproj", "{3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}" ProjectSection(ProjectDependencies) = postProject {FD19DDD8-72B2-4024-8665-0D1F7A2AA998} = {FD19DDD8-72B2-4024-8665-0D1F7A2AA998} EndProjectSection diff --git a/global.json b/global.json deleted file mode 100644 index d0f936b5..00000000 --- a/global.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "projects": ["src","test"] -} diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj new file mode 100644 index 00000000..8c7be75d --- /dev/null +++ b/src/SharpCompress/SharpCompress.csproj @@ -0,0 +1,31 @@ + + + + SharpCompress - Pure C# Decompression/Compression + en-US + 0.15.2 + Adam Hathcock + net35;netstandard1.0;netstandard1.3 + true + true + SharpCompress + ../../SharpCompress.snk + true + true + SharpCompress + rar;unrar;zip;unzip;bzip2;gzip;tar;7zip + https://github.com/adamhathcock/sharpcompress + https://github.com/adamhathcock/sharpcompress/blob/master/LICENSE.txt + false + false + + + + + + + + $(DefineConstants);NO_FILE;NO_CRYPTO;SILVERLIGHT + + + diff --git a/src/SharpCompress/SharpCompress.xproj b/src/SharpCompress/SharpCompress.xproj deleted file mode 100644 index 269099f5..00000000 --- a/src/SharpCompress/SharpCompress.xproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - fd19ddd8-72b2-4024-8665-0d1f7a2aa998 - SharpCompress - .\obj - .\bin\ - v4.5.2 - - - 2.0 - - - diff --git a/src/SharpCompress/project.json b/src/SharpCompress/project.json deleted file mode 100644 index 58344cdc..00000000 --- a/src/SharpCompress/project.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "version": "0.15.2", - "title": "SharpCompress - Pure C# Decompression/Compression", - "authors": [ "Adam Hathcock" ], - "language": "en-US", - "packOptions": { - "owners": [ "Adam Hathcock" ], - "tags": [ "rar", "unrar", "zip", "unzip", "bzip2", "gzip", "tar", "7zip" ], - "projectUrl": "https://github.com/adamhathcock/sharpcompress", - "licenseUrl": "https://github.com/adamhathcock/sharpcompress/blob/master/LICENSE.txt", - "description": "SharpCompress is a compression library for .NET/Mono/Silverlight/WP7/WindowsStore that can unrar, decompress 7zip, zip/unzip, tar/untar bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented.", - "requireLicenseAcceptance": false - }, - "buildOptions": { - "warningsAsErrors": true, - "allowUnsafe": true, - "keyFile": "../../SharpCompress.snk" - }, - "frameworks": { - "net35": { - }, - "net40": { - }, - "net45": { - }, - ".NETPortable,Version=v4.0,Profile=Profile328": { - "buildOptions": { - "define": [ "NO_FILE", "NO_CRYPTO", "SILVERLIGHT" ] - }, - "frameworkAssemblies": { - "mscorlib": { "type": "build" }, - "System": { "type": "build" }, - "System.Core": { "type": "build" } - } - }, - ".NETPortable,Version=v4.5,Profile=Profile259": { - "buildOptions": { - "define": [ "NO_FILE", "NO_CRYPTO", "SILVERLIGHT" ] - }, - "frameworkAssemblies": { - "System": { "type": "build" }, - "System.Collections": { "type": "build" }, - "System.Core": { "type": "build" }, - "System.Diagnostics.Debug": { "type": "build" }, - "System.IO": { "type": "build" }, - "System.Linq": { "type": "build" }, - "System.Linq.Expressions": { "type": "build" }, - "System.Resources.ResourceManager": { "type": "build" }, - "System.Runtime": { "type": "build" }, - "System.Runtime.Extensions": { "type": "build" }, - "System.Text.Encoding": { "type": "build" } - } - }, - "netstandard1.0": { - "buildOptions": { - "define": [ "NO_FILE", "NO_CRYPTO" ] - }, - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.IO": "4.1.0", - "System.Linq": "4.1.0", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Text.Encoding.Extensions": "4.0.11" - } - }, - "netstandard1.3": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.IO": "4.1.0", - "System.IO.FileSystem": "4.0.1", - "System.Linq": "4.1.0", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Security.Cryptography.Algorithms": "4.2.0", - "System.Text.Encoding.Extensions": "4.0.11" - } - } - } -} diff --git a/test/SharpCompress.Test/SharpCompress.Test.csproj b/test/SharpCompress.Test/SharpCompress.Test.csproj new file mode 100644 index 00000000..fcdcb779 --- /dev/null +++ b/test/SharpCompress.Test/SharpCompress.Test.csproj @@ -0,0 +1,29 @@ + + + + netcoreapp1.0 + SharpCompress.Test + ../../SharpCompress.snk + true + true + SharpCompress.Test + true + 1.0.4 + + + + + + + + + + + + + + + + + + diff --git a/test/SharpCompress.Test/SharpCompress.Test.xproj b/test/SharpCompress.Test/SharpCompress.Test.xproj deleted file mode 100644 index 707a4032..00000000 --- a/test/SharpCompress.Test/SharpCompress.Test.xproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 3b80e585-a2f3-4666-8f69-c7ffda0dd7e5 - SharpCompress.Test - .\obj - .\bin\ - v4.5.2 - - - 2.0 - - - - - - \ No newline at end of file diff --git a/test/SharpCompress.Test/project.json b/test/SharpCompress.Test/project.json deleted file mode 100644 index 0315281d..00000000 --- a/test/SharpCompress.Test/project.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "buildOptions": { - "keyFile": "../../SharpCompress.snk" - }, - - "testRunner": "xunit", - - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.1" - } - } - } - }, - "dependencies": { - "Microsoft.Extensions.PlatformAbstractions": "1.0.0", - "SharpCompress": { "target" : "project"}, - "xunit": "2.2.0-beta2-build3300", - "dotnet-test-xunit": "2.2.0-preview2-build1029" - } -} From 8dd1dbab5fd7f391167f3d3425dcafc6a54696f5 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 08:47:17 +0100 Subject: [PATCH 16/49] =?UTF-8?q?Remove=20Cake=20as=20it=E2=80=99s=20unnec?= =?UTF-8?q?essary=20for=20basic=20build/test/publish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 35 +++++--- build.cake | 229 --------------------------------------------------- build.ps1 | 130 ----------------------------- 3 files changed, 24 insertions(+), 370 deletions(-) delete mode 100644 build.cake delete mode 100644 build.ps1 diff --git a/appveyor.yml b/appveyor.yml index 058121f1..7771ef55 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,17 +1,30 @@ -version: '0.15.{build}' +version: '{build}' +image: Visual Studio 2017 -init: -- git config --global core.autocrlf true +pull_requests: + do_not_increment_build_number: true -build_script: -- ps: .\build.ps1 +branches: + only: + - master -test: off +nuget: + disable_publish_on_pr: true -cache: -- tools -> build.cake -- tools -> build.ps1 +before_build: + - cmd: dotnet restore + +after_build: +- dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release + +test_script: +- dotnet test "test\SharpCompress" -c Release artifacts: -- path: nupkgs\*.nupkg - name: NuPkgs \ No newline at end of file +- path: src\SharpCompress\bin\Release\*.nupkg + +deploy: + - provider: Environment + name: nuget.org + on: + branch: master \ No newline at end of file diff --git a/build.cake b/build.cake deleted file mode 100644 index 0977c35a..00000000 --- a/build.cake +++ /dev/null @@ -1,229 +0,0 @@ -#addin "Cake.Json" - -#addin "nuget:?package=NuGet.Core" - -using NuGet; - - -////////////////////////////////////////////////////////////////////// -// ARGUMENTS -////////////////////////////////////////////////////////////////////// - -var target = Argument("target", "Default"); -var apiKey = Argument("apiKey", ""); -var repo = Argument("repo", ""); - -////////////////////////////////////////////////////////////////////// -// PREPARATION -////////////////////////////////////////////////////////////////////// - -var sources = new [] { "https://api.nuget.org/v3/index.json" }; -var publishTarget = ""; - -Warning("============="); -var globalPath = MakeFullPath("global.json"); -var nupkgs = MakeFullPath("nupkgs"); -Warning("Operating on global.json: " + globalPath); -Warning("============="); - -////////////////////////////////////////////////////////////////////// -// FUNCTIONS -////////////////////////////////////////////////////////////////////// - -string MakeFullPath(string relativePath) -{ - if (string.IsNullOrEmpty(repo)) - { - return MakeAbsolute(new DirectoryPath(relativePath)).ToString(); - } - if (!System.IO.Path.IsPathRooted(repo)) - { - return MakeAbsolute(new DirectoryPath(System.IO.Path.Combine(repo,relativePath))).ToString(); - } - return System.IO.Path.Combine(repo, relativePath); -} - -IEnumerable GetAllProjects() -{ - var global = DeserializeJsonFromFile(globalPath); - var projs = global["projects"].Select(x => x.ToString()); - foreach(var y in projs) - { - yield return MakeFullPath(y); - } -} - -IEnumerable GetSourceProjects() -{ - return GetAllProjects().Where(x => x.EndsWith("src")); -} - -IEnumerable GetTestProjects() -{ - return GetAllProjects().Where(x => x.EndsWith("test")); -} - -IEnumerable GetFrameworks(string path) -{ - var projectJObject = DeserializeJsonFromFile(path); - foreach(var prop in ((JObject)projectJObject["frameworks"]).Properties()) - { - yield return prop.Name; - } -} - -string GetVersion(string path) -{ - var projectJObject = DeserializeJsonFromFile(path); - return ((JToken)projectJObject["version"]).ToString(); -} - -IEnumerable GetProjectJsons(IEnumerable projects) -{ - foreach(var proj in projects) - { - foreach(var projectJson in GetFiles(proj + "/**/project.json")) - { - yield return MakeFullPath(projectJson.ToString()); - } - } -} - -bool IsNuGetPublished (FilePath file, string nugetSource) -{ - var pkg = new ZipPackage(file.ToString()); - - var repo = PackageRepositoryFactory.Default.CreateRepository(nugetSource); - - var packages = repo.FindPackagesById(pkg.Id); - - var version = SemanticVersion.Parse(pkg.Version.ToString()); - - //Filter the list of packages that are not Release (Stable) versions - var exists = packages.Any (p => p.Version == version); - - return exists; -} - -////////////////////////////////////////////////////////////////////// -// TASKS -////////////////////////////////////////////////////////////////////// - -Task("Restore") - .Does(() => -{ - var settings = new DotNetCoreRestoreSettings - { - Sources = sources, - NoCache = true - }; - - foreach(var project in GetProjectJsons(GetSourceProjects().Concat(GetTestProjects()))) - { - DotNetCoreRestore(project, settings); - } -}); - -Task("Build") - .Does(() => -{ - var settings = new DotNetCoreBuildSettings - { - Configuration = "Release" - }; - - foreach(var project in GetProjectJsons(GetSourceProjects().Concat(GetTestProjects()))) - { - foreach(var framework in GetFrameworks(project)) - { - Information("Building: {0} on Framework: {1}", project, framework); - Information("========"); - settings.Framework = framework; - DotNetCoreBuild(project, settings); - } - } -}); - -Task("Test") - .Does(() => -{ - var settings = new DotNetCoreTestSettings - { - Configuration = "Release", - Verbose = true - }; - - foreach(var project in GetProjectJsons(GetTestProjects())) - { - settings.Framework = GetFrameworks(project).First(); - DotNetCoreTest(project.ToString(), settings); - } - -}).ReportError(exception => -{ - Error(exception.ToString()); -}); - -Task("Pack") - .Does(() => -{ - if (DirectoryExists(nupkgs)) - { - DeleteDirectory(nupkgs, true); - } - CreateDirectory(nupkgs); - - var settings = new DotNetCorePackSettings - { - Configuration = "Release", - OutputDirectory = nupkgs - }; - - foreach(var project in GetProjectJsons(GetSourceProjects())) - { - DotNetCorePack(project, settings); - } -}); - -Task("Publish") - .IsDependentOn("Restore") - .IsDependentOn("Build") - .IsDependentOn("Test") - .IsDependentOn("Pack") - .Does(() => -{ - var packages = GetFiles(nupkgs + "/*.nupkg"); - foreach(var package in packages) - { - if (package.ToString().Contains("symbols")) - { - Warning("Skipping Symbols package " + package); - continue; - } - if (IsNuGetPublished(package, sources[1])) - { - throw new InvalidOperationException(package + " is already published."); - } - NuGetPush(package, new NuGetPushSettings{ - ApiKey = apiKey, - Verbosity = NuGetVerbosity.Detailed, - Source = publishTarget - }); - } -}); - -////////////////////////////////////////////////////////////////////// -// TASK TARGETS -////////////////////////////////////////////////////////////////////// - -Task("Default") - .IsDependentOn("Restore") - .IsDependentOn("Build") - .IsDependentOn("Test") - .IsDependentOn("Pack"); - -////////////////////////////////////////////////////////////////////// -// EXECUTION -////////////////////////////////////////////////////////////////////// - -RunTarget(target); \ No newline at end of file diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index 878a2dc4..00000000 --- a/build.ps1 +++ /dev/null @@ -1,130 +0,0 @@ -<# -.SYNOPSIS -This is a Powershell script to bootstrap a Cake build. -.DESCRIPTION -This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) -and execute your Cake build script with the parameters you provide. -.PARAMETER Target -The build script target to run. -.PARAMETER Configuration -The build configuration to use. -.PARAMETER Verbosity -Specifies the amount of information to be displayed. -.PARAMETER WhatIf -Performs a dry run of the build script. -No tasks will be executed. -.PARAMETER ScriptArgs -Remaining arguments are added here. -.LINK -http://cakebuild.net -#> - -[CmdletBinding()] -Param( - [string]$Script = "build.cake", - [string]$Target = "Default", - [ValidateSet("Release", "Debug")] - [string]$Configuration = "Release", - [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity = "Verbose", - [switch]$WhatIf, - [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] - [string[]]$ScriptArgs -) - -$CakeVersion = "0.16.1" -$DotNetChannel = "preview"; -$DotNetVersion = "1.0.0-preview2-003131"; -$DotNetInstallerUri = "https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0-preview2/scripts/obtain/dotnet-install.ps1"; -$NugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" - -# Make sure tools folder exists -$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent -$ToolPath = Join-Path $PSScriptRoot "tools" -if (!(Test-Path $ToolPath)) { - Write-Verbose "Creating tools directory..." - New-Item -Path $ToolPath -Type directory | out-null -} - -########################################################################### -# INSTALL .NET CORE CLI -########################################################################### - -Function Remove-PathVariable([string]$VariableToRemove) -{ - $path = [Environment]::GetEnvironmentVariable("PATH", "User") - if ($path -ne $null) - { - $newItems = $path.Split(';', [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { "$($_)" -inotlike $VariableToRemove } - [Environment]::SetEnvironmentVariable("PATH", [System.String]::Join(';', $newItems), "User") - } - - $path = [Environment]::GetEnvironmentVariable("PATH", "Process") - if ($path -ne $null) - { - $newItems = $path.Split(';', [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { "$($_)" -inotlike $VariableToRemove } - [Environment]::SetEnvironmentVariable("PATH", [System.String]::Join(';', $newItems), "Process") - } -} - -# Get .NET Core CLI path if installed. -$FoundDotNetCliVersion = $null; -if (Get-Command dotnet -ErrorAction SilentlyContinue) { - $FoundDotNetCliVersion = dotnet --version; -} - -if($FoundDotNetCliVersion -ne $DotNetVersion) { - $InstallPath = Join-Path $PSScriptRoot ".dotnet" - if (!(Test-Path $InstallPath)) { - mkdir -Force $InstallPath | Out-Null; - } - (New-Object System.Net.WebClient).DownloadFile($DotNetInstallerUri, "$InstallPath\dotnet-install.ps1"); - & $InstallPath\dotnet-install.ps1 -Channel $DotNetChannel -Version $DotNetVersion -InstallDir $InstallPath; - - Remove-PathVariable "$InstallPath" - $env:PATH = "$InstallPath;$env:PATH" - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - $env:DOTNET_CLI_TELEMETRY_OPTOUT=1 -} - -########################################################################### -# INSTALL NUGET -########################################################################### - -# Make sure nuget.exe exists. -$NugetPath = Join-Path $ToolPath "nuget.exe" -if (!(Test-Path $NugetPath)) { - Write-Host "Downloading NuGet.exe..." - (New-Object System.Net.WebClient).DownloadFile($NugetUrl, $NugetPath); -} - -########################################################################### -# INSTALL CAKE -########################################################################### - -# Make sure Cake has been installed. -$CakePath = Join-Path $ToolPath "Cake.$CakeVersion/Cake.exe" -if (!(Test-Path $CakePath)) { - Write-Host "Installing Cake..." - Invoke-Expression "&`"$NugetPath`" install Cake -Version $CakeVersion -OutputDirectory `"$ToolPath`"" | Out-Null; - if ($LASTEXITCODE -ne 0) { - Throw "An error occured while restoring Cake from NuGet." - } -} - -########################################################################### -# RUN BUILD SCRIPT -########################################################################### - -# Build the argument list. -$Arguments = @{ - target=$Target; - configuration=$Configuration; - verbosity=$Verbosity; - dryrun=$WhatIf; -}.GetEnumerator() | %{"--{0}=`"{1}`"" -f $_.key, $_.value }; - -# Start Cake -Write-Host "Running build script..." -Invoke-Expression "& `"$CakePath`" `"$Script`" $Arguments $ScriptArgs" -exit $LASTEXITCODE \ No newline at end of file From 15e821aa39e347b889b2aaa6b8450b9a9cda1342 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 08:49:44 +0100 Subject: [PATCH 17/49] Remove unused events --- src/SharpCompress/Readers/AbstractReader.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index af0cbdeb..fd513d26 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -16,9 +16,7 @@ namespace SharpCompress.Readers private bool completed; private IEnumerator entriesForCurrentReadStream; private bool wroteCurrentEntry; - - public event EventHandler> EntryExtractionBegin; - public event EventHandler> EntryExtractionEnd; + public event EventHandler> EntryExtractionProgress; public event EventHandler CompressedBytesRead; From e3514c5c4b6bc4c33a701bb3a9e84cb4b360bd37 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:06:18 +0100 Subject: [PATCH 18/49] =?UTF-8?q?Don=E2=80=99t=20attempt=20to=20autodeploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7771ef55..d9991988 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,10 +21,4 @@ test_script: - dotnet test "test\SharpCompress" -c Release artifacts: -- path: src\SharpCompress\bin\Release\*.nupkg - -deploy: - - provider: Environment - name: nuget.org - on: - branch: master \ No newline at end of file +- path: src\SharpCompress\bin\Release\*.nupkg \ No newline at end of file From 3f7d0f5b68ed8d16c96af70e0db433b46af235c4 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:14:43 +0100 Subject: [PATCH 19/49] Update test project --- test/SharpCompress.Test/SharpCompress.Test.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/SharpCompress.Test/SharpCompress.Test.csproj b/test/SharpCompress.Test/SharpCompress.Test.csproj index fcdcb779..32fb65df 100644 --- a/test/SharpCompress.Test/SharpCompress.Test.csproj +++ b/test/SharpCompress.Test/SharpCompress.Test.csproj @@ -1,14 +1,14 @@  - netcoreapp1.0 + netcoreapp1.1 SharpCompress.Test ../../SharpCompress.snk true true SharpCompress.Test true - 1.0.4 + 1.1.2 @@ -18,7 +18,7 @@ - + From ee646707551388cec37acd2dc38da32d65b805e9 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:19:37 +0100 Subject: [PATCH 20/49] Move test folder to be tests --- SharpCompress.sln | 17 +++++++---------- {test => tests}/SharpCompress.Test/ADCTest.cs | 0 .../SharpCompress.Test/ArchiveTests.cs | 0 .../SharpCompress.Test/ForwardOnlyStream.cs | 0 .../GZip/GZipArchiveTests.cs | 0 .../SharpCompress.Test/GZip/GZipWriterTests.cs | 0 .../SharpCompress.Test/Rar/RarArchiveTests.cs | 0 .../Rar/RarHeaderFactoryTest.cs | 0 .../SharpCompress.Test/Rar/RarReaderTests.cs | 0 .../SharpCompress.Test/ReaderTests.cs | 0 .../SharpCompress.Test/RewindableStreamTest.cs | 0 .../SevenZip/SevenZipArchiveTests.cs | 0 .../SharpCompress.Test.csproj | 0 .../SharpCompress.Test/Streams/StreamTests.cs | 0 .../SharpCompress.Test/Tar/TarArchiveTests.cs | 0 .../SharpCompress.Test/Tar/TarReaderTests.cs | 0 .../SharpCompress.Test/Tar/TarWriterTests.cs | 0 {test => tests}/SharpCompress.Test/TestBase.cs | 0 .../SharpCompress.Test/TestStream.cs | 0 .../SharpCompress.Test/WriterTests.cs | 0 .../SharpCompress.Test/Zip/Zip64Tests.cs | 0 .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 0 .../SharpCompress.Test/Zip/ZipReaderTests.cs | 0 .../SharpCompress.Test/Zip/ZipWriterTests.cs | 0 .../TestArchives/Archives/7Zip.BZip2.7z | Bin .../TestArchives/Archives/7Zip.LZMA.7z | Bin .../TestArchives/Archives/7Zip.LZMA2.7z | Bin .../TestArchives/Archives/7Zip.PPMd.7z | Bin .../TestArchives/Archives/Audio_program.rar | Bin .../TestArchives/Archives/Encrypted.rar | Bin .../Archives/EncryptedParts.part01.rar | Bin .../Archives/EncryptedParts.part02.rar | Bin .../Archives/EncryptedParts.part03.rar | Bin .../Archives/EncryptedParts.part04.rar | Bin .../Archives/EncryptedParts.part05.rar | Bin .../Archives/EncryptedParts.part06.rar | Bin .../TestArchives/Archives/Original.7z.001 | Bin .../TestArchives/Archives/Original.7z.002 | Bin .../TestArchives/Archives/Original.7z.003 | Bin .../TestArchives/Archives/Original.7z.004 | Bin .../TestArchives/Archives/Original.7z.005 | Bin .../TestArchives/Archives/Original.7z.006 | Bin .../TestArchives/Archives/Original.7z.007 | Bin .../Archives/Rar.encrypted_filesAndHeader.rar | Bin .../Archives/Rar.encrypted_filesOnly.rar | Bin .../TestArchives/Archives/Rar.multi.part01.rar | Bin .../TestArchives/Archives/Rar.multi.part02.rar | Bin .../TestArchives/Archives/Rar.multi.part03.rar | Bin .../TestArchives/Archives/Rar.multi.part04.rar | Bin .../TestArchives/Archives/Rar.multi.part05.rar | Bin .../TestArchives/Archives/Rar.multi.part06.rar | Bin .../TestArchives/Archives/Rar.none.rar | Bin {test => tests}/TestArchives/Archives/Rar.rar | Bin .../TestArchives/Archives/Rar.solid.rar | Bin .../TestArchives/Archives/Rarjpeg.jpg | Bin .../TestArchives/Archives/Tar.ContainsRar.tar | Bin .../Tar.LongPathsWithLongNameExtension.tar | Bin .../TestArchives/Archives/Tar.mod.tar | Bin .../TestArchives/Archives/Tar.noEmptyDirs.tar | Bin .../Archives/Tar.noEmptyDirs.tar.bz2 | Bin {test => tests}/TestArchives/Archives/Tar.tar | Bin .../TestArchives/Archives/Tar.tar.bz2 | Bin .../TestArchives/Archives/Tar.tar.gz | Bin .../TestArchives/Archives/Tar.tar.lz | Bin .../TestArchives/Archives/Zip.bzip2.dd.zip | Bin .../Archives/Zip.bzip2.noEmptyDirs.zip | Bin .../TestArchives/Archives/Zip.bzip2.pkware.zip | Bin .../TestArchives/Archives/Zip.bzip2.zip | Bin .../Archives/Zip.deflate.WinzipAES.zip | Bin .../TestArchives/Archives/Zip.deflate.dd-.zip | Bin .../TestArchives/Archives/Zip.deflate.dd.zip | Bin .../TestArchives/Archives/Zip.deflate.mod.zip | Bin .../TestArchives/Archives/Zip.deflate.mod2.zip | Bin .../Archives/Zip.deflate.noEmptyDirs.zip | Bin .../Archives/Zip.deflate.pkware.zip | Bin .../TestArchives/Archives/Zip.deflate.zip | Bin .../Archives/Zip.lzma.WinzipAES.zip | Bin .../TestArchives/Archives/Zip.lzma.dd.zip | Bin .../Archives/Zip.lzma.noEmptyDirs.zip | Bin .../TestArchives/Archives/Zip.lzma.zip | Bin .../Archives/Zip.none.noEmptyDirs.zip | Bin .../TestArchives/Archives/Zip.none.zip | Bin .../TestArchives/Archives/Zip.ppmd.dd.zip | Bin .../Archives/Zip.ppmd.noEmptyDirs.zip | Bin .../TestArchives/Archives/Zip.ppmd.zip | Bin .../TestArchives/Archives/Zip.zip64.zip | Bin {test => tests}/TestArchives/Archives/Zip.zipx | Bin .../TestArchives/Archives/adc_compressed.bin | Bin .../TestArchives/Archives/adc_decompressed.bin | Bin .../Archives/test_invalid_exttime.rar | Bin .../Archives/ustar with long names.tar | Bin .../Archives/very long filename.tar | Bin {test => tests}/TestArchives/MiscTest/test.dat | Bin .../TestArchives/Original/exe/test.exe | Bin .../TestArchives/Original/jpg/test.jpg | Bin {test => tests}/TestArchives/Original/тест.txt | 0 .../TestArchives/SharpCompress.AES.zip | Bin .../TestArchives/SharpCompress.Encrypted.zip | Bin .../TestArchives/SharpCompress.Encrypted2.zip | Bin 99 files changed, 7 insertions(+), 10 deletions(-) rename {test => tests}/SharpCompress.Test/ADCTest.cs (100%) rename {test => tests}/SharpCompress.Test/ArchiveTests.cs (100%) rename {test => tests}/SharpCompress.Test/ForwardOnlyStream.cs (100%) rename {test => tests}/SharpCompress.Test/GZip/GZipArchiveTests.cs (100%) rename {test => tests}/SharpCompress.Test/GZip/GZipWriterTests.cs (100%) rename {test => tests}/SharpCompress.Test/Rar/RarArchiveTests.cs (100%) rename {test => tests}/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs (100%) rename {test => tests}/SharpCompress.Test/Rar/RarReaderTests.cs (100%) rename {test => tests}/SharpCompress.Test/ReaderTests.cs (100%) rename {test => tests}/SharpCompress.Test/RewindableStreamTest.cs (100%) rename {test => tests}/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs (100%) rename {test => tests}/SharpCompress.Test/SharpCompress.Test.csproj (100%) rename {test => tests}/SharpCompress.Test/Streams/StreamTests.cs (100%) rename {test => tests}/SharpCompress.Test/Tar/TarArchiveTests.cs (100%) rename {test => tests}/SharpCompress.Test/Tar/TarReaderTests.cs (100%) rename {test => tests}/SharpCompress.Test/Tar/TarWriterTests.cs (100%) rename {test => tests}/SharpCompress.Test/TestBase.cs (100%) rename {test => tests}/SharpCompress.Test/TestStream.cs (100%) rename {test => tests}/SharpCompress.Test/WriterTests.cs (100%) rename {test => tests}/SharpCompress.Test/Zip/Zip64Tests.cs (100%) rename {test => tests}/SharpCompress.Test/Zip/ZipArchiveTests.cs (100%) rename {test => tests}/SharpCompress.Test/Zip/ZipReaderTests.cs (100%) rename {test => tests}/SharpCompress.Test/Zip/ZipWriterTests.cs (100%) rename {test => tests}/TestArchives/Archives/7Zip.BZip2.7z (100%) rename {test => tests}/TestArchives/Archives/7Zip.LZMA.7z (100%) rename {test => tests}/TestArchives/Archives/7Zip.LZMA2.7z (100%) rename {test => tests}/TestArchives/Archives/7Zip.PPMd.7z (100%) rename {test => tests}/TestArchives/Archives/Audio_program.rar (100%) rename {test => tests}/TestArchives/Archives/Encrypted.rar (100%) rename {test => tests}/TestArchives/Archives/EncryptedParts.part01.rar (100%) rename {test => tests}/TestArchives/Archives/EncryptedParts.part02.rar (100%) rename {test => tests}/TestArchives/Archives/EncryptedParts.part03.rar (100%) rename {test => tests}/TestArchives/Archives/EncryptedParts.part04.rar (100%) rename {test => tests}/TestArchives/Archives/EncryptedParts.part05.rar (100%) rename {test => tests}/TestArchives/Archives/EncryptedParts.part06.rar (100%) rename {test => tests}/TestArchives/Archives/Original.7z.001 (100%) rename {test => tests}/TestArchives/Archives/Original.7z.002 (100%) rename {test => tests}/TestArchives/Archives/Original.7z.003 (100%) rename {test => tests}/TestArchives/Archives/Original.7z.004 (100%) rename {test => tests}/TestArchives/Archives/Original.7z.005 (100%) rename {test => tests}/TestArchives/Archives/Original.7z.006 (100%) rename {test => tests}/TestArchives/Archives/Original.7z.007 (100%) rename {test => tests}/TestArchives/Archives/Rar.encrypted_filesAndHeader.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.encrypted_filesOnly.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.multi.part01.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.multi.part02.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.multi.part03.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.multi.part04.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.multi.part05.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.multi.part06.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.none.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.rar (100%) rename {test => tests}/TestArchives/Archives/Rar.solid.rar (100%) rename {test => tests}/TestArchives/Archives/Rarjpeg.jpg (100%) rename {test => tests}/TestArchives/Archives/Tar.ContainsRar.tar (100%) rename {test => tests}/TestArchives/Archives/Tar.LongPathsWithLongNameExtension.tar (100%) rename {test => tests}/TestArchives/Archives/Tar.mod.tar (100%) rename {test => tests}/TestArchives/Archives/Tar.noEmptyDirs.tar (100%) rename {test => tests}/TestArchives/Archives/Tar.noEmptyDirs.tar.bz2 (100%) rename {test => tests}/TestArchives/Archives/Tar.tar (100%) rename {test => tests}/TestArchives/Archives/Tar.tar.bz2 (100%) rename {test => tests}/TestArchives/Archives/Tar.tar.gz (100%) rename {test => tests}/TestArchives/Archives/Tar.tar.lz (100%) rename {test => tests}/TestArchives/Archives/Zip.bzip2.dd.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.bzip2.noEmptyDirs.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.bzip2.pkware.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.bzip2.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.WinzipAES.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.dd-.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.dd.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.mod.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.mod2.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.noEmptyDirs.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.pkware.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.deflate.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.lzma.WinzipAES.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.lzma.dd.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.lzma.noEmptyDirs.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.lzma.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.none.noEmptyDirs.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.none.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.ppmd.dd.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.ppmd.noEmptyDirs.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.ppmd.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.zip64.zip (100%) rename {test => tests}/TestArchives/Archives/Zip.zipx (100%) rename {test => tests}/TestArchives/Archives/adc_compressed.bin (100%) rename {test => tests}/TestArchives/Archives/adc_decompressed.bin (100%) rename {test => tests}/TestArchives/Archives/test_invalid_exttime.rar (100%) rename {test => tests}/TestArchives/Archives/ustar with long names.tar (100%) rename {test => tests}/TestArchives/Archives/very long filename.tar (100%) rename {test => tests}/TestArchives/MiscTest/test.dat (100%) rename {test => tests}/TestArchives/Original/exe/test.exe (100%) rename {test => tests}/TestArchives/Original/jpg/test.jpg (100%) rename {test => tests}/TestArchives/Original/тест.txt (100%) rename {test => tests}/TestArchives/SharpCompress.AES.zip (100%) rename {test => tests}/TestArchives/SharpCompress.Encrypted.zip (100%) rename {test => tests}/TestArchives/SharpCompress.Encrypted2.zip (100%) diff --git a/SharpCompress.sln b/SharpCompress.sln index a94d8109..d6f16c37 100644 --- a/SharpCompress.sln +++ b/SharpCompress.sln @@ -7,14 +7,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C5BE746-03E5-4895-9988-0B57F162F86C}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0F0901FF-E8D9-426A-B5A2-17C7F47C1529}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0F0901FF-E8D9-426A-B5A2-17C7F47C1529}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCompress", "src\SharpCompress\SharpCompress.csproj", "{FD19DDD8-72B2-4024-8665-0D1F7A2AA998}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCompress.Test", "test\SharpCompress.Test\SharpCompress.Test.csproj", "{3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}" - ProjectSection(ProjectDependencies) = postProject - {FD19DDD8-72B2-4024-8665-0D1F7A2AA998} = {FD19DDD8-72B2-4024-8665-0D1F7A2AA998} - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCompress.Test", "tests\SharpCompress.Test\SharpCompress.Test.csproj", "{F2B1A1EB-0FA6-40D0-8908-E13247C7226F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -26,16 +23,16 @@ Global {FD19DDD8-72B2-4024-8665-0D1F7A2AA998}.Debug|Any CPU.Build.0 = Debug|Any CPU {FD19DDD8-72B2-4024-8665-0D1F7A2AA998}.Release|Any CPU.ActiveCfg = Release|Any CPU {FD19DDD8-72B2-4024-8665-0D1F7A2AA998}.Release|Any CPU.Build.0 = Release|Any CPU - {3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5}.Release|Any CPU.Build.0 = Release|Any CPU + {F2B1A1EB-0FA6-40D0-8908-E13247C7226F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2B1A1EB-0FA6-40D0-8908-E13247C7226F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2B1A1EB-0FA6-40D0-8908-E13247C7226F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2B1A1EB-0FA6-40D0-8908-E13247C7226F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {FD19DDD8-72B2-4024-8665-0D1F7A2AA998} = {3C5BE746-03E5-4895-9988-0B57F162F86C} - {3B80E585-A2F3-4666-8F69-C7FFDA0DD7E5} = {0F0901FF-E8D9-426A-B5A2-17C7F47C1529} + {F2B1A1EB-0FA6-40D0-8908-E13247C7226F} = {0F0901FF-E8D9-426A-B5A2-17C7F47C1529} EndGlobalSection EndGlobal diff --git a/test/SharpCompress.Test/ADCTest.cs b/tests/SharpCompress.Test/ADCTest.cs similarity index 100% rename from test/SharpCompress.Test/ADCTest.cs rename to tests/SharpCompress.Test/ADCTest.cs diff --git a/test/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs similarity index 100% rename from test/SharpCompress.Test/ArchiveTests.cs rename to tests/SharpCompress.Test/ArchiveTests.cs diff --git a/test/SharpCompress.Test/ForwardOnlyStream.cs b/tests/SharpCompress.Test/ForwardOnlyStream.cs similarity index 100% rename from test/SharpCompress.Test/ForwardOnlyStream.cs rename to tests/SharpCompress.Test/ForwardOnlyStream.cs diff --git a/test/SharpCompress.Test/GZip/GZipArchiveTests.cs b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs similarity index 100% rename from test/SharpCompress.Test/GZip/GZipArchiveTests.cs rename to tests/SharpCompress.Test/GZip/GZipArchiveTests.cs diff --git a/test/SharpCompress.Test/GZip/GZipWriterTests.cs b/tests/SharpCompress.Test/GZip/GZipWriterTests.cs similarity index 100% rename from test/SharpCompress.Test/GZip/GZipWriterTests.cs rename to tests/SharpCompress.Test/GZip/GZipWriterTests.cs diff --git a/test/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs similarity index 100% rename from test/SharpCompress.Test/Rar/RarArchiveTests.cs rename to tests/SharpCompress.Test/Rar/RarArchiveTests.cs diff --git a/test/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs b/tests/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs similarity index 100% rename from test/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs rename to tests/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs diff --git a/test/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs similarity index 100% rename from test/SharpCompress.Test/Rar/RarReaderTests.cs rename to tests/SharpCompress.Test/Rar/RarReaderTests.cs diff --git a/test/SharpCompress.Test/ReaderTests.cs b/tests/SharpCompress.Test/ReaderTests.cs similarity index 100% rename from test/SharpCompress.Test/ReaderTests.cs rename to tests/SharpCompress.Test/ReaderTests.cs diff --git a/test/SharpCompress.Test/RewindableStreamTest.cs b/tests/SharpCompress.Test/RewindableStreamTest.cs similarity index 100% rename from test/SharpCompress.Test/RewindableStreamTest.cs rename to tests/SharpCompress.Test/RewindableStreamTest.cs diff --git a/test/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs similarity index 100% rename from test/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs rename to tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs diff --git a/test/SharpCompress.Test/SharpCompress.Test.csproj b/tests/SharpCompress.Test/SharpCompress.Test.csproj similarity index 100% rename from test/SharpCompress.Test/SharpCompress.Test.csproj rename to tests/SharpCompress.Test/SharpCompress.Test.csproj diff --git a/test/SharpCompress.Test/Streams/StreamTests.cs b/tests/SharpCompress.Test/Streams/StreamTests.cs similarity index 100% rename from test/SharpCompress.Test/Streams/StreamTests.cs rename to tests/SharpCompress.Test/Streams/StreamTests.cs diff --git a/test/SharpCompress.Test/Tar/TarArchiveTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs similarity index 100% rename from test/SharpCompress.Test/Tar/TarArchiveTests.cs rename to tests/SharpCompress.Test/Tar/TarArchiveTests.cs diff --git a/test/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs similarity index 100% rename from test/SharpCompress.Test/Tar/TarReaderTests.cs rename to tests/SharpCompress.Test/Tar/TarReaderTests.cs diff --git a/test/SharpCompress.Test/Tar/TarWriterTests.cs b/tests/SharpCompress.Test/Tar/TarWriterTests.cs similarity index 100% rename from test/SharpCompress.Test/Tar/TarWriterTests.cs rename to tests/SharpCompress.Test/Tar/TarWriterTests.cs diff --git a/test/SharpCompress.Test/TestBase.cs b/tests/SharpCompress.Test/TestBase.cs similarity index 100% rename from test/SharpCompress.Test/TestBase.cs rename to tests/SharpCompress.Test/TestBase.cs diff --git a/test/SharpCompress.Test/TestStream.cs b/tests/SharpCompress.Test/TestStream.cs similarity index 100% rename from test/SharpCompress.Test/TestStream.cs rename to tests/SharpCompress.Test/TestStream.cs diff --git a/test/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs similarity index 100% rename from test/SharpCompress.Test/WriterTests.cs rename to tests/SharpCompress.Test/WriterTests.cs diff --git a/test/SharpCompress.Test/Zip/Zip64Tests.cs b/tests/SharpCompress.Test/Zip/Zip64Tests.cs similarity index 100% rename from test/SharpCompress.Test/Zip/Zip64Tests.cs rename to tests/SharpCompress.Test/Zip/Zip64Tests.cs diff --git a/test/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs similarity index 100% rename from test/SharpCompress.Test/Zip/ZipArchiveTests.cs rename to tests/SharpCompress.Test/Zip/ZipArchiveTests.cs diff --git a/test/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs similarity index 100% rename from test/SharpCompress.Test/Zip/ZipReaderTests.cs rename to tests/SharpCompress.Test/Zip/ZipReaderTests.cs diff --git a/test/SharpCompress.Test/Zip/ZipWriterTests.cs b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs similarity index 100% rename from test/SharpCompress.Test/Zip/ZipWriterTests.cs rename to tests/SharpCompress.Test/Zip/ZipWriterTests.cs diff --git a/test/TestArchives/Archives/7Zip.BZip2.7z b/tests/TestArchives/Archives/7Zip.BZip2.7z similarity index 100% rename from test/TestArchives/Archives/7Zip.BZip2.7z rename to tests/TestArchives/Archives/7Zip.BZip2.7z diff --git a/test/TestArchives/Archives/7Zip.LZMA.7z b/tests/TestArchives/Archives/7Zip.LZMA.7z similarity index 100% rename from test/TestArchives/Archives/7Zip.LZMA.7z rename to tests/TestArchives/Archives/7Zip.LZMA.7z diff --git a/test/TestArchives/Archives/7Zip.LZMA2.7z b/tests/TestArchives/Archives/7Zip.LZMA2.7z similarity index 100% rename from test/TestArchives/Archives/7Zip.LZMA2.7z rename to tests/TestArchives/Archives/7Zip.LZMA2.7z diff --git a/test/TestArchives/Archives/7Zip.PPMd.7z b/tests/TestArchives/Archives/7Zip.PPMd.7z similarity index 100% rename from test/TestArchives/Archives/7Zip.PPMd.7z rename to tests/TestArchives/Archives/7Zip.PPMd.7z diff --git a/test/TestArchives/Archives/Audio_program.rar b/tests/TestArchives/Archives/Audio_program.rar similarity index 100% rename from test/TestArchives/Archives/Audio_program.rar rename to tests/TestArchives/Archives/Audio_program.rar diff --git a/test/TestArchives/Archives/Encrypted.rar b/tests/TestArchives/Archives/Encrypted.rar similarity index 100% rename from test/TestArchives/Archives/Encrypted.rar rename to tests/TestArchives/Archives/Encrypted.rar diff --git a/test/TestArchives/Archives/EncryptedParts.part01.rar b/tests/TestArchives/Archives/EncryptedParts.part01.rar similarity index 100% rename from test/TestArchives/Archives/EncryptedParts.part01.rar rename to tests/TestArchives/Archives/EncryptedParts.part01.rar diff --git a/test/TestArchives/Archives/EncryptedParts.part02.rar b/tests/TestArchives/Archives/EncryptedParts.part02.rar similarity index 100% rename from test/TestArchives/Archives/EncryptedParts.part02.rar rename to tests/TestArchives/Archives/EncryptedParts.part02.rar diff --git a/test/TestArchives/Archives/EncryptedParts.part03.rar b/tests/TestArchives/Archives/EncryptedParts.part03.rar similarity index 100% rename from test/TestArchives/Archives/EncryptedParts.part03.rar rename to tests/TestArchives/Archives/EncryptedParts.part03.rar diff --git a/test/TestArchives/Archives/EncryptedParts.part04.rar b/tests/TestArchives/Archives/EncryptedParts.part04.rar similarity index 100% rename from test/TestArchives/Archives/EncryptedParts.part04.rar rename to tests/TestArchives/Archives/EncryptedParts.part04.rar diff --git a/test/TestArchives/Archives/EncryptedParts.part05.rar b/tests/TestArchives/Archives/EncryptedParts.part05.rar similarity index 100% rename from test/TestArchives/Archives/EncryptedParts.part05.rar rename to tests/TestArchives/Archives/EncryptedParts.part05.rar diff --git a/test/TestArchives/Archives/EncryptedParts.part06.rar b/tests/TestArchives/Archives/EncryptedParts.part06.rar similarity index 100% rename from test/TestArchives/Archives/EncryptedParts.part06.rar rename to tests/TestArchives/Archives/EncryptedParts.part06.rar diff --git a/test/TestArchives/Archives/Original.7z.001 b/tests/TestArchives/Archives/Original.7z.001 similarity index 100% rename from test/TestArchives/Archives/Original.7z.001 rename to tests/TestArchives/Archives/Original.7z.001 diff --git a/test/TestArchives/Archives/Original.7z.002 b/tests/TestArchives/Archives/Original.7z.002 similarity index 100% rename from test/TestArchives/Archives/Original.7z.002 rename to tests/TestArchives/Archives/Original.7z.002 diff --git a/test/TestArchives/Archives/Original.7z.003 b/tests/TestArchives/Archives/Original.7z.003 similarity index 100% rename from test/TestArchives/Archives/Original.7z.003 rename to tests/TestArchives/Archives/Original.7z.003 diff --git a/test/TestArchives/Archives/Original.7z.004 b/tests/TestArchives/Archives/Original.7z.004 similarity index 100% rename from test/TestArchives/Archives/Original.7z.004 rename to tests/TestArchives/Archives/Original.7z.004 diff --git a/test/TestArchives/Archives/Original.7z.005 b/tests/TestArchives/Archives/Original.7z.005 similarity index 100% rename from test/TestArchives/Archives/Original.7z.005 rename to tests/TestArchives/Archives/Original.7z.005 diff --git a/test/TestArchives/Archives/Original.7z.006 b/tests/TestArchives/Archives/Original.7z.006 similarity index 100% rename from test/TestArchives/Archives/Original.7z.006 rename to tests/TestArchives/Archives/Original.7z.006 diff --git a/test/TestArchives/Archives/Original.7z.007 b/tests/TestArchives/Archives/Original.7z.007 similarity index 100% rename from test/TestArchives/Archives/Original.7z.007 rename to tests/TestArchives/Archives/Original.7z.007 diff --git a/test/TestArchives/Archives/Rar.encrypted_filesAndHeader.rar b/tests/TestArchives/Archives/Rar.encrypted_filesAndHeader.rar similarity index 100% rename from test/TestArchives/Archives/Rar.encrypted_filesAndHeader.rar rename to tests/TestArchives/Archives/Rar.encrypted_filesAndHeader.rar diff --git a/test/TestArchives/Archives/Rar.encrypted_filesOnly.rar b/tests/TestArchives/Archives/Rar.encrypted_filesOnly.rar similarity index 100% rename from test/TestArchives/Archives/Rar.encrypted_filesOnly.rar rename to tests/TestArchives/Archives/Rar.encrypted_filesOnly.rar diff --git a/test/TestArchives/Archives/Rar.multi.part01.rar b/tests/TestArchives/Archives/Rar.multi.part01.rar similarity index 100% rename from test/TestArchives/Archives/Rar.multi.part01.rar rename to tests/TestArchives/Archives/Rar.multi.part01.rar diff --git a/test/TestArchives/Archives/Rar.multi.part02.rar b/tests/TestArchives/Archives/Rar.multi.part02.rar similarity index 100% rename from test/TestArchives/Archives/Rar.multi.part02.rar rename to tests/TestArchives/Archives/Rar.multi.part02.rar diff --git a/test/TestArchives/Archives/Rar.multi.part03.rar b/tests/TestArchives/Archives/Rar.multi.part03.rar similarity index 100% rename from test/TestArchives/Archives/Rar.multi.part03.rar rename to tests/TestArchives/Archives/Rar.multi.part03.rar diff --git a/test/TestArchives/Archives/Rar.multi.part04.rar b/tests/TestArchives/Archives/Rar.multi.part04.rar similarity index 100% rename from test/TestArchives/Archives/Rar.multi.part04.rar rename to tests/TestArchives/Archives/Rar.multi.part04.rar diff --git a/test/TestArchives/Archives/Rar.multi.part05.rar b/tests/TestArchives/Archives/Rar.multi.part05.rar similarity index 100% rename from test/TestArchives/Archives/Rar.multi.part05.rar rename to tests/TestArchives/Archives/Rar.multi.part05.rar diff --git a/test/TestArchives/Archives/Rar.multi.part06.rar b/tests/TestArchives/Archives/Rar.multi.part06.rar similarity index 100% rename from test/TestArchives/Archives/Rar.multi.part06.rar rename to tests/TestArchives/Archives/Rar.multi.part06.rar diff --git a/test/TestArchives/Archives/Rar.none.rar b/tests/TestArchives/Archives/Rar.none.rar similarity index 100% rename from test/TestArchives/Archives/Rar.none.rar rename to tests/TestArchives/Archives/Rar.none.rar diff --git a/test/TestArchives/Archives/Rar.rar b/tests/TestArchives/Archives/Rar.rar similarity index 100% rename from test/TestArchives/Archives/Rar.rar rename to tests/TestArchives/Archives/Rar.rar diff --git a/test/TestArchives/Archives/Rar.solid.rar b/tests/TestArchives/Archives/Rar.solid.rar similarity index 100% rename from test/TestArchives/Archives/Rar.solid.rar rename to tests/TestArchives/Archives/Rar.solid.rar diff --git a/test/TestArchives/Archives/Rarjpeg.jpg b/tests/TestArchives/Archives/Rarjpeg.jpg similarity index 100% rename from test/TestArchives/Archives/Rarjpeg.jpg rename to tests/TestArchives/Archives/Rarjpeg.jpg diff --git a/test/TestArchives/Archives/Tar.ContainsRar.tar b/tests/TestArchives/Archives/Tar.ContainsRar.tar similarity index 100% rename from test/TestArchives/Archives/Tar.ContainsRar.tar rename to tests/TestArchives/Archives/Tar.ContainsRar.tar diff --git a/test/TestArchives/Archives/Tar.LongPathsWithLongNameExtension.tar b/tests/TestArchives/Archives/Tar.LongPathsWithLongNameExtension.tar similarity index 100% rename from test/TestArchives/Archives/Tar.LongPathsWithLongNameExtension.tar rename to tests/TestArchives/Archives/Tar.LongPathsWithLongNameExtension.tar diff --git a/test/TestArchives/Archives/Tar.mod.tar b/tests/TestArchives/Archives/Tar.mod.tar similarity index 100% rename from test/TestArchives/Archives/Tar.mod.tar rename to tests/TestArchives/Archives/Tar.mod.tar diff --git a/test/TestArchives/Archives/Tar.noEmptyDirs.tar b/tests/TestArchives/Archives/Tar.noEmptyDirs.tar similarity index 100% rename from test/TestArchives/Archives/Tar.noEmptyDirs.tar rename to tests/TestArchives/Archives/Tar.noEmptyDirs.tar diff --git a/test/TestArchives/Archives/Tar.noEmptyDirs.tar.bz2 b/tests/TestArchives/Archives/Tar.noEmptyDirs.tar.bz2 similarity index 100% rename from test/TestArchives/Archives/Tar.noEmptyDirs.tar.bz2 rename to tests/TestArchives/Archives/Tar.noEmptyDirs.tar.bz2 diff --git a/test/TestArchives/Archives/Tar.tar b/tests/TestArchives/Archives/Tar.tar similarity index 100% rename from test/TestArchives/Archives/Tar.tar rename to tests/TestArchives/Archives/Tar.tar diff --git a/test/TestArchives/Archives/Tar.tar.bz2 b/tests/TestArchives/Archives/Tar.tar.bz2 similarity index 100% rename from test/TestArchives/Archives/Tar.tar.bz2 rename to tests/TestArchives/Archives/Tar.tar.bz2 diff --git a/test/TestArchives/Archives/Tar.tar.gz b/tests/TestArchives/Archives/Tar.tar.gz similarity index 100% rename from test/TestArchives/Archives/Tar.tar.gz rename to tests/TestArchives/Archives/Tar.tar.gz diff --git a/test/TestArchives/Archives/Tar.tar.lz b/tests/TestArchives/Archives/Tar.tar.lz similarity index 100% rename from test/TestArchives/Archives/Tar.tar.lz rename to tests/TestArchives/Archives/Tar.tar.lz diff --git a/test/TestArchives/Archives/Zip.bzip2.dd.zip b/tests/TestArchives/Archives/Zip.bzip2.dd.zip similarity index 100% rename from test/TestArchives/Archives/Zip.bzip2.dd.zip rename to tests/TestArchives/Archives/Zip.bzip2.dd.zip diff --git a/test/TestArchives/Archives/Zip.bzip2.noEmptyDirs.zip b/tests/TestArchives/Archives/Zip.bzip2.noEmptyDirs.zip similarity index 100% rename from test/TestArchives/Archives/Zip.bzip2.noEmptyDirs.zip rename to tests/TestArchives/Archives/Zip.bzip2.noEmptyDirs.zip diff --git a/test/TestArchives/Archives/Zip.bzip2.pkware.zip b/tests/TestArchives/Archives/Zip.bzip2.pkware.zip similarity index 100% rename from test/TestArchives/Archives/Zip.bzip2.pkware.zip rename to tests/TestArchives/Archives/Zip.bzip2.pkware.zip diff --git a/test/TestArchives/Archives/Zip.bzip2.zip b/tests/TestArchives/Archives/Zip.bzip2.zip similarity index 100% rename from test/TestArchives/Archives/Zip.bzip2.zip rename to tests/TestArchives/Archives/Zip.bzip2.zip diff --git a/test/TestArchives/Archives/Zip.deflate.WinzipAES.zip b/tests/TestArchives/Archives/Zip.deflate.WinzipAES.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.WinzipAES.zip rename to tests/TestArchives/Archives/Zip.deflate.WinzipAES.zip diff --git a/test/TestArchives/Archives/Zip.deflate.dd-.zip b/tests/TestArchives/Archives/Zip.deflate.dd-.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.dd-.zip rename to tests/TestArchives/Archives/Zip.deflate.dd-.zip diff --git a/test/TestArchives/Archives/Zip.deflate.dd.zip b/tests/TestArchives/Archives/Zip.deflate.dd.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.dd.zip rename to tests/TestArchives/Archives/Zip.deflate.dd.zip diff --git a/test/TestArchives/Archives/Zip.deflate.mod.zip b/tests/TestArchives/Archives/Zip.deflate.mod.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.mod.zip rename to tests/TestArchives/Archives/Zip.deflate.mod.zip diff --git a/test/TestArchives/Archives/Zip.deflate.mod2.zip b/tests/TestArchives/Archives/Zip.deflate.mod2.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.mod2.zip rename to tests/TestArchives/Archives/Zip.deflate.mod2.zip diff --git a/test/TestArchives/Archives/Zip.deflate.noEmptyDirs.zip b/tests/TestArchives/Archives/Zip.deflate.noEmptyDirs.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.noEmptyDirs.zip rename to tests/TestArchives/Archives/Zip.deflate.noEmptyDirs.zip diff --git a/test/TestArchives/Archives/Zip.deflate.pkware.zip b/tests/TestArchives/Archives/Zip.deflate.pkware.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.pkware.zip rename to tests/TestArchives/Archives/Zip.deflate.pkware.zip diff --git a/test/TestArchives/Archives/Zip.deflate.zip b/tests/TestArchives/Archives/Zip.deflate.zip similarity index 100% rename from test/TestArchives/Archives/Zip.deflate.zip rename to tests/TestArchives/Archives/Zip.deflate.zip diff --git a/test/TestArchives/Archives/Zip.lzma.WinzipAES.zip b/tests/TestArchives/Archives/Zip.lzma.WinzipAES.zip similarity index 100% rename from test/TestArchives/Archives/Zip.lzma.WinzipAES.zip rename to tests/TestArchives/Archives/Zip.lzma.WinzipAES.zip diff --git a/test/TestArchives/Archives/Zip.lzma.dd.zip b/tests/TestArchives/Archives/Zip.lzma.dd.zip similarity index 100% rename from test/TestArchives/Archives/Zip.lzma.dd.zip rename to tests/TestArchives/Archives/Zip.lzma.dd.zip diff --git a/test/TestArchives/Archives/Zip.lzma.noEmptyDirs.zip b/tests/TestArchives/Archives/Zip.lzma.noEmptyDirs.zip similarity index 100% rename from test/TestArchives/Archives/Zip.lzma.noEmptyDirs.zip rename to tests/TestArchives/Archives/Zip.lzma.noEmptyDirs.zip diff --git a/test/TestArchives/Archives/Zip.lzma.zip b/tests/TestArchives/Archives/Zip.lzma.zip similarity index 100% rename from test/TestArchives/Archives/Zip.lzma.zip rename to tests/TestArchives/Archives/Zip.lzma.zip diff --git a/test/TestArchives/Archives/Zip.none.noEmptyDirs.zip b/tests/TestArchives/Archives/Zip.none.noEmptyDirs.zip similarity index 100% rename from test/TestArchives/Archives/Zip.none.noEmptyDirs.zip rename to tests/TestArchives/Archives/Zip.none.noEmptyDirs.zip diff --git a/test/TestArchives/Archives/Zip.none.zip b/tests/TestArchives/Archives/Zip.none.zip similarity index 100% rename from test/TestArchives/Archives/Zip.none.zip rename to tests/TestArchives/Archives/Zip.none.zip diff --git a/test/TestArchives/Archives/Zip.ppmd.dd.zip b/tests/TestArchives/Archives/Zip.ppmd.dd.zip similarity index 100% rename from test/TestArchives/Archives/Zip.ppmd.dd.zip rename to tests/TestArchives/Archives/Zip.ppmd.dd.zip diff --git a/test/TestArchives/Archives/Zip.ppmd.noEmptyDirs.zip b/tests/TestArchives/Archives/Zip.ppmd.noEmptyDirs.zip similarity index 100% rename from test/TestArchives/Archives/Zip.ppmd.noEmptyDirs.zip rename to tests/TestArchives/Archives/Zip.ppmd.noEmptyDirs.zip diff --git a/test/TestArchives/Archives/Zip.ppmd.zip b/tests/TestArchives/Archives/Zip.ppmd.zip similarity index 100% rename from test/TestArchives/Archives/Zip.ppmd.zip rename to tests/TestArchives/Archives/Zip.ppmd.zip diff --git a/test/TestArchives/Archives/Zip.zip64.zip b/tests/TestArchives/Archives/Zip.zip64.zip similarity index 100% rename from test/TestArchives/Archives/Zip.zip64.zip rename to tests/TestArchives/Archives/Zip.zip64.zip diff --git a/test/TestArchives/Archives/Zip.zipx b/tests/TestArchives/Archives/Zip.zipx similarity index 100% rename from test/TestArchives/Archives/Zip.zipx rename to tests/TestArchives/Archives/Zip.zipx diff --git a/test/TestArchives/Archives/adc_compressed.bin b/tests/TestArchives/Archives/adc_compressed.bin similarity index 100% rename from test/TestArchives/Archives/adc_compressed.bin rename to tests/TestArchives/Archives/adc_compressed.bin diff --git a/test/TestArchives/Archives/adc_decompressed.bin b/tests/TestArchives/Archives/adc_decompressed.bin similarity index 100% rename from test/TestArchives/Archives/adc_decompressed.bin rename to tests/TestArchives/Archives/adc_decompressed.bin diff --git a/test/TestArchives/Archives/test_invalid_exttime.rar b/tests/TestArchives/Archives/test_invalid_exttime.rar similarity index 100% rename from test/TestArchives/Archives/test_invalid_exttime.rar rename to tests/TestArchives/Archives/test_invalid_exttime.rar diff --git a/test/TestArchives/Archives/ustar with long names.tar b/tests/TestArchives/Archives/ustar with long names.tar similarity index 100% rename from test/TestArchives/Archives/ustar with long names.tar rename to tests/TestArchives/Archives/ustar with long names.tar diff --git a/test/TestArchives/Archives/very long filename.tar b/tests/TestArchives/Archives/very long filename.tar similarity index 100% rename from test/TestArchives/Archives/very long filename.tar rename to tests/TestArchives/Archives/very long filename.tar diff --git a/test/TestArchives/MiscTest/test.dat b/tests/TestArchives/MiscTest/test.dat similarity index 100% rename from test/TestArchives/MiscTest/test.dat rename to tests/TestArchives/MiscTest/test.dat diff --git a/test/TestArchives/Original/exe/test.exe b/tests/TestArchives/Original/exe/test.exe similarity index 100% rename from test/TestArchives/Original/exe/test.exe rename to tests/TestArchives/Original/exe/test.exe diff --git a/test/TestArchives/Original/jpg/test.jpg b/tests/TestArchives/Original/jpg/test.jpg similarity index 100% rename from test/TestArchives/Original/jpg/test.jpg rename to tests/TestArchives/Original/jpg/test.jpg diff --git a/test/TestArchives/Original/тест.txt b/tests/TestArchives/Original/тест.txt similarity index 100% rename from test/TestArchives/Original/тест.txt rename to tests/TestArchives/Original/тест.txt diff --git a/test/TestArchives/SharpCompress.AES.zip b/tests/TestArchives/SharpCompress.AES.zip similarity index 100% rename from test/TestArchives/SharpCompress.AES.zip rename to tests/TestArchives/SharpCompress.AES.zip diff --git a/test/TestArchives/SharpCompress.Encrypted.zip b/tests/TestArchives/SharpCompress.Encrypted.zip similarity index 100% rename from test/TestArchives/SharpCompress.Encrypted.zip rename to tests/TestArchives/SharpCompress.Encrypted.zip diff --git a/test/TestArchives/SharpCompress.Encrypted2.zip b/tests/TestArchives/SharpCompress.Encrypted2.zip similarity index 100% rename from test/TestArchives/SharpCompress.Encrypted2.zip rename to tests/TestArchives/SharpCompress.Encrypted2.zip From 6e95c1d84a23e78d5ef268e01e2de9f4ecb241fd Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:34:02 +0100 Subject: [PATCH 21/49] =?UTF-8?q?Drop=20net35=20support=20as=20dot=20net?= =?UTF-8?q?=20tooling=20doesn=E2=80=99t=20support=20it=20currently?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 8 ++++++-- src/SharpCompress/SharpCompress.csproj | 6 +----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d9991988..3fb84396 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,11 +14,15 @@ nuget: before_build: - cmd: dotnet restore +build: + parallel: true + verbosity: minimal + after_build: -- dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release +- dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release --no-build test_script: -- dotnet test "test\SharpCompress" -c Release +- dotnet test "test\SharpCompress.Test" -c Release --no-build artifacts: - path: src\SharpCompress\bin\Release\*.nupkg \ No newline at end of file diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 8c7be75d..1d28a102 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -5,7 +5,7 @@ en-US 0.15.2 Adam Hathcock - net35;netstandard1.0;netstandard1.3 + netstandard1.0;netstandard1.3 true true SharpCompress @@ -20,10 +20,6 @@ false - - - - $(DefineConstants);NO_FILE;NO_CRYPTO;SILVERLIGHT From 59d7de5bfc8fa18b346aec5148a9be4f17bfb3d5 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:36:05 +0100 Subject: [PATCH 22/49] Try again appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3fb84396..7eeca442 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,7 +19,7 @@ build: verbosity: minimal after_build: -- dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release --no-build +- dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release test_script: - dotnet test "test\SharpCompress.Test" -c Release --no-build From 60e1fe86f26a526495804de64373c7b0771fefb4 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:40:37 +0100 Subject: [PATCH 23/49] Fix test running --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 7eeca442..3b4015a0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ after_build: - dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release test_script: -- dotnet test "test\SharpCompress.Test" -c Release --no-build +- dotnet test --no-build .\tests\SharpCompress.Test\SharpCompress.Test.csproj artifacts: - path: src\SharpCompress\bin\Release\*.nupkg \ No newline at end of file From f1809163c7e5dacc1976a8b3f5ea760578666daa Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 09:44:45 +0100 Subject: [PATCH 24/49] correct gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1b119084..71becff1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ TestResults/ *.nupkg packages/*/ project.lock.json -test/TestArchives/Scratch +tests/TestArchives/Scratch .vs tools .vscode From 631578c17513e60a1a72f71190307fc2c19094a8 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 10:10:23 +0100 Subject: [PATCH 25/49] Update to next version. Stop Zip64 tests from running all the time and some clean up --- src/SharpCompress/SharpCompress.csproj | 5 +- .../SharpCompress.Test/Rar/RarArchiveTests.cs | 4 +- .../SharpCompress.Test/Rar/RarReaderTests.cs | 14 ++--- .../RewindableStreamTest.cs | 58 +++++++++---------- .../SharpCompress.Test.csproj | 5 +- tests/SharpCompress.Test/Zip/Zip64Tests.cs | 28 +++++---- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 4 +- .../SharpCompress.Test/Zip/ZipReaderTests.cs | 7 +-- 8 files changed, 68 insertions(+), 57 deletions(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 1d28a102..48bf9708 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -3,7 +3,9 @@ SharpCompress - Pure C# Decompression/Compression en-US - 0.15.2 + 0.16.0 + 0.16.0.0 + 0.16.0.0 Adam Hathcock netstandard1.0;netstandard1.3 true @@ -18,6 +20,7 @@ https://github.com/adamhathcock/sharpcompress/blob/master/LICENSE.txt false false + SharpCompress is a compression library for NET Standard 1.0 that can unrar, decompress 7zip, zip/unzip, tar/untar bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented. diff --git a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs index aba37b87..fa1c399f 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs @@ -44,7 +44,7 @@ namespace SharpCompress.Test { if (!entry.IsDirectory) { - Assert.Equal(entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, entry.CompressionType); entry.WriteToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, @@ -189,7 +189,7 @@ namespace SharpCompress.Test ResetScratch(); using (var archive = RarArchive.Open(testArchives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) - .Select(p => File.OpenRead(p)))) + .Select(File.OpenRead))) { foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) { diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index 912692ec..d51366fa 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -36,7 +36,7 @@ namespace SharpCompress.Test VerifyFiles(); } - //[Fact] + [Fact] public void Rar_Multi_Reader_Encrypted() { var testArchives = new string[] { "EncryptedParts.part01.rar", @@ -149,7 +149,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, @@ -172,7 +172,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType); using (var entryStream = reader.OpenEntryStream()) { string file = Path.GetFileName(reader.Entry.Key); @@ -207,7 +207,7 @@ namespace SharpCompress.Test { while (reader.MoveToNextEntry()) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, @@ -231,7 +231,7 @@ namespace SharpCompress.Test { while (reader.MoveToNextEntry()) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, @@ -262,7 +262,7 @@ namespace SharpCompress.Test { if (reader.Entry.Key.Contains("jpg")) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, @@ -287,7 +287,7 @@ namespace SharpCompress.Test { if (reader.Entry.Key.Contains("jpg")) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Rar); + Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, diff --git a/tests/SharpCompress.Test/RewindableStreamTest.cs b/tests/SharpCompress.Test/RewindableStreamTest.cs index 991b1acf..52c58227 100644 --- a/tests/SharpCompress.Test/RewindableStreamTest.cs +++ b/tests/SharpCompress.Test/RewindableStreamTest.cs @@ -23,25 +23,25 @@ namespace SharpCompress.Test RewindableStream stream = new RewindableStream(ms); stream.StartRecording(); BinaryReader br = new BinaryReader(stream); - Assert.Equal(br.ReadInt32(), 1); - Assert.Equal(br.ReadInt32(), 2); - Assert.Equal(br.ReadInt32(), 3); - Assert.Equal(br.ReadInt32(), 4); + Assert.Equal(1, br.ReadInt32()); + Assert.Equal(2, br.ReadInt32()); + Assert.Equal(3, br.ReadInt32()); + Assert.Equal(4, br.ReadInt32()); stream.Rewind(true); stream.StartRecording(); - Assert.Equal(br.ReadInt32(), 1); - Assert.Equal(br.ReadInt32(), 2); - Assert.Equal(br.ReadInt32(), 3); - Assert.Equal(br.ReadInt32(), 4); - Assert.Equal(br.ReadInt32(), 5); - Assert.Equal(br.ReadInt32(), 6); - Assert.Equal(br.ReadInt32(), 7); + Assert.Equal(1, br.ReadInt32()); + Assert.Equal(2, br.ReadInt32()); + Assert.Equal(3, br.ReadInt32()); + Assert.Equal(4, br.ReadInt32()); + Assert.Equal(5, br.ReadInt32()); + Assert.Equal(6, br.ReadInt32()); + Assert.Equal(7, br.ReadInt32()); stream.Rewind(true); stream.StartRecording(); - Assert.Equal(br.ReadInt32(), 1); - Assert.Equal(br.ReadInt32(), 2); - Assert.Equal(br.ReadInt32(), 3); - Assert.Equal(br.ReadInt32(), 4); + Assert.Equal(1, br.ReadInt32()); + Assert.Equal(2, br.ReadInt32()); + Assert.Equal(3, br.ReadInt32()); + Assert.Equal(4, br.ReadInt32()); } [Fact] @@ -61,23 +61,23 @@ namespace SharpCompress.Test RewindableStream stream = new RewindableStream(ms); stream.StartRecording(); BinaryReader br = new BinaryReader(stream); - Assert.Equal(br.ReadInt32(), 1); - Assert.Equal(br.ReadInt32(), 2); - Assert.Equal(br.ReadInt32(), 3); - Assert.Equal(br.ReadInt32(), 4); + Assert.Equal(1, br.ReadInt32()); + Assert.Equal(2, br.ReadInt32()); + Assert.Equal(3, br.ReadInt32()); + Assert.Equal(4, br.ReadInt32()); stream.Rewind(true); - Assert.Equal(br.ReadInt32(), 1); - Assert.Equal(br.ReadInt32(), 2); + Assert.Equal(1, br.ReadInt32()); + Assert.Equal(2, br.ReadInt32()); stream.StartRecording(); - Assert.Equal(br.ReadInt32(), 3); - Assert.Equal(br.ReadInt32(), 4); - Assert.Equal(br.ReadInt32(), 5); + Assert.Equal(3, br.ReadInt32()); + Assert.Equal(4, br.ReadInt32()); + Assert.Equal(5, br.ReadInt32()); stream.Rewind(true); - Assert.Equal(br.ReadInt32(), 3); - Assert.Equal(br.ReadInt32(), 4); - Assert.Equal(br.ReadInt32(), 5); - Assert.Equal(br.ReadInt32(), 6); - Assert.Equal(br.ReadInt32(), 7); + Assert.Equal(3, br.ReadInt32()); + Assert.Equal(4, br.ReadInt32()); + Assert.Equal(5, br.ReadInt32()); + Assert.Equal(6, br.ReadInt32()); + Assert.Equal(7, br.ReadInt32()); } } } diff --git a/tests/SharpCompress.Test/SharpCompress.Test.csproj b/tests/SharpCompress.Test/SharpCompress.Test.csproj index 32fb65df..90da286c 100644 --- a/tests/SharpCompress.Test/SharpCompress.Test.csproj +++ b/tests/SharpCompress.Test/SharpCompress.Test.csproj @@ -17,9 +17,10 @@ - + - + + diff --git a/tests/SharpCompress.Test/Zip/Zip64Tests.cs b/tests/SharpCompress.Test/Zip/Zip64Tests.cs index 4a4bf639..d626ae71 100644 --- a/tests/SharpCompress.Test/Zip/Zip64Tests.cs +++ b/tests/SharpCompress.Test/Zip/Zip64Tests.cs @@ -21,42 +21,48 @@ namespace SharpCompress.Test // 4GiB + 1 const long FOUR_GB_LIMIT = ((long)uint.MaxValue) + 1; - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("format", "zip64")] public void Zip64_Single_Large_File() { // One single file, requires zip64 RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: true, forward_only: false); } - [Fact] - public void Zip64_Two_Large_Files() + [Fact(Skip = "Takes too long")] + [Trait("format", "zip64")] + public void Zip64_Two_Large_Files() { // One single file, requires zip64 RunSingleTest(2, FOUR_GB_LIMIT, set_zip64: true, forward_only: false); - } + } - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("format", "zip64")] public void Zip64_Two_Small_files() { // Multiple files, does not require zip64 RunSingleTest(2, FOUR_GB_LIMIT / 2, set_zip64: false, forward_only: false); } - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("format", "zip64")] public void Zip64_Two_Small_files_stream() { // Multiple files, does not require zip64, and works with streams RunSingleTest(2, FOUR_GB_LIMIT / 2, set_zip64: false, forward_only: true); } - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("format", "zip64")] public void Zip64_Two_Small_Files_Zip64() { // Multiple files, use zip64 even though it is not required RunSingleTest(2, FOUR_GB_LIMIT / 2, set_zip64: true, forward_only: false); } - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("format", "zip64")] public void Zip64_Single_Large_File_Fail() { try @@ -70,7 +76,8 @@ namespace SharpCompress.Test } } - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("zip64", "true")] public void Zip64_Single_Large_File_Zip64_Streaming_Fail() { try @@ -84,7 +91,8 @@ namespace SharpCompress.Test } } - [Fact] + [Fact(Skip = "Takes too long")] + [Trait("zip64", "true")] public void Zip64_Single_Large_File_Streaming_Fail() { try diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 257f6da9..d3d8832e 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -358,7 +358,7 @@ namespace SharpCompress.Test count++; //Prints 3 - Assert.Equal(count, 3); + Assert.Equal(3, count); a.Dispose(); a = ZipArchive.Open(unmodified); @@ -382,7 +382,7 @@ namespace SharpCompress.Test foreach (var e in a.Entries) count3++; - Assert.Equal(count3, 3); + Assert.Equal(3, count3); } [Fact] diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index 35db1278..8f945a9f 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -100,7 +100,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.BZip2); + Assert.Equal(CompressionType.BZip2, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true, @@ -179,8 +179,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, - CompressionType.Unknown); + Assert.Equal(CompressionType.Unknown, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { @@ -208,7 +207,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.Unknown); + Assert.Equal(CompressionType.Unknown, reader.Entry.CompressionType); reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() { From 3197ef289c6bc2687b2ce750006b139873c2006e Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 10:15:19 +0100 Subject: [PATCH 26/49] Forgot to hit save --- tests/SharpCompress.Test/Tar/TarReaderTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index 2251b0d8..5529abfd 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -50,7 +50,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.BZip2); + Assert.Equal(CompressionType.BZip2, reader.Entry.CompressionType); using (var entryStream = reader.OpenEntryStream()) { string file = Path.GetFileName(reader.Entry.Key); @@ -107,7 +107,7 @@ namespace SharpCompress.Test { if (!reader.Entry.IsDirectory) { - Assert.Equal(reader.Entry.CompressionType, CompressionType.BZip2); + Assert.Equal(CompressionType.BZip2, reader.Entry.CompressionType); using (var entryStream = reader.OpenEntryStream()) { entryStream.SkipEntry(); @@ -115,7 +115,7 @@ namespace SharpCompress.Test } } } - Assert.Equal(names.Count, 3); + Assert.Equal(3, names.Count); } } From 8be931bbcbfbdb5d4d3acb90c5f92aa0f0ae72b8 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 10:52:49 +0100 Subject: [PATCH 27/49] Doing some resharper clean up --- src/SharpCompress/Archives/AbstractArchive.cs | 34 +++++---------- .../Archives/GZip/GZipArchiveEntry.cs | 2 +- .../Archives/GZip/GZipWritableArchiveEntry.cs | 20 ++++----- src/SharpCompress/Archives/Rar/RarArchive.cs | 2 +- .../Archives/Rar/RarArchiveEntry.cs | 8 ++-- .../Archives/Rar/SeekableFilePart.cs | 2 +- .../Archives/SevenZip/SevenZipArchive.cs | 2 +- .../Archives/SevenZip/SevenZipArchiveEntry.cs | 4 +- .../Archives/Tar/TarArchiveEntry.cs | 2 +- .../Archives/Tar/TarWritableArchiveEntry.cs | 20 ++++----- .../Archives/Zip/ZipArchiveEntry.cs | 4 +- .../Archives/Zip/ZipWritableArchiveEntry.cs | 20 ++++----- src/SharpCompress/Common/Entry.cs | 2 +- src/SharpCompress/Common/EntryStream.cs | 10 ++--- src/SharpCompress/Common/GZip/GZipEntry.cs | 26 +++++------ src/SharpCompress/Common/GZip/GZipFilePart.cs | 2 +- src/SharpCompress/Common/GZip/GZipVolume.cs | 4 +- .../Common/Rar/Headers/ArchiveHeader.cs | 4 +- .../Common/Rar/Headers/EndArchiveHeader.cs | 2 +- .../Common/Rar/Headers/FileHeader.cs | 2 +- .../Common/Rar/Headers/ProtectHeader.cs | 2 +- .../Common/Rar/RarCrcBinaryReader.cs | 8 ++-- src/SharpCompress/Common/Rar/RarEntry.cs | 18 ++++---- src/SharpCompress/Common/Rar/RarVolume.cs | 2 +- .../Common/SevenZip/ArchiveReader.cs | 10 ++--- .../Common/SevenZip/CFileItem.cs | 4 +- src/SharpCompress/Common/SevenZip/CFolder.cs | 2 +- .../Common/SevenZip/SevenZipEntry.cs | 28 ++++++------ .../Common/SevenZip/SevenZipFilePart.cs | 2 +- src/SharpCompress/Common/Tar/TarEntry.cs | 24 +++++------ src/SharpCompress/Common/Tar/TarFilePart.cs | 2 +- .../Common/Tar/TarReadOnlySubStream.cs | 10 ++--- src/SharpCompress/Common/Volume.cs | 6 +-- .../Common/Zip/Headers/DirectoryEndHeader.cs | 12 ++---- .../Headers/LocalEntryHeaderExtraFactory.cs | 2 +- .../Zip/Headers/Zip64DirectoryEndHeader.cs | 2 +- .../Common/Zip/Headers/ZipFileEntry.cs | 2 +- .../Zip/PkwareTraditionalCryptoStream.cs | 10 ++--- .../Common/Zip/SeekableZipFilePart.cs | 2 +- src/SharpCompress/Common/Zip/ZipEntry.cs | 22 +++++----- src/SharpCompress/Common/Zip/ZipFilePart.cs | 4 +- .../Compressors/ADC/ADCStream.cs | 10 ++--- .../Compressors/BZip2/BZip2Stream.cs | 10 ++--- .../Compressors/BZip2/CBZip2InputStream.cs | 8 ++-- .../Compressors/BZip2/CBZip2OutputStream.cs | 8 ++-- .../Compressors/Deflate/CRC32.cs | 9 +--- .../Compressors/Deflate/DeflateStream.cs | 26 +++++------ .../Compressors/Deflate/GZipStream.cs | 18 ++++---- .../Compressors/Deflate/ZlibBaseStream.cs | 12 +++--- .../Compressors/Deflate/ZlibCodec.cs | 2 +- .../Compressors/Deflate/ZlibStream.cs | 14 +++--- .../Compressors/Filters/BCJ2Filter.cs | 10 ++--- .../Compressors/Filters/Filter.cs | 10 ++--- .../Compressors/LZMA/DecoderStream.cs | 10 ++--- .../Compressors/LZMA/LZ/LzInWindow.cs | 2 +- .../Compressors/LZMA/LZ/LzOutWindow.cs | 6 +-- .../Compressors/LZMA/LZipStream.cs | 4 +- .../Compressors/LZMA/LzmaStream.cs | 10 ++--- .../Compressors/LZMA/RangeCoder/RangeCoder.cs | 2 +- .../LZMA/Utilites/CrcBuilderStream.cs | 20 ++++----- .../LZMA/Utilites/CrcCheckStream.cs | 10 ++--- .../Compressors/PPMd/H/FreqData.cs | 2 +- .../Compressors/PPMd/H/ModelPPM.cs | 24 +++++------ .../Compressors/PPMd/H/PPMContext.cs | 5 +-- .../Compressors/PPMd/H/RangeCoder.cs | 6 +-- .../Compressors/PPMd/H/SEE2Context.cs | 6 +-- src/SharpCompress/Compressors/PPMd/H/State.cs | 4 +- .../Compressors/PPMd/H/StateRef.cs | 4 +- .../Compressors/PPMd/H/SubAllocator.cs | 10 ++--- .../Compressors/PPMd/I1/MemoryNode.cs | 26 ++++------- .../Compressors/PPMd/I1/PpmContext.cs | 42 +++++++----------- .../Compressors/PPMd/I1/PpmState.cs | 16 +++---- .../Compressors/PPMd/PpmdProperties.cs | 15 ++----- .../Compressors/PPMd/PpmdStream.cs | 10 ++--- .../Rar/MultiVolumeReadOnlyStream.cs | 15 +++---- .../Compressors/Rar/RarCrcStream.cs | 8 ++-- .../Compressors/Rar/RarStream.cs | 10 ++--- src/SharpCompress/Compressors/Rar/Unpack.cs | 4 +- src/SharpCompress/Converters/DataConverter.cs | 4 +- src/SharpCompress/Crypto/RijndaelEngine.cs | 4 +- src/SharpCompress/IO/AppendingStream.cs | 10 ++--- src/SharpCompress/IO/BufferedSubStream.cs | 10 ++--- .../IO/CountingWritableSubStream.cs | 10 ++--- src/SharpCompress/IO/ListeningStream.cs | 10 ++--- src/SharpCompress/IO/NonDisposingStream.cs | 10 ++--- src/SharpCompress/IO/ReadOnlySubStream.cs | 10 ++--- src/SharpCompress/IO/RewindableStream.cs | 6 +-- src/SharpCompress/LazyReadOnlyCollection.cs | 6 +-- src/SharpCompress/ReadOnlyCollection.cs | 4 +- src/SharpCompress/Readers/AbstractReader.cs | 35 ++++++--------- .../Readers/Rar/MultiVolumeRarReader.cs | 2 +- .../Readers/Rar/NonSeekableStreamFilePart.cs | 2 +- src/SharpCompress/Readers/Rar/RarReader.cs | 2 +- .../Readers/Rar/RarReaderEntry.cs | 10 ++--- src/SharpCompress/Writers/Zip/ZipWriter.cs | 12 +++--- tests/SharpCompress.Test/ArchiveTests.cs | 14 +++--- tests/SharpCompress.Test/ForwardOnlyStream.cs | 9 ++-- .../GZip/GZipArchiveTests.cs | 2 +- .../Rar/RarHeaderFactoryTest.cs | 2 +- .../SharpCompress.Test/Tar/TarArchiveTests.cs | 6 +-- tests/SharpCompress.Test/TestBase.cs | 2 +- tests/SharpCompress.Test/TestStream.cs | 43 ++++++------------- tests/SharpCompress.Test/WriterTests.cs | 2 +- tests/SharpCompress.Test/Zip/Zip64Tests.cs | 12 +++--- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 18 +++----- .../SharpCompress.Test/Zip/ZipReaderTests.cs | 8 +--- 106 files changed, 456 insertions(+), 563 deletions(-) diff --git a/src/SharpCompress/Archives/AbstractArchive.cs b/src/SharpCompress/Archives/AbstractArchive.cs index cc51b1c4..2981f734 100644 --- a/src/SharpCompress/Archives/AbstractArchive.cs +++ b/src/SharpCompress/Archives/AbstractArchive.cs @@ -61,18 +61,12 @@ namespace SharpCompress.Archives void IArchiveExtractionListener.FireEntryExtractionBegin(IArchiveEntry entry) { - if (EntryExtractionBegin != null) - { - EntryExtractionBegin(this, new ArchiveExtractionEventArgs(entry)); - } + EntryExtractionBegin?.Invoke(this, new ArchiveExtractionEventArgs(entry)); } void IArchiveExtractionListener.FireEntryExtractionEnd(IArchiveEntry entry) { - if (EntryExtractionEnd != null) - { - EntryExtractionEnd(this, new ArchiveExtractionEventArgs(entry)); - } + EntryExtractionEnd?.Invoke(this, new ArchiveExtractionEventArgs(entry)); } private static Stream CheckStreams(Stream stream) @@ -129,27 +123,21 @@ namespace SharpCompress.Archives void IExtractionListener.FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes) { - if (CompressedBytesRead != null) + CompressedBytesRead?.Invoke(this, new CompressedBytesReadEventArgs { - CompressedBytesRead(this, new CompressedBytesReadEventArgs - { - CurrentFilePartCompressedBytesRead = currentPartCompressedBytes, - CompressedBytesRead = compressedReadBytes - }); - } + CurrentFilePartCompressedBytesRead = currentPartCompressedBytes, + CompressedBytesRead = compressedReadBytes + }); } void IExtractionListener.FireFilePartExtractionBegin(string name, long size, long compressedSize) { - if (FilePartExtractionBegin != null) + FilePartExtractionBegin?.Invoke(this, new FilePartExtractionBeginEventArgs { - FilePartExtractionBegin(this, new FilePartExtractionBeginEventArgs - { - CompressedSize = compressedSize, - Size = size, - Name = name - }); - } + CompressedSize = compressedSize, + Size = size, + Name = name + }); } /// diff --git a/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs b/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs index cdbbc89d..7f417171 100644 --- a/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs +++ b/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs @@ -27,7 +27,7 @@ namespace SharpCompress.Archives.GZip public IArchive Archive { get; } - public bool IsComplete { get { return true; } } + public bool IsComplete => true; #endregion } diff --git a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs index 4aec0f62..852b15da 100644 --- a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs @@ -22,31 +22,31 @@ namespace SharpCompress.Archives.GZip this.closeStream = closeStream; } - public override long Crc { get { return 0; } } + public override long Crc => 0; public override string Key { get; } - public override long CompressedSize { get { return 0; } } + public override long CompressedSize => 0; public override long Size { get; } public override DateTime? LastModifiedTime { get; } - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return false; } } + public override bool IsEncrypted => false; - public override bool IsDirectory { get { return false; } } + public override bool IsDirectory => false; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - internal override IEnumerable Parts { get { throw new NotImplementedException(); } } + internal override IEnumerable Parts => throw new NotImplementedException(); - Stream IWritableArchiveEntry.Stream { get { return stream; } } + Stream IWritableArchiveEntry.Stream => stream; public override Stream OpenEntryStream() { diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs index b3f48a26..eecd27b6 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.cs @@ -60,7 +60,7 @@ namespace SharpCompress.Archives.Rar return RarReader.Open(stream, ReaderOptions); } - public override bool IsSolid { get { return Volumes.First().IsSolidArchive; } } + public override bool IsSolid => Volumes.First().IsSolidArchive; #region Creation diff --git a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs index 285ab5cf..fe3d5106 100644 --- a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs +++ b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs @@ -20,13 +20,13 @@ namespace SharpCompress.Archives.Rar this.archive = archive; } - public override CompressionType CompressionType { get { return CompressionType.Rar; } } + public override CompressionType CompressionType => CompressionType.Rar; - public IArchive Archive { get { return archive; } } + public IArchive Archive => archive; - internal override IEnumerable Parts { get { return parts.Cast(); } } + internal override IEnumerable Parts => parts.Cast(); - internal override FileHeader FileHeader { get { return parts.First().FileHeader; } } + internal override FileHeader FileHeader => parts.First().FileHeader; public override long Crc { diff --git a/src/SharpCompress/Archives/Rar/SeekableFilePart.cs b/src/SharpCompress/Archives/Rar/SeekableFilePart.cs index eac4ec9d..1e583f07 100644 --- a/src/SharpCompress/Archives/Rar/SeekableFilePart.cs +++ b/src/SharpCompress/Archives/Rar/SeekableFilePart.cs @@ -28,6 +28,6 @@ namespace SharpCompress.Archives.Rar return stream; } - internal override string FilePartName { get { return "Unknown Stream - File Entry: " + FileHeader.FileName; } } + internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName; } } \ No newline at end of file diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs index 0aaa9cf5..06cac787 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs @@ -171,7 +171,7 @@ namespace SharpCompress.Archives.SevenZip this.archive = archive; } - public override SevenZipVolume Volume { get { return archive.Volumes.Single(); } } + public override SevenZipVolume Volume => archive.Volumes.Single(); internal override IEnumerable GetEntries(Stream stream) { diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs index 7614c94a..ea80b5cb 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs @@ -18,11 +18,11 @@ namespace SharpCompress.Archives.SevenZip public IArchive Archive { get; } - public bool IsComplete { get { return true; } } + public bool IsComplete => true; /// /// This is a 7Zip Anti item /// - public bool IsAnti { get { return FilePart.Header.IsAnti; } } + public bool IsAnti => FilePart.Header.IsAnti; } } \ No newline at end of file diff --git a/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs b/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs index 968ab4f2..51a0a49b 100644 --- a/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs +++ b/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs @@ -22,7 +22,7 @@ namespace SharpCompress.Archives.Tar public IArchive Archive { get; } - public bool IsComplete { get { return true; } } + public bool IsComplete => true; #endregion } diff --git a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs index 784823ec..33c2e766 100644 --- a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs @@ -22,30 +22,30 @@ namespace SharpCompress.Archives.Tar this.closeStream = closeStream; } - public override long Crc { get { return 0; } } + public override long Crc => 0; public override string Key { get; } - public override long CompressedSize { get { return 0; } } + public override long CompressedSize => 0; public override long Size { get; } public override DateTime? LastModifiedTime { get; } - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return false; } } + public override bool IsEncrypted => false; - public override bool IsDirectory { get { return false; } } + public override bool IsDirectory => false; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - internal override IEnumerable Parts { get { throw new NotImplementedException(); } } - Stream IWritableArchiveEntry.Stream { get { return stream; } } + internal override IEnumerable Parts => throw new NotImplementedException(); + Stream IWritableArchiveEntry.Stream => stream; public override Stream OpenEntryStream() { diff --git a/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs index 3e4f71f1..2f1f80f2 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs @@ -21,10 +21,10 @@ namespace SharpCompress.Archives.Zip public IArchive Archive { get; } - public bool IsComplete { get { return true; } } + public bool IsComplete => true; #endregion - public string Comment { get { return (Parts.Single() as SeekableZipFilePart).Comment; } } + public string Comment => (Parts.Single() as SeekableZipFilePart).Comment; } } \ No newline at end of file diff --git a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs index c40394ea..4b4bbf36 100644 --- a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs @@ -23,31 +23,31 @@ namespace SharpCompress.Archives.Zip this.closeStream = closeStream; } - public override long Crc { get { return 0; } } + public override long Crc => 0; public override string Key { get; } - public override long CompressedSize { get { return 0; } } + public override long CompressedSize => 0; public override long Size { get; } public override DateTime? LastModifiedTime { get; } - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return false; } } + public override bool IsEncrypted => false; - public override bool IsDirectory { get { return false; } } + public override bool IsDirectory => false; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - internal override IEnumerable Parts { get { throw new NotImplementedException(); } } + internal override IEnumerable Parts => throw new NotImplementedException(); - Stream IWritableArchiveEntry.Stream { get { return stream; } } + Stream IWritableArchiveEntry.Stream => stream; public override Stream OpenEntryStream() { diff --git a/src/SharpCompress/Common/Entry.cs b/src/SharpCompress/Common/Entry.cs index d546aad5..5f07af2f 100644 --- a/src/SharpCompress/Common/Entry.cs +++ b/src/SharpCompress/Common/Entry.cs @@ -75,6 +75,6 @@ namespace SharpCompress.Common /// /// Entry file attribute. /// - public virtual int? Attrib { get { throw new NotImplementedException(); } } + public virtual int? Attrib => throw new NotImplementedException(); } } \ No newline at end of file diff --git a/src/SharpCompress/Common/EntryStream.cs b/src/SharpCompress/Common/EntryStream.cs index 1df65dbd..0120b782 100644 --- a/src/SharpCompress/Common/EntryStream.cs +++ b/src/SharpCompress/Common/EntryStream.cs @@ -44,20 +44,20 @@ namespace SharpCompress.Common stream.Dispose(); } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Common/GZip/GZipEntry.cs b/src/SharpCompress/Common/GZip/GZipEntry.cs index c347e32a..dd80e73e 100644 --- a/src/SharpCompress/Common/GZip/GZipEntry.cs +++ b/src/SharpCompress/Common/GZip/GZipEntry.cs @@ -13,31 +13,31 @@ namespace SharpCompress.Common.GZip this.filePart = filePart; } - public override CompressionType CompressionType { get { return CompressionType.GZip; } } + public override CompressionType CompressionType => CompressionType.GZip; - public override long Crc { get { return 0; } } + public override long Crc => 0; - public override string Key { get { return filePart.FilePartName; } } + public override string Key => filePart.FilePartName; - public override long CompressedSize { get { return 0; } } + public override long CompressedSize => 0; - public override long Size { get { return 0; } } + public override long Size => 0; - public override DateTime? LastModifiedTime { get { return filePart.DateModified; } } + public override DateTime? LastModifiedTime => filePart.DateModified; - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return false; } } + public override bool IsEncrypted => false; - public override bool IsDirectory { get { return false; } } + public override bool IsDirectory => false; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - internal override IEnumerable Parts { get { return filePart.AsEnumerable(); } } + internal override IEnumerable Parts => filePart.AsEnumerable(); internal static IEnumerable GetEntries(Stream stream) { diff --git a/src/SharpCompress/Common/GZip/GZipFilePart.cs b/src/SharpCompress/Common/GZip/GZipFilePart.cs index f793195a..7690a014 100644 --- a/src/SharpCompress/Common/GZip/GZipFilePart.cs +++ b/src/SharpCompress/Common/GZip/GZipFilePart.cs @@ -24,7 +24,7 @@ namespace SharpCompress.Common.GZip internal DateTime? DateModified { get; private set; } - internal override string FilePartName { get { return name; } } + internal override string FilePartName => name; internal override Stream GetCompressedStream() { diff --git a/src/SharpCompress/Common/GZip/GZipVolume.cs b/src/SharpCompress/Common/GZip/GZipVolume.cs index c3a8bd68..7da73560 100644 --- a/src/SharpCompress/Common/GZip/GZipVolume.cs +++ b/src/SharpCompress/Common/GZip/GZipVolume.cs @@ -18,8 +18,8 @@ namespace SharpCompress.Common.GZip } #endif - public override bool IsFirstVolume { get { return true; } } + public override bool IsFirstVolume => true; - public override bool IsMultiVolume { get { return true; } } + public override bool IsMultiVolume => true; } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Rar/Headers/ArchiveHeader.cs b/src/SharpCompress/Common/Rar/Headers/ArchiveHeader.cs index 2f982946..214a25c0 100644 --- a/src/SharpCompress/Common/Rar/Headers/ArchiveHeader.cs +++ b/src/SharpCompress/Common/Rar/Headers/ArchiveHeader.cs @@ -17,7 +17,7 @@ namespace SharpCompress.Common.Rar.Headers } } - internal ArchiveFlags ArchiveHeaderFlags { get { return (ArchiveFlags)Flags; } } + internal ArchiveFlags ArchiveHeaderFlags => (ArchiveFlags)Flags; internal short HighPosAv { get; private set; } @@ -25,6 +25,6 @@ namespace SharpCompress.Common.Rar.Headers internal byte EncryptionVersion { get; private set; } - public bool HasPassword { get { return ArchiveHeaderFlags.HasFlag(ArchiveFlags.PASSWORD); } } + public bool HasPassword => ArchiveHeaderFlags.HasFlag(ArchiveFlags.PASSWORD); } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Rar/Headers/EndArchiveHeader.cs b/src/SharpCompress/Common/Rar/Headers/EndArchiveHeader.cs index 30e5acea..b2f62039 100644 --- a/src/SharpCompress/Common/Rar/Headers/EndArchiveHeader.cs +++ b/src/SharpCompress/Common/Rar/Headers/EndArchiveHeader.cs @@ -16,7 +16,7 @@ namespace SharpCompress.Common.Rar.Headers } } - internal EndArchiveFlags EndArchiveFlags { get { return (EndArchiveFlags)Flags; } } + internal EndArchiveFlags EndArchiveFlags => (EndArchiveFlags)Flags; internal int? ArchiveCRC { get; private set; } diff --git a/src/SharpCompress/Common/Rar/Headers/FileHeader.cs b/src/SharpCompress/Common/Rar/Headers/FileHeader.cs index 8cdd7135..b870ed84 100644 --- a/src/SharpCompress/Common/Rar/Headers/FileHeader.cs +++ b/src/SharpCompress/Common/Rar/Headers/FileHeader.cs @@ -208,7 +208,7 @@ namespace SharpCompress.Common.Rar.Headers internal int FileAttributes { get; private set; } - internal FileFlags FileFlags { get { return (FileFlags)Flags; } } + internal FileFlags FileFlags => (FileFlags)Flags; internal long CompressedSize { get; private set; } internal long UncompressedSize { get; private set; } diff --git a/src/SharpCompress/Common/Rar/Headers/ProtectHeader.cs b/src/SharpCompress/Common/Rar/Headers/ProtectHeader.cs index b72391d4..e2f78c32 100644 --- a/src/SharpCompress/Common/Rar/Headers/ProtectHeader.cs +++ b/src/SharpCompress/Common/Rar/Headers/ProtectHeader.cs @@ -13,7 +13,7 @@ namespace SharpCompress.Common.Rar.Headers Mark = reader.ReadBytes(8); } - internal uint DataSize { get { return AdditionalSize; } } + internal uint DataSize => AdditionalSize; internal byte Version { get; private set; } internal ushort RecSectors { get; private set; } internal uint TotalBlocks { get; private set; } diff --git a/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs b/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs index fe15e517..6df617b5 100644 --- a/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs +++ b/src/SharpCompress/Common/Rar/RarCrcBinaryReader.cs @@ -12,17 +12,17 @@ namespace SharpCompress.Common.Rar { public ushort GetCrc() { - return (ushort)~this.currentCrc; + return (ushort)~currentCrc; } public void ResetCrc() { - this.currentCrc = 0xffffffff; + currentCrc = 0xffffffff; } protected void UpdateCrc(byte b) { - this.currentCrc = RarCRC.CheckCrc(this.currentCrc, b); + currentCrc = RarCRC.CheckCrc(currentCrc, b); } protected byte[] ReadBytesNoCrc(int count) @@ -33,7 +33,7 @@ namespace SharpCompress.Common.Rar { public override byte[] ReadBytes(int count) { var result = base.ReadBytes(count); - this.currentCrc = RarCRC.CheckCrc(this.currentCrc, result, 0, result.Length); + currentCrc = RarCRC.CheckCrc(currentCrc, result, 0, result.Length); return result; } } diff --git a/src/SharpCompress/Common/Rar/RarEntry.cs b/src/SharpCompress/Common/Rar/RarEntry.cs index c69a514e..cddfca3e 100644 --- a/src/SharpCompress/Common/Rar/RarEntry.cs +++ b/src/SharpCompress/Common/Rar/RarEntry.cs @@ -10,44 +10,44 @@ namespace SharpCompress.Common.Rar /// /// The File's 32 bit CRC Hash /// - public override long Crc { get { return FileHeader.FileCRC; } } + public override long Crc => FileHeader.FileCRC; /// /// The path of the file internal to the Rar Archive. /// - public override string Key { get { return FileHeader.FileName; } } + public override string Key => FileHeader.FileName; /// /// The entry last modified time in the archive, if recorded /// - public override DateTime? LastModifiedTime { get { return FileHeader.FileLastModifiedTime; } } + public override DateTime? LastModifiedTime => FileHeader.FileLastModifiedTime; /// /// The entry create time in the archive, if recorded /// - public override DateTime? CreatedTime { get { return FileHeader.FileCreatedTime; } } + public override DateTime? CreatedTime => FileHeader.FileCreatedTime; /// /// The entry last accessed time in the archive, if recorded /// - public override DateTime? LastAccessedTime { get { return FileHeader.FileLastAccessedTime; } } + public override DateTime? LastAccessedTime => FileHeader.FileLastAccessedTime; /// /// The entry time whend archived, if recorded /// - public override DateTime? ArchivedTime { get { return FileHeader.FileArchivedTime; } } + public override DateTime? ArchivedTime => FileHeader.FileArchivedTime; /// /// Entry is password protected and encrypted and cannot be extracted. /// - public override bool IsEncrypted { get { return FileHeader.FileFlags.HasFlag(FileFlags.PASSWORD); } } + public override bool IsEncrypted => FileHeader.FileFlags.HasFlag(FileFlags.PASSWORD); /// /// Entry is password protected and encrypted and cannot be extracted. /// - public override bool IsDirectory { get { return FileHeader.FileFlags.HasFlag(FileFlags.DIRECTORY); } } + public override bool IsDirectory => FileHeader.FileFlags.HasFlag(FileFlags.DIRECTORY); - public override bool IsSplit { get { return FileHeader.FileFlags.HasFlag(FileFlags.SPLIT_AFTER); } } + public override bool IsSplit => FileHeader.FileFlags.HasFlag(FileFlags.SPLIT_AFTER); public override string ToString() { diff --git a/src/SharpCompress/Common/Rar/RarVolume.cs b/src/SharpCompress/Common/Rar/RarVolume.cs index c7e9729f..89fee688 100644 --- a/src/SharpCompress/Common/Rar/RarVolume.cs +++ b/src/SharpCompress/Common/Rar/RarVolume.cs @@ -21,7 +21,7 @@ namespace SharpCompress.Common.Rar headerFactory = new RarHeaderFactory(mode, options); } - internal StreamingMode Mode { get { return headerFactory.StreamingMode; } } + internal StreamingMode Mode => headerFactory.StreamingMode; internal abstract IEnumerable ReadFileParts(); diff --git a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs index ad6992cc..64a18b8b 100644 --- a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs +++ b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs @@ -1339,20 +1339,20 @@ namespace SharpCompress.Common.SevenZip #region Stream - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Common/SevenZip/CFileItem.cs b/src/SharpCompress/Common/SevenZip/CFileItem.cs index 9d4960e3..450cbdfc 100644 --- a/src/SharpCompress/Common/SevenZip/CFileItem.cs +++ b/src/SharpCompress/Common/SevenZip/CFileItem.cs @@ -12,9 +12,9 @@ namespace SharpCompress.Common.SevenZip public bool HasStream { get; internal set; } public bool IsDir { get; internal set; } - public bool CrcDefined { get { return Crc != null; } } + public bool CrcDefined => Crc != null; - public bool AttribDefined { get { return Attrib != null; } } + public bool AttribDefined => Attrib != null; public void SetAttrib(uint attrib) { diff --git a/src/SharpCompress/Common/SevenZip/CFolder.cs b/src/SharpCompress/Common/SevenZip/CFolder.cs index 008c041c..4606d9dc 100644 --- a/src/SharpCompress/Common/SevenZip/CFolder.cs +++ b/src/SharpCompress/Common/SevenZip/CFolder.cs @@ -13,7 +13,7 @@ namespace SharpCompress.Common.SevenZip internal List UnpackSizes = new List(); internal uint? UnpackCRC; - internal bool UnpackCRCDefined { get { return UnpackCRC != null; } } + internal bool UnpackCRCDefined => UnpackCRC != null; public long GetUnpackSize() { diff --git a/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs b/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs index e6665f01..dd23d629 100644 --- a/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs +++ b/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs @@ -12,32 +12,32 @@ namespace SharpCompress.Common.SevenZip internal SevenZipFilePart FilePart { get; } - public override CompressionType CompressionType { get { return FilePart.CompressionType; } } + public override CompressionType CompressionType => FilePart.CompressionType; - public override long Crc { get { return FilePart.Header.Crc ?? 0; } } + public override long Crc => FilePart.Header.Crc ?? 0; - public override string Key { get { return FilePart.Header.Name; } } + public override string Key => FilePart.Header.Name; - public override long CompressedSize { get { return 0; } } + public override long CompressedSize => 0; - public override long Size { get { return FilePart.Header.Size; } } + public override long Size => FilePart.Header.Size; - public override DateTime? LastModifiedTime { get { return FilePart.Header.MTime; } } + public override DateTime? LastModifiedTime => FilePart.Header.MTime; - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return false; } } + public override bool IsEncrypted => false; - public override bool IsDirectory { get { return FilePart.Header.IsDir; } } + public override bool IsDirectory => FilePart.Header.IsDir; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - public override int? Attrib { get { return (int)FilePart.Header.Attrib; } } + public override int? Attrib => (int)FilePart.Header.Attrib; - internal override IEnumerable Parts { get { return FilePart.AsEnumerable(); } } + internal override IEnumerable Parts => FilePart.AsEnumerable(); } } \ No newline at end of file diff --git a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs index 7f77aadf..13ac91b6 100644 --- a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs +++ b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs @@ -28,7 +28,7 @@ namespace SharpCompress.Common.SevenZip internal CFolder Folder { get; } internal int Index { get; } - internal override string FilePartName { get { return Header.Name; } } + internal override string FilePartName => Header.Name; internal override Stream GetRawStream() { diff --git a/src/SharpCompress/Common/Tar/TarEntry.cs b/src/SharpCompress/Common/Tar/TarEntry.cs index 6fe0ba9e..101271a9 100644 --- a/src/SharpCompress/Common/Tar/TarEntry.cs +++ b/src/SharpCompress/Common/Tar/TarEntry.cs @@ -18,29 +18,29 @@ namespace SharpCompress.Common.Tar public override CompressionType CompressionType { get; } - public override long Crc { get { return 0; } } + public override long Crc => 0; - public override string Key { get { return filePart.Header.Name; } } + public override string Key => filePart.Header.Name; - public override long CompressedSize { get { return filePart.Header.Size; } } + public override long CompressedSize => filePart.Header.Size; - public override long Size { get { return filePart.Header.Size; } } + public override long Size => filePart.Header.Size; - public override DateTime? LastModifiedTime { get { return filePart.Header.LastModifiedTime; } } + public override DateTime? LastModifiedTime => filePart.Header.LastModifiedTime; - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return false; } } + public override bool IsEncrypted => false; - public override bool IsDirectory { get { return filePart.Header.EntryType == EntryType.Directory; } } + public override bool IsDirectory => filePart.Header.EntryType == EntryType.Directory; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - internal override IEnumerable Parts { get { return filePart.AsEnumerable(); } } + internal override IEnumerable Parts => filePart.AsEnumerable(); internal static IEnumerable GetEntries(StreamingMode mode, Stream stream, CompressionType compressionType) diff --git a/src/SharpCompress/Common/Tar/TarFilePart.cs b/src/SharpCompress/Common/Tar/TarFilePart.cs index 3b0a5729..d3569df1 100644 --- a/src/SharpCompress/Common/Tar/TarFilePart.cs +++ b/src/SharpCompress/Common/Tar/TarFilePart.cs @@ -16,7 +16,7 @@ namespace SharpCompress.Common.Tar internal TarHeader Header { get; } - internal override string FilePartName { get { return Header.Name; } } + internal override string FilePartName => Header.Name; internal override Stream GetCompressedStream() { diff --git a/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs b/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs index 420bdafe..337dad74 100644 --- a/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs +++ b/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs @@ -42,20 +42,20 @@ namespace SharpCompress.Common.Tar public Stream Stream { get; } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Common/Volume.cs b/src/SharpCompress/Common/Volume.cs index d5921ab7..87b0d856 100644 --- a/src/SharpCompress/Common/Volume.cs +++ b/src/SharpCompress/Common/Volume.cs @@ -14,7 +14,7 @@ namespace SharpCompress.Common ReaderOptions = readerOptions; } - internal Stream Stream { get { return new NonDisposingStream(actualStream); } } + internal Stream Stream => new NonDisposingStream(actualStream); protected ReaderOptions ReaderOptions { get; } @@ -22,12 +22,12 @@ namespace SharpCompress.Common /// RarArchive is the first volume of a multi-part archive. /// Only Rar 3.0 format and higher /// - public virtual bool IsFirstVolume { get { return true; } } + public virtual bool IsFirstVolume => true; /// /// RarArchive is part of a multi-part archive. /// - public virtual bool IsMultiVolume { get { return true; } } + public virtual bool IsMultiVolume => true; private bool disposed; diff --git a/src/SharpCompress/Common/Zip/Headers/DirectoryEndHeader.cs b/src/SharpCompress/Common/Zip/Headers/DirectoryEndHeader.cs index 32074e4d..0a0a7880 100644 --- a/src/SharpCompress/Common/Zip/Headers/DirectoryEndHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/DirectoryEndHeader.cs @@ -49,14 +49,8 @@ namespace SharpCompress.Common.Zip.Headers public ushort TotalNumberOfEntries { get; private set; } - public bool IsZip64 - { - get - { - return TotalNumberOfEntriesInDisk == ushort.MaxValue - || DirectorySize == uint.MaxValue - || DirectoryStartOffsetRelativeToDisk == uint.MaxValue; - } - } + public bool IsZip64 => TotalNumberOfEntriesInDisk == ushort.MaxValue + || DirectorySize == uint.MaxValue + || DirectoryStartOffsetRelativeToDisk == uint.MaxValue; } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs index 14033ab6..23ae243a 100644 --- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs +++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs @@ -25,7 +25,7 @@ namespace SharpCompress.Common.Zip.Headers internal class ExtraUnicodePathExtraField : ExtraData { - internal byte Version { get { return DataBytes[0]; } } + internal byte Version => DataBytes[0]; internal byte[] NameCRC32 { diff --git a/src/SharpCompress/Common/Zip/Headers/Zip64DirectoryEndHeader.cs b/src/SharpCompress/Common/Zip/Headers/Zip64DirectoryEndHeader.cs index 607ac8ce..32580ceb 100644 --- a/src/SharpCompress/Common/Zip/Headers/Zip64DirectoryEndHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/Zip64DirectoryEndHeader.cs @@ -28,7 +28,7 @@ namespace SharpCompress.Common.Zip.Headers internal override void Write(BinaryWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public long SizeOfDirectoryEndRecord { get; private set; } diff --git a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs index 924ade93..6ffc2781 100644 --- a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs +++ b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs @@ -113,6 +113,6 @@ namespace SharpCompress.Common.Zip.Headers internal ZipFilePart Part { get; set; } - internal bool IsZip64 { get { return CompressedSize == uint.MaxValue; } } + internal bool IsZip64 => CompressedSize == uint.MaxValue; } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs b/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs index 86d0d2d9..c43c4d00 100644 --- a/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs +++ b/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs @@ -23,15 +23,15 @@ namespace SharpCompress.Common.Zip this.mode = mode; } - public override bool CanRead { get { return (mode == CryptoMode.Decrypt); } } + public override bool CanRead => (mode == CryptoMode.Decrypt); - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return (mode == CryptoMode.Encrypt); } } + public override bool CanWrite => (mode == CryptoMode.Encrypt); - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs index 5042f23f..73600aa1 100644 --- a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs @@ -24,7 +24,7 @@ namespace SharpCompress.Common.Zip return base.GetCompressedStream(); } - internal string Comment { get { return (Header as DirectoryEntryHeader).Comment; } } + internal string Comment => (Header as DirectoryEntryHeader).Comment; private void LoadLocalHeader() { diff --git a/src/SharpCompress/Common/Zip/ZipEntry.cs b/src/SharpCompress/Common/Zip/ZipEntry.cs index 45363306..8b8c7337 100644 --- a/src/SharpCompress/Common/Zip/ZipEntry.cs +++ b/src/SharpCompress/Common/Zip/ZipEntry.cs @@ -52,28 +52,28 @@ namespace SharpCompress.Common.Zip } } - public override long Crc { get { return filePart.Header.Crc; } } + public override long Crc => filePart.Header.Crc; - public override string Key { get { return filePart.Header.Name; } } + public override string Key => filePart.Header.Name; - public override long CompressedSize { get { return filePart.Header.CompressedSize; } } + public override long CompressedSize => filePart.Header.CompressedSize; - public override long Size { get { return filePart.Header.UncompressedSize; } } + public override long Size => filePart.Header.UncompressedSize; public override DateTime? LastModifiedTime { get; } - public override DateTime? CreatedTime { get { return null; } } + public override DateTime? CreatedTime => null; - public override DateTime? LastAccessedTime { get { return null; } } + public override DateTime? LastAccessedTime => null; - public override DateTime? ArchivedTime { get { return null; } } + public override DateTime? ArchivedTime => null; - public override bool IsEncrypted { get { return FlagUtility.HasFlag(filePart.Header.Flags, HeaderFlags.Encrypted); } } + public override bool IsEncrypted => FlagUtility.HasFlag(filePart.Header.Flags, HeaderFlags.Encrypted); - public override bool IsDirectory { get { return filePart.Header.IsDirectory; } } + public override bool IsDirectory => filePart.Header.IsDirectory; - public override bool IsSplit { get { return false; } } + public override bool IsSplit => false; - internal override IEnumerable Parts { get { return filePart.AsEnumerable(); } } + internal override IEnumerable Parts => filePart.AsEnumerable(); } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs index 5c9a68b1..7038876d 100644 --- a/src/SharpCompress/Common/Zip/ZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs @@ -24,7 +24,7 @@ namespace SharpCompress.Common.Zip internal Stream BaseStream { get; private set; } internal ZipFileEntry Header { get; set; } - internal override string FilePartName { get { return Header.Name; } } + internal override string FilePartName => Header.Name; internal override Stream GetCompressedStream() { @@ -51,7 +51,7 @@ namespace SharpCompress.Common.Zip protected abstract Stream CreateBaseStream(); - protected bool LeaveStreamOpen { get { return FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor) || Header.IsZip64; } } + protected bool LeaveStreamOpen => FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor) || Header.IsZip64; protected Stream CreateDecompressionStream(Stream stream) { diff --git a/src/SharpCompress/Compressors/ADC/ADCStream.cs b/src/SharpCompress/Compressors/ADC/ADCStream.cs index c1d0bacc..2a909568 100644 --- a/src/SharpCompress/Compressors/ADC/ADCStream.cs +++ b/src/SharpCompress/Compressors/ADC/ADCStream.cs @@ -73,15 +73,15 @@ namespace SharpCompress.Compressors.ADC this.stream = stream; } - public override bool CanRead { get { return stream.CanRead; } } + public override bool CanRead => stream.CanRead; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { return position; } set { throw new NotSupportedException(); } } + public override long Position { get => position; set => throw new NotSupportedException(); } public override void Flush() { diff --git a/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs b/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs index e2685e27..590313d3 100644 --- a/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs +++ b/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs @@ -48,20 +48,20 @@ namespace SharpCompress.Compressors.BZip2 public CompressionMode Mode { get; } - public override bool CanRead { get { return stream.CanRead; } } + public override bool CanRead => stream.CanRead; - public override bool CanSeek { get { return stream.CanSeek; } } + public override bool CanSeek => stream.CanSeek; - public override bool CanWrite { get { return stream.CanWrite; } } + public override bool CanWrite => stream.CanWrite; public override void Flush() { stream.Flush(); } - public override long Length { get { return stream.Length; } } + public override long Length => stream.Length; - public override long Position { get { return stream.Position; } set { stream.Position = value; } } + public override long Position { get => stream.Position; set => stream.Position = value; } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs index 0c9bca55..0656801e 100644 --- a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs +++ b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs @@ -1092,13 +1092,13 @@ namespace SharpCompress.Compressors.BZip2 { } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; - public override long Length { get { return 0; } } + public override long Length => 0; public override long Position { get { return 0; } set { } } } diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs index 56dcf4f9..9f4817cc 100644 --- a/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs +++ b/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs @@ -1956,13 +1956,13 @@ namespace SharpCompress.Compressors.BZip2 } } - public override bool CanRead { get { return false; } } + public override bool CanRead => false; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return true; } } + public override bool CanWrite => true; - public override long Length { get { return 0; } } + public override long Length => 0; public override long Position { get { return 0; } set { } } } diff --git a/src/SharpCompress/Compressors/Deflate/CRC32.cs b/src/SharpCompress/Compressors/Deflate/CRC32.cs index c1263574..9be80960 100644 --- a/src/SharpCompress/Compressors/Deflate/CRC32.cs +++ b/src/SharpCompress/Compressors/Deflate/CRC32.cs @@ -92,14 +92,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Indicates the current CRC for all blocks slurped in. /// - public Int32 Crc32Result - { - get - { - // return one's complement of the running result - return unchecked((Int32)(~runningCrc32Result)); - } - } + public Int32 Crc32Result => unchecked((Int32)(~runningCrc32Result)); /// /// Returns the CRC32 for the specified stream. diff --git a/src/SharpCompress/Compressors/Deflate/DeflateStream.cs b/src/SharpCompress/Compressors/Deflate/DeflateStream.cs index 23399464..8ccaca1e 100644 --- a/src/SharpCompress/Compressors/Deflate/DeflateStream.cs +++ b/src/SharpCompress/Compressors/Deflate/DeflateStream.cs @@ -50,7 +50,7 @@ namespace SharpCompress.Compressors.Deflate /// public virtual FlushType FlushMode { - get { return (_baseStream._flushMode); } + get => (_baseStream._flushMode); set { if (_disposed) @@ -80,7 +80,7 @@ namespace SharpCompress.Compressors.Deflate /// public int BufferSize { - get { return _baseStream._bufferSize; } + get => _baseStream._bufferSize; set { if (_disposed) @@ -111,7 +111,7 @@ namespace SharpCompress.Compressors.Deflate /// public CompressionStrategy Strategy { - get { return _baseStream.Strategy; } + get => _baseStream.Strategy; set { if (_disposed) @@ -123,10 +123,10 @@ namespace SharpCompress.Compressors.Deflate } /// Returns the total number of bytes input so far. - public virtual long TotalIn { get { return _baseStream._z.TotalBytesIn; } } + public virtual long TotalIn => _baseStream._z.TotalBytesIn; /// Returns the total number of bytes output so far. - public virtual long TotalOut { get { return _baseStream._z.TotalBytesOut; } } + public virtual long TotalOut => _baseStream._z.TotalBytesOut; #endregion @@ -156,7 +156,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Always returns false. /// - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; /// /// Indicates whether the stream can be written. @@ -179,7 +179,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Reading this property always throws a . /// - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); /// /// The position of the stream pointer. @@ -206,7 +206,7 @@ namespace SharpCompress.Compressors.Deflate } return 0; } - set { throw new NotSupportedException(); } + set => throw new NotSupportedException(); } /// @@ -342,13 +342,7 @@ namespace SharpCompress.Compressors.Deflate #endregion - public MemoryStream InputBuffer - { - get - { - return new MemoryStream(_baseStream._z.InputBuffer, _baseStream._z.NextIn, - _baseStream._z.AvailableBytesIn); - } - } + public MemoryStream InputBuffer => new MemoryStream(_baseStream._z.InputBuffer, _baseStream._z.NextIn, + _baseStream._z.AvailableBytesIn); } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/Deflate/GZipStream.cs b/src/SharpCompress/Compressors/Deflate/GZipStream.cs index a7a7f74d..8e775c99 100644 --- a/src/SharpCompress/Compressors/Deflate/GZipStream.cs +++ b/src/SharpCompress/Compressors/Deflate/GZipStream.cs @@ -71,7 +71,7 @@ namespace SharpCompress.Compressors.Deflate public virtual FlushType FlushMode { - get { return (BaseStream._flushMode); } + get => (BaseStream._flushMode); set { if (disposed) @@ -84,7 +84,7 @@ namespace SharpCompress.Compressors.Deflate public int BufferSize { - get { return BaseStream._bufferSize; } + get => BaseStream._bufferSize; set { if (disposed) @@ -105,9 +105,9 @@ namespace SharpCompress.Compressors.Deflate } } - internal virtual long TotalIn { get { return BaseStream._z.TotalBytesIn; } } + internal virtual long TotalIn => BaseStream._z.TotalBytesIn; - internal virtual long TotalOut { get { return BaseStream._z.TotalBytesOut; } } + internal virtual long TotalOut => BaseStream._z.TotalBytesOut; #endregion @@ -137,7 +137,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Always returns false. /// - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; /// /// Indicates whether the stream can be written. @@ -160,7 +160,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Reading this property always throws a . /// - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); /// /// The position of the stream pointer. @@ -188,7 +188,7 @@ namespace SharpCompress.Compressors.Deflate return 0; } - set { throw new NotSupportedException(); } + set => throw new NotSupportedException(); } /// @@ -350,7 +350,7 @@ namespace SharpCompress.Compressors.Deflate public String Comment { - get { return comment; } + get => comment; set { if (disposed) @@ -363,7 +363,7 @@ namespace SharpCompress.Compressors.Deflate public string FileName { - get { return fileName; } + get => fileName; set { if (disposed) diff --git a/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs b/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs index c6d8d1dc..7051b1f2 100644 --- a/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs +++ b/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs @@ -98,7 +98,7 @@ namespace SharpCompress.Compressors.Deflate } } - protected internal bool _wantCompress { get { return (_compressionMode == CompressionMode.Compress); } } + protected internal bool _wantCompress => (_compressionMode == CompressionMode.Compress); private ZlibCodec z { @@ -630,15 +630,15 @@ namespace SharpCompress.Compressors.Deflate return rc; } - public override Boolean CanRead { get { return _stream.CanRead; } } + public override Boolean CanRead => _stream.CanRead; - public override Boolean CanSeek { get { return _stream.CanSeek; } } + public override Boolean CanSeek => _stream.CanSeek; - public override Boolean CanWrite { get { return _stream.CanWrite; } } + public override Boolean CanWrite => _stream.CanWrite; - public override Int64 Length { get { return _stream.Length; } } + public override Int64 Length => _stream.Length; - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } internal enum StreamMode { diff --git a/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs b/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs index 5343057f..f2e9339b 100644 --- a/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs +++ b/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs @@ -171,7 +171,7 @@ namespace SharpCompress.Compressors.Deflate /// /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. /// - public int Adler32 { get { return (int)_Adler32; } } + public int Adler32 => (int)_Adler32; /// /// Create a ZlibCodec. diff --git a/src/SharpCompress/Compressors/Deflate/ZlibStream.cs b/src/SharpCompress/Compressors/Deflate/ZlibStream.cs index 9e20bc50..6777c20d 100644 --- a/src/SharpCompress/Compressors/Deflate/ZlibStream.cs +++ b/src/SharpCompress/Compressors/Deflate/ZlibStream.cs @@ -63,7 +63,7 @@ namespace SharpCompress.Compressors.Deflate /// public virtual FlushType FlushMode { - get { return (_baseStream._flushMode); } + get => (_baseStream._flushMode); set { if (_disposed) @@ -93,7 +93,7 @@ namespace SharpCompress.Compressors.Deflate /// public int BufferSize { - get { return _baseStream._bufferSize; } + get => _baseStream._bufferSize; set { if (_disposed) @@ -115,10 +115,10 @@ namespace SharpCompress.Compressors.Deflate } /// Returns the total number of bytes input so far. - public virtual long TotalIn { get { return _baseStream._z.TotalBytesIn; } } + public virtual long TotalIn => _baseStream._z.TotalBytesIn; /// Returns the total number of bytes output so far. - public virtual long TotalOut { get { return _baseStream._z.TotalBytesOut; } } + public virtual long TotalOut => _baseStream._z.TotalBytesOut; #endregion @@ -148,7 +148,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Always returns false. /// - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; /// /// Indicates whether the stream can be written. @@ -171,7 +171,7 @@ namespace SharpCompress.Compressors.Deflate /// /// Reading this property always throws a . /// - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); /// /// The position of the stream pointer. @@ -199,7 +199,7 @@ namespace SharpCompress.Compressors.Deflate return 0; } - set { throw new NotSupportedException(); } + set => throw new NotSupportedException(); } /// diff --git a/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs b/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs index 86ed1b97..65af71ee 100644 --- a/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs +++ b/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs @@ -78,20 +78,20 @@ namespace SharpCompress.Compressors.Filters baseStream.Dispose(); } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { return baseStream.Length + data1.Length + data2.Length; } } + public override long Length => baseStream.Length + data1.Length + data2.Length; - public override long Position { get { return position; } set { throw new NotSupportedException(); } } + public override long Position { get => position; set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/Filters/Filter.cs b/src/SharpCompress/Compressors/Filters/Filter.cs index d19235ca..c0b23eb1 100644 --- a/src/SharpCompress/Compressors/Filters/Filter.cs +++ b/src/SharpCompress/Compressors/Filters/Filter.cs @@ -34,20 +34,20 @@ namespace SharpCompress.Compressors.Filters baseStream.Dispose(); } - public override bool CanRead { get { return !isEncoder; } } + public override bool CanRead => !isEncoder; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return isEncoder; } } + public override bool CanWrite => isEncoder; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { return baseStream.Length; } } + public override long Length => baseStream.Length; - public override long Position { get { return baseStream.Position; } set { throw new NotSupportedException(); } } + public override long Position { get => baseStream.Position; set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/LZMA/DecoderStream.cs b/src/SharpCompress/Compressors/LZMA/DecoderStream.cs index b4adab90..c9c6fd21 100644 --- a/src/SharpCompress/Compressors/LZMA/DecoderStream.cs +++ b/src/SharpCompress/Compressors/LZMA/DecoderStream.cs @@ -8,20 +8,20 @@ namespace SharpCompress.Compressors.LZMA { internal abstract class DecoderStream2 : Stream { - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override long Seek(long offset, SeekOrigin origin) { diff --git a/src/SharpCompress/Compressors/LZMA/LZ/LzInWindow.cs b/src/SharpCompress/Compressors/LZMA/LZ/LzInWindow.cs index fa41ed9f..ad8c9170 100644 --- a/src/SharpCompress/Compressors/LZMA/LZ/LzInWindow.cs +++ b/src/SharpCompress/Compressors/LZMA/LZ/LzInWindow.cs @@ -178,6 +178,6 @@ namespace SharpCompress.Compressors.LZMA.LZ _streamPos -= (UInt32)subValue; } - public bool IsDataStarved { get { return _streamPos - _pos < _keepSizeAfter; } } + public bool IsDataStarved => _streamPos - _pos < _keepSizeAfter; } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/LZMA/LZ/LzOutWindow.cs b/src/SharpCompress/Compressors/LZMA/LZ/LzOutWindow.cs index d9dbc3d0..1b230873 100644 --- a/src/SharpCompress/Compressors/LZMA/LZ/LzOutWindow.cs +++ b/src/SharpCompress/Compressors/LZMA/LZ/LzOutWindow.cs @@ -166,9 +166,9 @@ namespace SharpCompress.Compressors.LZMA.LZ Limit = Total + size; } - public bool HasSpace { get { return _pos < _windowSize && Total < Limit; } } + public bool HasSpace => _pos < _windowSize && Total < Limit; - public bool HasPending { get { return _pendingLen > 0; } } + public bool HasPending => _pendingLen > 0; public int Read(byte[] buffer, int offset, int count) { @@ -200,6 +200,6 @@ namespace SharpCompress.Compressors.LZMA.LZ } } - public int AvailableBytes { get { return _pos - _streamPos; } } + public int AvailableBytes => _pos - _streamPos; } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/LZMA/LZipStream.cs b/src/SharpCompress/Compressors/LZMA/LZipStream.cs index 19b89764..a061d1df 100644 --- a/src/SharpCompress/Compressors/LZMA/LZipStream.cs +++ b/src/SharpCompress/Compressors/LZMA/LZipStream.cs @@ -69,9 +69,9 @@ namespace SharpCompress.Compressors.LZMA // TODO: Both Length and Position are sometimes feasible, but would require // reading the output length when we initialize. - public override long Length { get { throw new NotImplementedException(); } } + public override long Length => throw new NotImplementedException(); - public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public override int Read(byte[] buffer, int offset, int count) => stream.Read(buffer, offset, count); diff --git a/src/SharpCompress/Compressors/LZMA/LzmaStream.cs b/src/SharpCompress/Compressors/LZMA/LzmaStream.cs index 3614b4c8..b2591cde 100644 --- a/src/SharpCompress/Compressors/LZMA/LzmaStream.cs +++ b/src/SharpCompress/Compressors/LZMA/LzmaStream.cs @@ -118,11 +118,11 @@ namespace SharpCompress.Compressors.LZMA } } - public override bool CanRead { get { return encoder == null; } } + public override bool CanRead => encoder == null; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return encoder != null; } } + public override bool CanWrite => encoder != null; public override void Flush() { @@ -149,9 +149,9 @@ namespace SharpCompress.Compressors.LZMA base.Dispose(disposing); } - public override long Length { get { return position + availableBytes; } } + public override long Length => position + availableBytes; - public override long Position { get { return position; } set { throw new NotSupportedException(); } } + public override long Position { get => position; set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoder.cs b/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoder.cs index 1c3d5ecc..6b6ab41e 100644 --- a/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoder.cs +++ b/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoder.cs @@ -245,7 +245,7 @@ namespace SharpCompress.Compressors.LZMA.RangeCoder return symbol; } - public bool IsFinished { get { return Code == 0; } } + public bool IsFinished => Code == 0; // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } } diff --git a/src/SharpCompress/Compressors/LZMA/Utilites/CrcBuilderStream.cs b/src/SharpCompress/Compressors/LZMA/Utilites/CrcBuilderStream.cs index b93a0181..1da7a723 100644 --- a/src/SharpCompress/Compressors/LZMA/Utilites/CrcBuilderStream.cs +++ b/src/SharpCompress/Compressors/LZMA/Utilites/CrcBuilderStream.cs @@ -40,19 +40,19 @@ namespace SharpCompress.Compressors.LZMA.Utilites return mCRC; } - public override bool CanRead { get { return false; } } + public override bool CanRead => false; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return true; } } + public override bool CanWrite => true; public override void Flush() { } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { @@ -122,20 +122,20 @@ namespace SharpCompress.Compressors.LZMA.Utilites return mCRC; } - public override bool CanRead { get { return mSource.CanRead; } } + public override bool CanRead => mSource.CanRead; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/LZMA/Utilites/CrcCheckStream.cs b/src/SharpCompress/Compressors/LZMA/Utilites/CrcCheckStream.cs index 6f1ca915..f64887e4 100644 --- a/src/SharpCompress/Compressors/LZMA/Utilites/CrcCheckStream.cs +++ b/src/SharpCompress/Compressors/LZMA/Utilites/CrcCheckStream.cs @@ -62,19 +62,19 @@ namespace SharpCompress.Compressors.LZMA.Utilites } } - public override bool CanRead { get { return false; } } + public override bool CanRead => false; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return true; } } + public override bool CanWrite => true; public override void Flush() { } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/PPMd/H/FreqData.cs b/src/SharpCompress/Compressors/PPMd/H/FreqData.cs index e32ec69d..731ed972 100644 --- a/src/SharpCompress/Compressors/PPMd/H/FreqData.cs +++ b/src/SharpCompress/Compressors/PPMd/H/FreqData.cs @@ -19,7 +19,7 @@ namespace SharpCompress.Compressors.PPMd.H { } - internal int SummFreq { get { return DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff; } set { DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value); } } + internal int SummFreq { get => DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff; set => DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value); } internal FreqData Initialize(byte[] mem) { diff --git a/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs b/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs index 0329ab9c..8a754333 100644 --- a/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs +++ b/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs @@ -22,33 +22,33 @@ namespace SharpCompress.Compressors.PPMd.H public SubAllocator SubAlloc { get; } = new SubAllocator(); - public virtual SEE2Context DummySEE2Cont { get { return dummySEE2Cont; } } + public virtual SEE2Context DummySEE2Cont => dummySEE2Cont; - public virtual int InitRL { get { return initRL; } } + public virtual int InitRL => initRL; - public virtual int EscCount { get { return escCount; } set { escCount = value & 0xff; } } + public virtual int EscCount { get => escCount; set => escCount = value & 0xff; } - public virtual int[] CharMask { get { return charMask; } } + public virtual int[] CharMask => charMask; - public virtual int NumMasked { get { return numMasked; } set { numMasked = value; } } + public virtual int NumMasked { get => numMasked; set => numMasked = value; } - public virtual int PrevSuccess { get { return prevSuccess; } set { prevSuccess = value & 0xff; } } + public virtual int PrevSuccess { get => prevSuccess; set => prevSuccess = value & 0xff; } - public virtual int InitEsc { get { return initEsc; } set { initEsc = value; } } + public virtual int InitEsc { get => initEsc; set => initEsc = value; } - public virtual int RunLength { get { return runLength; } set { runLength = value; } } + public virtual int RunLength { get => runLength; set => runLength = value; } - public virtual int HiBitsFlag { get { return hiBitsFlag; } set { hiBitsFlag = value & 0xff; } } + public virtual int HiBitsFlag { get => hiBitsFlag; set => hiBitsFlag = value & 0xff; } - public virtual int[][] BinSumm { get { return binSumm; } } + public virtual int[][] BinSumm => binSumm; internal RangeCoder Coder { get; private set; } internal State FoundState { get; private set; } - public virtual byte[] Heap { get { return SubAlloc.Heap; } } + public virtual byte[] Heap => SubAlloc.Heap; - public virtual int OrderFall { get { return orderFall; } } + public virtual int OrderFall => orderFall; public const int MAX_O = 64; /* maximum allowed model order */ diff --git a/src/SharpCompress/Compressors/PPMd/H/PPMContext.cs b/src/SharpCompress/Compressors/PPMd/H/PPMContext.cs index f3a153aa..e39fa69c 100644 --- a/src/SharpCompress/Compressors/PPMd/H/PPMContext.cs +++ b/src/SharpCompress/Compressors/PPMd/H/PPMContext.cs @@ -8,8 +8,7 @@ namespace SharpCompress.Compressors.PPMd.H { internal FreqData FreqData { - get { return freqData; } - + get => freqData; set { freqData.SummFreq = value.SummFreq; @@ -131,7 +130,7 @@ namespace SharpCompress.Compressors.PPMd.H internal override int Address { - get { return base.Address; } + get => base.Address; set { base.Address = value; diff --git a/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs b/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs index a408e426..4c04828a 100644 --- a/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs +++ b/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs @@ -131,11 +131,11 @@ namespace SharpCompress.Compressors.PPMd.H Scale = Scale + dScale; } - internal long HighCount { get { return highCount; } set { highCount = value & RangeCoder.UintMask; } } + internal long HighCount { get => highCount; set => highCount = value & RangeCoder.UintMask; } - internal long LowCount { get { return lowCount & RangeCoder.UintMask; } set { lowCount = value & RangeCoder.UintMask; } } + internal long LowCount { get => lowCount & RangeCoder.UintMask; set => lowCount = value & RangeCoder.UintMask; } - internal long Scale { get { return scale; } set { scale = value & RangeCoder.UintMask; } } + internal long Scale { get => scale; set => scale = value & RangeCoder.UintMask; } // Debug public override String ToString() diff --git a/src/SharpCompress/Compressors/PPMd/H/SEE2Context.cs b/src/SharpCompress/Compressors/PPMd/H/SEE2Context.cs index 5cb2aca8..66344c00 100644 --- a/src/SharpCompress/Compressors/PPMd/H/SEE2Context.cs +++ b/src/SharpCompress/Compressors/PPMd/H/SEE2Context.cs @@ -15,11 +15,11 @@ namespace SharpCompress.Compressors.PPMd.H } } - public virtual int Count { get { return count; } set { count = value & 0xff; } } + public virtual int Count { get => count; set => count = value & 0xff; } - public virtual int Shift { get { return shift; } set { shift = value & 0xff; } } + public virtual int Shift { get => shift; set => shift = value & 0xff; } - public virtual int Summ { get { return summ; } set { summ = value & 0xffff; } } + public virtual int Summ { get => summ; set => summ = value & 0xffff; } public const int size = 4; diff --git a/src/SharpCompress/Compressors/PPMd/H/State.cs b/src/SharpCompress/Compressors/PPMd/H/State.cs index b248f5d8..2771e5b3 100644 --- a/src/SharpCompress/Compressors/PPMd/H/State.cs +++ b/src/SharpCompress/Compressors/PPMd/H/State.cs @@ -13,9 +13,9 @@ namespace SharpCompress.Compressors.PPMd.H { } - internal int Symbol { get { return Memory[Address] & 0xff; } set { Memory[Address] = (byte)value; } } + internal int Symbol { get => Memory[Address] & 0xff; set => Memory[Address] = (byte)value; } - internal int Freq { get { return Memory[Address + 1] & 0xff; } set { Memory[Address + 1] = (byte)value; } } + internal int Freq { get => Memory[Address + 1] & 0xff; set => Memory[Address + 1] = (byte)value; } internal State Initialize(byte[] mem) { diff --git a/src/SharpCompress/Compressors/PPMd/H/StateRef.cs b/src/SharpCompress/Compressors/PPMd/H/StateRef.cs index 83764370..3499bdd8 100644 --- a/src/SharpCompress/Compressors/PPMd/H/StateRef.cs +++ b/src/SharpCompress/Compressors/PPMd/H/StateRef.cs @@ -11,9 +11,9 @@ namespace SharpCompress.Compressors.PPMd.H private int successor; // pointer ppmcontext - internal int Symbol { get { return symbol; } set { symbol = value & 0xff; } } + internal int Symbol { get => symbol; set => symbol = value & 0xff; } - internal int Freq { get { return freq; } set { freq = value & 0xff; } } + internal int Freq { get => freq; set => freq = value & 0xff; } internal State Values { diff --git a/src/SharpCompress/Compressors/PPMd/H/SubAllocator.cs b/src/SharpCompress/Compressors/PPMd/H/SubAllocator.cs index da74fd96..0918e9a9 100644 --- a/src/SharpCompress/Compressors/PPMd/H/SubAllocator.cs +++ b/src/SharpCompress/Compressors/PPMd/H/SubAllocator.cs @@ -5,15 +5,15 @@ namespace SharpCompress.Compressors.PPMd.H { internal class SubAllocator { - public virtual int FakeUnitsStart { get { return fakeUnitsStart; } set { fakeUnitsStart = value; } } + public virtual int FakeUnitsStart { get => fakeUnitsStart; set => fakeUnitsStart = value; } - public virtual int HeapEnd { get { return heapEnd; } } + public virtual int HeapEnd => heapEnd; - public virtual int PText { get { return pText; } set { pText = value; } } + public virtual int PText { get => pText; set => pText = value; } - public virtual int UnitsStart { get { return unitsStart; } set { unitsStart = value; } } + public virtual int UnitsStart { get => unitsStart; set => unitsStart = value; } - public virtual byte[] Heap { get { return heap; } } + public virtual byte[] Heap => heap; //UPGRADE_NOTE: Final was removed from the declaration of 'N4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" public const int N1 = 4; diff --git a/src/SharpCompress/Compressors/PPMd/I1/MemoryNode.cs b/src/SharpCompress/Compressors/PPMd/I1/MemoryNode.cs index c9e9483b..23a08643 100644 --- a/src/SharpCompress/Compressors/PPMd/I1/MemoryNode.cs +++ b/src/SharpCompress/Compressors/PPMd/I1/MemoryNode.cs @@ -48,11 +48,8 @@ namespace SharpCompress.Compressors.PPMd.I1 /// public uint Stamp { - get - { - return Memory[Address] | ((uint)Memory[Address + 1]) << 8 | ((uint)Memory[Address + 2]) << 16 | - ((uint)Memory[Address + 3]) << 24; - } + get => Memory[Address] | ((uint)Memory[Address + 1]) << 8 | ((uint)Memory[Address + 2]) << 16 | + ((uint)Memory[Address + 3]) << 24; set { Memory[Address] = (byte)value; @@ -67,13 +64,9 @@ namespace SharpCompress.Compressors.PPMd.I1 /// public MemoryNode Next { - get - { - return - new MemoryNode( - Memory[Address + 4] | ((uint)Memory[Address + 5]) << 8 | - ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); - } + get => new MemoryNode( + Memory[Address + 4] | ((uint)Memory[Address + 5]) << 8 | + ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); set { Memory[Address + 4] = (byte)value.Address; @@ -88,11 +81,8 @@ namespace SharpCompress.Compressors.PPMd.I1 /// public uint UnitCount { - get - { - return Memory[Address + 8] | ((uint)Memory[Address + 9]) << 8 | - ((uint)Memory[Address + 10]) << 16 | ((uint)Memory[Address + 11]) << 24; - } + get => Memory[Address + 8] | ((uint)Memory[Address + 9]) << 8 | + ((uint)Memory[Address + 10]) << 16 | ((uint)Memory[Address + 11]) << 24; set { Memory[Address + 8] = (byte)value; @@ -105,7 +95,7 @@ namespace SharpCompress.Compressors.PPMd.I1 /// /// Gets whether there is a next memory node available. /// - public bool Available { get { return Next.Address != 0; } } + public bool Available => Next.Address != 0; /// /// Link in the provided memory node. diff --git a/src/SharpCompress/Compressors/PPMd/I1/PpmContext.cs b/src/SharpCompress/Compressors/PPMd/I1/PpmContext.cs index 8b05e637..371385fe 100644 --- a/src/SharpCompress/Compressors/PPMd/I1/PpmContext.cs +++ b/src/SharpCompress/Compressors/PPMd/I1/PpmContext.cs @@ -34,19 +34,19 @@ namespace SharpCompress.Compressors.PPMd.I1 /// /// Gets or sets the number statistics. /// - public byte NumberStatistics { get { return Memory[Address]; } set { Memory[Address] = value; } } + public byte NumberStatistics { get => Memory[Address]; set => Memory[Address] = value; } /// /// Gets or sets the flags. /// - public byte Flags { get { return Memory[Address + 1]; } set { Memory[Address + 1] = value; } } + public byte Flags { get => Memory[Address + 1]; set => Memory[Address + 1] = value; } /// /// Gets or sets the summary frequency. /// public ushort SummaryFrequency { - get { return (ushort)(Memory[Address + 2] | Memory[Address + 3] << 8); } + get => (ushort)(Memory[Address + 2] | Memory[Address + 3] << 8); set { Memory[Address + 2] = (byte)value; @@ -59,13 +59,9 @@ namespace SharpCompress.Compressors.PPMd.I1 /// public PpmState Statistics { - get - { - return - new PpmState( - Memory[Address + 4] | ((uint)Memory[Address + 5]) << 8 | - ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); - } + get => new PpmState( + Memory[Address + 4] | ((uint)Memory[Address + 5]) << 8 | + ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); set { Memory[Address + 4] = (byte)value.Address; @@ -80,13 +76,9 @@ namespace SharpCompress.Compressors.PPMd.I1 /// public PpmContext Suffix { - get - { - return - new PpmContext( - Memory[Address + 8] | ((uint)Memory[Address + 9]) << 8 | - ((uint)Memory[Address + 10]) << 16 | ((uint)Memory[Address + 11]) << 24, Memory); - } + get => new PpmContext( + Memory[Address + 8] | ((uint)Memory[Address + 9]) << 8 | + ((uint)Memory[Address + 10]) << 16 | ((uint)Memory[Address + 11]) << 24, Memory); set { Memory[Address + 8] = (byte)value.Address; @@ -121,21 +113,21 @@ namespace SharpCompress.Compressors.PPMd.I1 /// /// /// - public PpmState FirstState { get { return new PpmState(Address + 2, Memory); } } + public PpmState FirstState => new PpmState(Address + 2, Memory); /// /// Gets or sets the symbol of the first PPM state. This is provided for convenience. The same /// information can be obtained using the Symbol property on the PPM state provided by the /// property. /// - public byte FirstStateSymbol { get { return Memory[Address + 2]; } set { Memory[Address + 2] = value; } } + public byte FirstStateSymbol { get => Memory[Address + 2]; set => Memory[Address + 2] = value; } /// /// Gets or sets the frequency of the first PPM state. This is provided for convenience. The same /// information can be obtained using the Frequency property on the PPM state provided by the ///context.FirstState property. /// - public byte FirstStateFrequency { get { return Memory[Address + 3]; } set { Memory[Address + 3] = value; } } + public byte FirstStateFrequency { get => Memory[Address + 3]; set => Memory[Address + 3] = value; } /// /// Gets or sets the successor of the first PPM state. This is provided for convenience. The same @@ -143,13 +135,9 @@ namespace SharpCompress.Compressors.PPMd.I1 /// public PpmContext FirstStateSuccessor { - get - { - return - new PpmContext( - Memory[Address + 4] | ((uint)Memory[Address + 5]) << 8 | - ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); - } + get => new PpmContext( + Memory[Address + 4] | ((uint)Memory[Address + 5]) << 8 | + ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); set { Memory[Address + 4] = (byte)value.Address; diff --git a/src/SharpCompress/Compressors/PPMd/I1/PpmState.cs b/src/SharpCompress/Compressors/PPMd/I1/PpmState.cs index 584eb389..d6c2d39f 100644 --- a/src/SharpCompress/Compressors/PPMd/I1/PpmState.cs +++ b/src/SharpCompress/Compressors/PPMd/I1/PpmState.cs @@ -38,25 +38,21 @@ namespace SharpCompress.Compressors.PPMd.I1 /// /// Gets or sets the symbol. /// - public byte Symbol { get { return Memory[Address]; } set { Memory[Address] = value; } } + public byte Symbol { get => Memory[Address]; set => Memory[Address] = value; } /// /// Gets or sets the frequency. /// - public byte Frequency { get { return Memory[Address + 1]; } set { Memory[Address + 1] = value; } } + public byte Frequency { get => Memory[Address + 1]; set => Memory[Address + 1] = value; } /// /// Gets or sets the successor. /// public Model.PpmContext Successor { - get - { - return - new Model.PpmContext( - Memory[Address + 2] | ((uint)Memory[Address + 3]) << 8 | - ((uint)Memory[Address + 4]) << 16 | ((uint)Memory[Address + 5]) << 24, Memory); - } + get => new Model.PpmContext( + Memory[Address + 2] | ((uint)Memory[Address + 3]) << 8 | + ((uint)Memory[Address + 4]) << 16 | ((uint)Memory[Address + 5]) << 24, Memory); set { Memory[Address + 2] = (byte)value.Address; @@ -72,7 +68,7 @@ namespace SharpCompress.Compressors.PPMd.I1 /// /// /// - public PpmState this[int offset] { get { return new PpmState((uint)(Address + offset * Size), Memory); } } + public PpmState this[int offset] => new PpmState((uint)(Address + offset * Size), Memory); /// /// Allow a pointer to be implicitly converted to a PPM state. diff --git a/src/SharpCompress/Compressors/PPMd/PpmdProperties.cs b/src/SharpCompress/Compressors/PPMd/PpmdProperties.cs index 25e90b6e..bd8b43bc 100644 --- a/src/SharpCompress/Compressors/PPMd/PpmdProperties.cs +++ b/src/SharpCompress/Compressors/PPMd/PpmdProperties.cs @@ -48,7 +48,7 @@ namespace SharpCompress.Compressors.PPMd public int AllocatorSize { - get { return allocatorSize; } + get => allocatorSize; set { allocatorSize = value; @@ -63,15 +63,8 @@ namespace SharpCompress.Compressors.PPMd } } - public byte[] Properties - { - get - { - return - DataConverter.LittleEndian.GetBytes( - (ushort) - ((ModelOrder - 1) + (((AllocatorSize >> 20) - 1) << 4) + ((ushort)ModelRestorationMethod << 12))); - } - } + public byte[] Properties => DataConverter.LittleEndian.GetBytes( + (ushort) + ((ModelOrder - 1) + (((AllocatorSize >> 20) - 1) << 4) + ((ushort)ModelRestorationMethod << 12))); } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/PPMd/PpmdStream.cs b/src/SharpCompress/Compressors/PPMd/PpmdStream.cs index 94e5b596..1169ed52 100644 --- a/src/SharpCompress/Compressors/PPMd/PpmdStream.cs +++ b/src/SharpCompress/Compressors/PPMd/PpmdStream.cs @@ -57,11 +57,11 @@ namespace SharpCompress.Compressors.PPMd } } - public override bool CanRead { get { return !compress; } } + public override bool CanRead => !compress; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return compress; } } + public override bool CanWrite => compress; public override void Flush() { @@ -84,9 +84,9 @@ namespace SharpCompress.Compressors.PPMd base.Dispose(isDisposing); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { return position; } set { throw new NotSupportedException(); } } + public override long Position { get => position; set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs b/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs index 90a823a6..d5618d5f 100644 --- a/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs +++ b/src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyStream.cs @@ -19,7 +19,6 @@ namespace SharpCompress.Compressors.Rar private long currentPartTotalReadBytes; private long currentEntryTotalReadBytes; - private uint currentCrc; internal MultiVolumeReadOnlyStream(IEnumerable parts, IExtractionListener streamListener) { @@ -60,7 +59,7 @@ namespace SharpCompress.Compressors.Rar currentPartTotalReadBytes = 0; - currentCrc = filePartEnumerator.Current.FileHeader.FileCRC; + CurrentCrc = filePartEnumerator.Current.FileHeader.FileCRC; streamListener.FireFilePartExtractionBegin(filePartEnumerator.Current.FilePartName, filePartEnumerator.Current.FileHeader.CompressedSize, @@ -116,22 +115,22 @@ namespace SharpCompress.Compressors.Rar return totalRead; } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; - public uint CurrentCrc { get { return this.currentCrc; } } + public uint CurrentCrc { get; private set; } public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override long Seek(long offset, SeekOrigin origin) { diff --git a/src/SharpCompress/Compressors/Rar/RarCrcStream.cs b/src/SharpCompress/Compressors/Rar/RarCrcStream.cs index 9922d967..3760d252 100644 --- a/src/SharpCompress/Compressors/Rar/RarCrcStream.cs +++ b/src/SharpCompress/Compressors/Rar/RarCrcStream.cs @@ -15,12 +15,12 @@ namespace SharpCompress.Compressors.Rar { public uint GetCrc() { - return ~this.currentCrc; + return ~currentCrc; } public void ResetCrc() { - this.currentCrc = 0xffffffff; + currentCrc = 0xffffffff; } @@ -29,9 +29,9 @@ namespace SharpCompress.Compressors.Rar { var result = base.Read(buffer, offset, count); if (result != 0) { - this.currentCrc = RarCRC.CheckCrc(this.currentCrc, buffer, offset, result); + currentCrc = RarCRC.CheckCrc(currentCrc, buffer, offset, result); } - else if (GetCrc() != this.readStream.CurrentCrc) + else if (GetCrc() != readStream.CurrentCrc) { // NOTE: we use the last FileHeader in a multipart volume to check CRC throw new InvalidFormatException("file crc mismatch"); diff --git a/src/SharpCompress/Compressors/Rar/RarStream.cs b/src/SharpCompress/Compressors/Rar/RarStream.cs index f118db02..c36f261c 100644 --- a/src/SharpCompress/Compressors/Rar/RarStream.cs +++ b/src/SharpCompress/Compressors/Rar/RarStream.cs @@ -43,19 +43,19 @@ namespace SharpCompress.Compressors.Rar readStream.Dispose(); } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { } - public override long Length { get { return fileHeader.UncompressedSize; } } + public override long Length => fileHeader.UncompressedSize; - public override long Position { get { return fileHeader.UncompressedSize - unpack.DestSize; } set { throw new NotSupportedException(); } } + public override long Position { get => fileHeader.UncompressedSize - unpack.DestSize; set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/Compressors/Rar/Unpack.cs b/src/SharpCompress/Compressors/Rar/Unpack.cs index 9e8b4736..197d6e51 100644 --- a/src/SharpCompress/Compressors/Rar/Unpack.cs +++ b/src/SharpCompress/Compressors/Rar/Unpack.cs @@ -32,7 +32,7 @@ namespace SharpCompress.Compressors.Rar public long DestSize { - get { return destUnpSize; } + get => destUnpSize; set { destUnpSize = value; @@ -40,7 +40,7 @@ namespace SharpCompress.Compressors.Rar } } - public bool Suspended { set { suspended = value; } } + public bool Suspended { set => suspended = value; } public int Char { diff --git a/src/SharpCompress/Converters/DataConverter.cs b/src/SharpCompress/Converters/DataConverter.cs index 29dca6ec..9ea6953f 100644 --- a/src/SharpCompress/Converters/DataConverter.cs +++ b/src/SharpCompress/Converters/DataConverter.cs @@ -146,9 +146,9 @@ namespace SharpCompress.Converters return ret; } - static public DataConverter LittleEndian { get { return BitConverter.IsLittleEndian ? Native : SwapConv; } } + static public DataConverter LittleEndian => BitConverter.IsLittleEndian ? Native : SwapConv; - static public DataConverter BigEndian { get { return BitConverter.IsLittleEndian ? SwapConv : Native; } } + static public DataConverter BigEndian => BitConverter.IsLittleEndian ? SwapConv : Native; static public DataConverter Native { get; } = new CopyConverter(); diff --git a/src/SharpCompress/Crypto/RijndaelEngine.cs b/src/SharpCompress/Crypto/RijndaelEngine.cs index 7aca7aea..6fa73b4b 100644 --- a/src/SharpCompress/Crypto/RijndaelEngine.cs +++ b/src/SharpCompress/Crypto/RijndaelEngine.cs @@ -577,9 +577,9 @@ namespace Org.BouncyCastle.Crypto.Engines throw new ArgumentException("invalid parameter passed to Rijndael init - " + parameters.GetType()); } - public string AlgorithmName { get { return "Rijndael"; } } + public string AlgorithmName => "Rijndael"; - public bool IsPartialBlockOkay { get { return false; } } + public bool IsPartialBlockOkay => false; public int GetBlockSize() { diff --git a/src/SharpCompress/IO/AppendingStream.cs b/src/SharpCompress/IO/AppendingStream.cs index 3c55bfb4..4a024fb1 100644 --- a/src/SharpCompress/IO/AppendingStream.cs +++ b/src/SharpCompress/IO/AppendingStream.cs @@ -14,20 +14,20 @@ namespace SharpCompress.IO this.streams = new Queue(streams); } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotImplementedException(); } - public override long Length { get { throw new NotImplementedException(); } } + public override long Length => throw new NotImplementedException(); - public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/IO/BufferedSubStream.cs b/src/SharpCompress/IO/BufferedSubStream.cs index f98c1c0b..dd913d49 100644 --- a/src/SharpCompress/IO/BufferedSubStream.cs +++ b/src/SharpCompress/IO/BufferedSubStream.cs @@ -30,20 +30,20 @@ namespace SharpCompress.IO public Stream Stream { get; } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/IO/CountingWritableSubStream.cs b/src/SharpCompress/IO/CountingWritableSubStream.cs index 51989b75..f6577177 100644 --- a/src/SharpCompress/IO/CountingWritableSubStream.cs +++ b/src/SharpCompress/IO/CountingWritableSubStream.cs @@ -14,19 +14,19 @@ namespace SharpCompress.IO public ulong Count { get; private set; } - public override bool CanRead { get { return false; } } + public override bool CanRead => false; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return true; } } + public override bool CanWrite => true; public override void Flush() { } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/IO/ListeningStream.cs b/src/SharpCompress/IO/ListeningStream.cs index bbec0a96..1cc694e0 100644 --- a/src/SharpCompress/IO/ListeningStream.cs +++ b/src/SharpCompress/IO/ListeningStream.cs @@ -24,20 +24,20 @@ namespace SharpCompress.IO public Stream Stream { get; } - public override bool CanRead { get { return Stream.CanRead; } } + public override bool CanRead => Stream.CanRead; - public override bool CanSeek { get { return Stream.CanSeek; } } + public override bool CanSeek => Stream.CanSeek; - public override bool CanWrite { get { return Stream.CanWrite; } } + public override bool CanWrite => Stream.CanWrite; public override void Flush() { Stream.Flush(); } - public override long Length { get { return Stream.Length; } } + public override long Length => Stream.Length; - public override long Position { get { return Stream.Position; } set { Stream.Position = value; } } + public override long Position { get => Stream.Position; set => Stream.Position = value; } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/IO/NonDisposingStream.cs b/src/SharpCompress/IO/NonDisposingStream.cs index ebd77787..0c5363d1 100644 --- a/src/SharpCompress/IO/NonDisposingStream.cs +++ b/src/SharpCompress/IO/NonDisposingStream.cs @@ -16,20 +16,20 @@ namespace SharpCompress.IO public Stream Stream { get; } - public override bool CanRead { get { return Stream.CanRead; } } + public override bool CanRead => Stream.CanRead; - public override bool CanSeek { get { return Stream.CanSeek; } } + public override bool CanSeek => Stream.CanSeek; - public override bool CanWrite { get { return Stream.CanWrite; } } + public override bool CanWrite => Stream.CanWrite; public override void Flush() { Stream.Flush(); } - public override long Length { get { return Stream.Length; } } + public override long Length => Stream.Length; - public override long Position { get { return Stream.Position; } set { Stream.Position = value; } } + public override long Position { get => Stream.Position; set => Stream.Position = value; } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/IO/ReadOnlySubStream.cs b/src/SharpCompress/IO/ReadOnlySubStream.cs index c9c1df3c..48609526 100644 --- a/src/SharpCompress/IO/ReadOnlySubStream.cs +++ b/src/SharpCompress/IO/ReadOnlySubStream.cs @@ -32,20 +32,20 @@ namespace SharpCompress.IO public Stream Stream { get; } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { diff --git a/src/SharpCompress/IO/RewindableStream.cs b/src/SharpCompress/IO/RewindableStream.cs index f1f58436..f5a8d11f 100644 --- a/src/SharpCompress/IO/RewindableStream.cs +++ b/src/SharpCompress/IO/RewindableStream.cs @@ -68,18 +68,18 @@ namespace SharpCompress.IO IsRecording = true; } - public override bool CanRead { get { return true; } } + public override bool CanRead => true; public override bool CanSeek => stream.CanSeek; - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; public override void Flush() { throw new NotSupportedException(); } - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); public override long Position { diff --git a/src/SharpCompress/LazyReadOnlyCollection.cs b/src/SharpCompress/LazyReadOnlyCollection.cs index d3e3fff4..ecec3aea 100644 --- a/src/SharpCompress/LazyReadOnlyCollection.cs +++ b/src/SharpCompress/LazyReadOnlyCollection.cs @@ -28,7 +28,7 @@ namespace SharpCompress #region IEnumerator Members - public T Current { get { return lazyReadOnlyCollection.backing[index]; } } + public T Current => lazyReadOnlyCollection.backing[index]; #endregion @@ -46,7 +46,7 @@ namespace SharpCompress #region IEnumerator Members - object IEnumerator.Current { get { return Current; } } + object IEnumerator.Current => Current; public bool MoveNext() { @@ -120,7 +120,7 @@ namespace SharpCompress } } - public bool IsReadOnly { get { return true; } } + public bool IsReadOnly => true; public bool Remove(T item) { diff --git a/src/SharpCompress/ReadOnlyCollection.cs b/src/SharpCompress/ReadOnlyCollection.cs index 7b6f54e9..32c2abc8 100644 --- a/src/SharpCompress/ReadOnlyCollection.cs +++ b/src/SharpCompress/ReadOnlyCollection.cs @@ -33,9 +33,9 @@ namespace SharpCompress collection.CopyTo(array, arrayIndex); } - public int Count { get { return collection.Count; } } + public int Count => collection.Count; - public bool IsReadOnly { get { return true; } } + public bool IsReadOnly => true; public bool Remove(T item) { diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index fd513d26..96fc4e62 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -40,7 +40,7 @@ namespace SharpCompress.Readers /// /// Current file entry /// - public TEntry Entry { get { return entriesForCurrentReadStream.Current; } } + public TEntry Entry => entriesForCurrentReadStream.Current; #region IDisposable Members @@ -217,40 +217,29 @@ namespace SharpCompress.Readers #endregion - IEntry IReader.Entry { get { return Entry; } } + IEntry IReader.Entry => Entry; void IExtractionListener.FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes) { - if (CompressedBytesRead != null) + CompressedBytesRead?.Invoke(this, new CompressedBytesReadEventArgs { - CompressedBytesRead(this, new CompressedBytesReadEventArgs - { - CurrentFilePartCompressedBytesRead = currentPartCompressedBytes, - CompressedBytesRead = compressedReadBytes - }); - } + CurrentFilePartCompressedBytesRead = currentPartCompressedBytes, + CompressedBytesRead = compressedReadBytes + }); } void IExtractionListener.FireFilePartExtractionBegin(string name, long size, long compressedSize) { - if (FilePartExtractionBegin != null) + FilePartExtractionBegin?.Invoke(this, new FilePartExtractionBeginEventArgs { - FilePartExtractionBegin(this, new FilePartExtractionBeginEventArgs - { - CompressedSize = compressedSize, - Size = size, - Name = name - }); - } + CompressedSize = compressedSize, + Size = size, + Name = name + }); } void IReaderExtractionListener.FireEntryExtractionProgress(Entry entry, long bytesTransferred, int iterations) { - if (EntryExtractionProgress != null) - { - EntryExtractionProgress(this, - new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations)) - ); - } + EntryExtractionProgress?.Invoke(this, new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations))); } } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/Rar/MultiVolumeRarReader.cs b/src/SharpCompress/Readers/Rar/MultiVolumeRarReader.cs index b3bf672f..7bc61e2e 100644 --- a/src/SharpCompress/Readers/Rar/MultiVolumeRarReader.cs +++ b/src/SharpCompress/Readers/Rar/MultiVolumeRarReader.cs @@ -83,7 +83,7 @@ namespace SharpCompress.Readers.Rar { } - object IEnumerator.Current { get { return Current; } } + object IEnumerator.Current => Current; public bool MoveNext() { diff --git a/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs b/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs index 63a1c10a..c5f62a44 100644 --- a/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs +++ b/src/SharpCompress/Readers/Rar/NonSeekableStreamFilePart.cs @@ -16,6 +16,6 @@ namespace SharpCompress.Readers.Rar return FileHeader.PackedStream; } - internal override string FilePartName { get { return "Unknown Stream - File Entry: " + FileHeader.FileName; } } + internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName; } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/Rar/RarReader.cs b/src/SharpCompress/Readers/Rar/RarReader.cs index 5ac7d2e2..92e4d737 100644 --- a/src/SharpCompress/Readers/Rar/RarReader.cs +++ b/src/SharpCompress/Readers/Rar/RarReader.cs @@ -22,7 +22,7 @@ namespace SharpCompress.Readers.Rar internal abstract void ValidateArchive(RarVolume archive); - public override RarVolume Volume { get { return volume; } } + public override RarVolume Volume => volume; #region Open diff --git a/src/SharpCompress/Readers/Rar/RarReaderEntry.cs b/src/SharpCompress/Readers/Rar/RarReaderEntry.cs index bf2ec4a5..2e29d615 100644 --- a/src/SharpCompress/Readers/Rar/RarReaderEntry.cs +++ b/src/SharpCompress/Readers/Rar/RarReaderEntry.cs @@ -15,20 +15,20 @@ namespace SharpCompress.Readers.Rar internal RarFilePart Part { get; } - internal override IEnumerable Parts { get { return Part.AsEnumerable(); } } + internal override IEnumerable Parts => Part.AsEnumerable(); - internal override FileHeader FileHeader { get { return Part.FileHeader; } } + internal override FileHeader FileHeader => Part.FileHeader; - public override CompressionType CompressionType { get { return CompressionType.Rar; } } + public override CompressionType CompressionType => CompressionType.Rar; /// /// The compressed file size /// - public override long CompressedSize { get { return Part.FileHeader.CompressedSize; } } + public override long CompressedSize => Part.FileHeader.CompressedSize; /// /// The uncompressed file size /// - public override long Size { get { return Part.FileHeader.UncompressedSize; } } + public override long Size => Part.FileHeader.UncompressedSize; } } \ No newline at end of file diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index e1a001b5..1f5908b1 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -23,7 +23,7 @@ namespace SharpCompress.Writers.Zip private readonly string zipComment; private long streamPosition; private PpmdProperties ppmdProps; - private bool isZip64; + private readonly bool isZip64; public ZipWriter(Stream destination, ZipWriterOptions zipWriterOptions) : base(ArchiveType.Zip) @@ -293,15 +293,15 @@ namespace SharpCompress.Writers.Zip writeStream = GetWriteStream(originalStream); } - public override bool CanRead { get { return false; } } + public override bool CanRead => false; - public override bool CanSeek { get { return false; } } + public override bool CanSeek => false; - public override bool CanWrite { get { return true; } } + public override bool CanWrite => true; - public override long Length { get { throw new NotSupportedException(); } } + public override long Length => throw new NotSupportedException(); - public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } private Stream GetWriteStream(Stream writeStream) { diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index f5ddf543..14eccee1 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -126,13 +126,13 @@ namespace SharpCompress.Test void archive_FilePartExtractionBegin(object sender, FilePartExtractionBeginEventArgs e) { - this.partTotal = e.Size; + partTotal = e.Size; Console.WriteLine("Initializing File Part Extraction: " + e.Name); } void archive_EntryExtractionBegin(object sender, ArchiveExtractionEventArgs e) { - this.entryTotal = e.Item.Size; + entryTotal = e.Item.Size; Console.WriteLine("Initializing File Entry Extraction: " + e.Item.Key); } @@ -156,7 +156,7 @@ namespace SharpCompress.Test ResetScratch(); using (var archive = ArchiveFactory.Open(path)) { - this.totalSize = archive.TotalUncompressSize; + totalSize = archive.TotalUncompressSize; archive.EntryExtractionBegin += Archive_EntryExtractionBeginEx; archive.EntryExtractionEnd += Archive_EntryExtractionEndEx; archive.CompressedBytesRead += Archive_CompressedBytesReadEx; @@ -179,19 +179,19 @@ namespace SharpCompress.Test private void Archive_EntryExtractionEndEx(object sender, ArchiveExtractionEventArgs e) { - this.partTotal += e.Item.Size; + partTotal += e.Item.Size; } private void Archive_CompressedBytesReadEx(object sender, CompressedBytesReadEventArgs e) { - string percentage = this.entryTotal.HasValue ? this.CreatePercentage(e.CompressedBytesRead, this.entryTotal.Value).ToString() : "-"; - string tortalPercentage = this.CreatePercentage(this.partTotal + e.CompressedBytesRead, this.totalSize).ToString(); + string percentage = entryTotal.HasValue ? CreatePercentage(e.CompressedBytesRead, entryTotal.Value).ToString() : "-"; + string tortalPercentage = CreatePercentage(partTotal + e.CompressedBytesRead, totalSize).ToString(); Console.WriteLine(@"Read Compressed File Progress: {0}% Total Progress {1}%", percentage, tortalPercentage); } private void Archive_EntryExtractionBeginEx(object sender, ArchiveExtractionEventArgs e) { - this.entryTotal = e.Item.Size; + entryTotal = e.Item.Size; } private int CreatePercentage(long n, long d) diff --git a/tests/SharpCompress.Test/ForwardOnlyStream.cs b/tests/SharpCompress.Test/ForwardOnlyStream.cs index 53f4a99a..d9cf85e3 100644 --- a/tests/SharpCompress.Test/ForwardOnlyStream.cs +++ b/tests/SharpCompress.Test/ForwardOnlyStream.cs @@ -31,15 +31,12 @@ namespace SharpCompress.Test throw new NotSupportedException(); } - public override long Length - { - get { throw new NotSupportedException(); } - } + public override long Length => throw new NotSupportedException(); public override long Position { - get { throw new NotSupportedException(); } - set { throw new NotSupportedException(); } + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) diff --git a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs index 64d71d09..7f6e43c6 100644 --- a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs +++ b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs @@ -86,7 +86,7 @@ namespace SharpCompress.Test Assert.Equal(size, tarStream.Length); using (var entryStream = archiveEntry.OpenEntryStream()) { - var result = SharpCompress.Archives.Tar.TarArchive.IsTarFile(entryStream); + var result = Archives.Tar.TarArchive.IsTarFile(entryStream); } Assert.Equal(size, tarStream.Length); using (var entryStream = archiveEntry.OpenEntryStream()) diff --git a/tests/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs b/tests/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs index 99ed66ea..0a5908d3 100644 --- a/tests/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs +++ b/tests/SharpCompress.Test/Rar/RarHeaderFactoryTest.cs @@ -11,7 +11,7 @@ namespace SharpCompress.Test.Rar /// public class RarHeaderFactoryTest : TestBase { - private RarHeaderFactory rarHeaderFactory; + private readonly RarHeaderFactory rarHeaderFactory; public RarHeaderFactoryTest() { diff --git a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs index df0666a0..cb34a873 100644 --- a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs +++ b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs @@ -104,7 +104,7 @@ namespace SharpCompress.Test string scratchPath = Path.Combine(SCRATCH_FILES_PATH, "Tar.tar"); string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.noEmptyDirs.tar"); - base.ResetScratch(); + ResetScratch(); using (var archive = TarArchive.Create()) { archive.AddAllFromDirectory(ORIGINAL_FILES_PATH); @@ -120,7 +120,7 @@ namespace SharpCompress.Test string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.mod.tar"); string modified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.noEmptyDirs.tar"); - base.ResetScratch(); + ResetScratch(); using (var archive = TarArchive.Open(unmodified)) { archive.AddEntry("jpg\\test.jpg", jpg); @@ -136,7 +136,7 @@ namespace SharpCompress.Test string modified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.mod.tar"); string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.noEmptyDirs.tar"); - base.ResetScratch(); + ResetScratch(); using (var archive = TarArchive.Open(unmodified)) { var entry = archive.Entries.Single(x => x.Key.EndsWith("jpg")); diff --git a/tests/SharpCompress.Test/TestBase.cs b/tests/SharpCompress.Test/TestBase.cs index f8e4fd91..496cff41 100644 --- a/tests/SharpCompress.Test/TestBase.cs +++ b/tests/SharpCompress.Test/TestBase.cs @@ -232,7 +232,7 @@ namespace SharpCompress.Test } } - private static object lockObject = new object(); + private static readonly object lockObject = new object(); public TestBase() { diff --git a/tests/SharpCompress.Test/TestStream.cs b/tests/SharpCompress.Test/TestStream.cs index b6c1abf5..f9e0b713 100644 --- a/tests/SharpCompress.Test/TestStream.cs +++ b/tests/SharpCompress.Test/TestStream.cs @@ -4,12 +4,9 @@ namespace SharpCompress.Test { public class TestStream : Stream { - private Stream stream; - private bool read; - private bool write; - private bool seek; + private readonly Stream stream; - public TestStream(Stream stream) + public TestStream(Stream stream) : this(stream, true, true, true) { } @@ -19,9 +16,9 @@ namespace SharpCompress.Test public TestStream(Stream stream, bool read, bool write, bool seek) { this.stream = stream; - this.read = read; - this.write = write; - this.seek = seek; + CanRead = read; + CanWrite = write; + CanSeek = seek; } protected override void Dispose(bool disposing) @@ -31,36 +28,24 @@ namespace SharpCompress.Test IsDisposed = true; } - public override bool CanRead - { - get { return read; } - } + public override bool CanRead { get; } - public override bool CanSeek - { - get { return seek; } - } + public override bool CanSeek { get; } - public override bool CanWrite - { - get { return write; } - } + public override bool CanWrite { get; } - public override void Flush() + public override void Flush() { stream.Flush(); } - public override long Length - { - get { return stream.Length; } - } + public override long Length => stream.Length; - public override long Position + public override long Position { - get { return stream.Position; } - set { stream.Position = value; } - } + get => stream.Position; + set => stream.Position = value; + } public override int Read(byte[] buffer, int offset, int count) { diff --git a/tests/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs index ff1cf827..ea2de961 100644 --- a/tests/SharpCompress.Test/WriterTests.cs +++ b/tests/SharpCompress.Test/WriterTests.cs @@ -9,7 +9,7 @@ namespace SharpCompress.Test { public class WriterTests : TestBase { - private ArchiveType type; + private readonly ArchiveType type; protected WriterTests(ArchiveType type) { diff --git a/tests/SharpCompress.Test/Zip/Zip64Tests.cs b/tests/SharpCompress.Test/Zip/Zip64Tests.cs index d626ae71..d1ce0545 100644 --- a/tests/SharpCompress.Test/Zip/Zip64Tests.cs +++ b/tests/SharpCompress.Test/Zip/Zip64Tests.cs @@ -139,7 +139,7 @@ namespace SharpCompress.Test var opts = new ZipWriterOptions(CompressionType.Deflate) { UseZip64 = set_zip64 }; // Use no compression to ensure we hit the limits (actually inflates a bit, but seems better than using method==Store) - var eo = new ZipWriterEntryOptions() { DeflateCompressionLevel = SharpCompress.Compressors.Deflate.CompressionLevel.None }; + var eo = new ZipWriterEntryOptions() { DeflateCompressionLevel = Compressors.Deflate.CompressionLevel.None }; using (var zip = File.OpenWrite(filename)) using(var st = forward_only ? (Stream)new NonSeekableStream(zip) : zip) @@ -203,11 +203,11 @@ namespace SharpCompress.Test { private readonly Stream stream; public NonSeekableStream(Stream s) { stream = s; } - public override bool CanRead { get { return stream.CanRead; } } - public override bool CanSeek { get { return false; } } - public override bool CanWrite { get { return stream.CanWrite; } } - public override long Length { get { throw new NotImplementedException(); } } - public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } + public override bool CanRead => stream.CanRead; + public override bool CanSeek => false; + public override bool CanWrite => stream.CanWrite; + public override long Length => throw new NotImplementedException(); + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public override void Flush() { stream.Flush(); } public override int Read(byte[] buffer, int offset, int count) diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index d3d8832e..9ac4737f 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -148,7 +148,7 @@ namespace SharpCompress.Test string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.noEmptyDirs.zip"); string modified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod.zip"); - base.ResetScratch(); + ResetScratch(); using (var archive = ZipArchive.Open(unmodified)) { var entry = archive.Entries.Single(x => x.Key.EndsWith("jpg")); @@ -166,7 +166,7 @@ namespace SharpCompress.Test string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod.zip"); string modified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod2.zip"); - base.ResetScratch(); + ResetScratch(); using (var archive = ZipArchive.Open(unmodified)) { archive.AddEntry("jpg\\test.jpg", jpg); @@ -245,7 +245,7 @@ namespace SharpCompress.Test [Fact] public void Zip_Create_New() { - base.ResetScratch(); + ResetScratch(); foreach (var file in Directory.EnumerateFiles(ORIGINAL_FILES_PATH, "*.*", SearchOption.AllDirectories)) { var newFileName = file.Substring(ORIGINAL_FILES_PATH.Length); @@ -276,7 +276,7 @@ namespace SharpCompress.Test [Fact] public void Zip_Create_New_Add_Remove() { - base.ResetScratch(); + ResetScratch(); foreach (var file in Directory.EnumerateFiles(ORIGINAL_FILES_PATH, "*.*", SearchOption.AllDirectories)) { var newFileName = file.Substring(ORIGINAL_FILES_PATH.Length); @@ -351,7 +351,7 @@ namespace SharpCompress.Test { string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.noEmptyDirs.zip"); - base.ResetScratch(); + ResetScratch(); ZipArchive a = ZipArchive.Open(unmodified); int count = 0; foreach (var e in a.Entries) @@ -411,13 +411,7 @@ namespace SharpCompress.Test class NonSeekableMemoryStream : MemoryStream { - public override bool CanSeek - { - get - { - return false; - } - } + public override bool CanSeek => false; } [Fact] diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index 8f945a9f..886e2c14 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -222,13 +222,7 @@ namespace SharpCompress.Test class NonSeekableMemoryStream : MemoryStream { - public override bool CanSeek - { - get - { - return false; - } - } + public override bool CanSeek => false; } [Fact] From 057ac9b0019c027a3a03d5abfaaf7dd32dc37b69 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 11:03:31 +0100 Subject: [PATCH 28/49] Enable test --- .../SharpCompress.Test/Rar/RarReaderTests.cs | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index d51366fa..53db8fd0 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -47,20 +47,28 @@ namespace SharpCompress.Test "EncryptedParts.part06.rar"}; - ResetScratch(); - using (var reader = RarReader.Open(testArchives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) - .Select(p => File.OpenRead(p)))) - { - while (reader.MoveToNextEntry()) - { - reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions() - { - ExtractFullPath = true, - Overwrite = true - }); - } - } - VerifyFiles(); + Assert.Throws(() => + { + ResetScratch(); + using (var reader = RarReader.Open(testArchives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) + .Select(p => File.OpenRead(p)), + new ReaderOptions() + { + Password = "test" + })) + { + while (reader.MoveToNextEntry()) + { + reader.WriteEntryToDirectory(SCRATCH_FILES_PATH, + new ExtractionOptions() + { + ExtractFullPath = true, + Overwrite = true + }); + } + } + VerifyFiles(); + }); } [Fact] From d0302898e02c44d416d1351a27d14939fba9d2bf Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 13:33:12 +0100 Subject: [PATCH 29/49] Add back net45,net35 and cake --- appveyor.yml | 14 +- build.cake | 52 ++++++ build.ps1 | 228 +++++++++++++++++++++++++ src/SharpCompress/SharpCompress.csproj | 7 +- 4 files changed, 288 insertions(+), 13 deletions(-) create mode 100644 build.cake create mode 100644 build.ps1 diff --git a/appveyor.yml b/appveyor.yml index 3b4015a0..88d8dfc0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,18 +11,8 @@ branches: nuget: disable_publish_on_pr: true -before_build: - - cmd: dotnet restore - -build: - parallel: true - verbosity: minimal - -after_build: -- dotnet pack "src\SharpCompress\SharpCompress.csproj" -c Release - -test_script: -- dotnet test --no-build .\tests\SharpCompress.Test\SharpCompress.Test.csproj +build_script: +- ps: .\build.ps1 artifacts: - path: src\SharpCompress\bin\Release\*.nupkg \ No newline at end of file diff --git a/build.cake b/build.cake new file mode 100644 index 00000000..01247e9f --- /dev/null +++ b/build.cake @@ -0,0 +1,52 @@ +var target = Argument("target", "Default"); +var tag = Argument("tag", "cake"); + +Task("Restore") + .Does(() => +{ + DotNetCoreRestore("."); +}); + +Task("Build") + .Does(() => +{ + MSBuild("./sharpcompress.sln", c => c + .SetConfiguration("Release") + .SetVerbosity(Verbosity.Minimal) + .UseToolVersion(MSBuildToolVersion.VS2017)); +}); + +Task("Test") + .Does(() => +{ + var files = GetFiles("tests/**/*.csproj"); + foreach(var file in files) + { + DotNetCoreTest(file.ToString()); + } +}); + +Task("Pack") + .IsDependentOn("Build") + .Does(() => +{ + MSBuild("src/SharpCompress/SharpCompress.csproj", c => c + .SetConfiguration("Release") + .SetVerbosity(Verbosity.Minimal) + .UseToolVersion(MSBuildToolVersion.VS2017) + .WithProperty("NoBuild", "true") + .WithTarget("Pack")); +}); + +Task("Default") + .IsDependentOn("Restore") + .IsDependentOn("Build") + .IsDependentOn("Test") + .IsDependentOn("Pack"); + + Task("Rebuild") + .IsDependentOn("Restore") + .IsDependentOn("Build"); + + +RunTarget(target); \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 00000000..6d04c8cf --- /dev/null +++ b/build.ps1 @@ -0,0 +1,228 @@ +########################################################################## +# This is the Cake bootstrapper script for PowerShell. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +<# + +.SYNOPSIS +This is a Powershell script to bootstrap a Cake build. + +.DESCRIPTION +This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) +and execute your Cake build script with the parameters you provide. + +.PARAMETER Script +The build script to execute. +.PARAMETER Target +The build script target to run. +.PARAMETER Configuration +The build configuration to use. +.PARAMETER Verbosity +Specifies the amount of information to be displayed. +.PARAMETER Experimental +Tells Cake to use the latest Roslyn release. +.PARAMETER WhatIf +Performs a dry run of the build script. +No tasks will be executed. +.PARAMETER Mono +Tells Cake to use the Mono scripting engine. +.PARAMETER SkipToolPackageRestore +Skips restoring of packages. +.PARAMETER ScriptArgs +Remaining arguments are added here. + +.LINK +http://cakebuild.net + +#> + +[CmdletBinding()] +Param( + [string]$Script = "build.cake", + [string]$Target = "Default", + [ValidateSet("Release", "Debug")] + [string]$Configuration = "Release", + [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] + [string]$Verbosity = "Verbose", + [switch]$Experimental, + [Alias("DryRun","Noop")] + [switch]$WhatIf, + [switch]$Mono, + [switch]$SkipToolPackageRestore, + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$ScriptArgs +) + +[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null +function MD5HashFile([string] $filePath) +{ + if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) + { + return $null + } + + [System.IO.Stream] $file = $null; + [System.Security.Cryptography.MD5] $md5 = $null; + try + { + $md5 = [System.Security.Cryptography.MD5]::Create() + $file = [System.IO.File]::OpenRead($filePath) + return [System.BitConverter]::ToString($md5.ComputeHash($file)) + } + finally + { + if ($file -ne $null) + { + $file.Dispose() + } + } +} + +Write-Host "Preparing to run build script..." + +if(!$PSScriptRoot){ + $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent +} + +$TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$ADDINS_DIR = Join-Path $TOOLS_DIR "addins" +$MODULES_DIR = Join-Path $TOOLS_DIR "modules" +$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" +$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" +$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" +$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" +$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" +$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" +$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" + +# Should we use mono? +$UseMono = ""; +if($Mono.IsPresent) { + Write-Verbose -Message "Using the Mono based scripting engine." + $UseMono = "-mono" +} + +# Should we use the new Roslyn? +$UseExperimental = ""; +if($Experimental.IsPresent -and !($Mono.IsPresent)) { + Write-Verbose -Message "Using experimental version of Roslyn." + $UseExperimental = "-experimental" +} + +# Is this a dry run? +$UseDryRun = ""; +if($WhatIf.IsPresent) { + $UseDryRun = "-dryrun" +} + +# Make sure tools folder exists +if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { + Write-Verbose -Message "Creating tools directory..." + New-Item -Path $TOOLS_DIR -Type directory | out-null +} + +# Make sure that packages.config exist. +if (!(Test-Path $PACKAGES_CONFIG)) { + Write-Verbose -Message "Downloading packages.config..." + try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { + Throw "Could not download packages.config." + } +} + +# Try find NuGet.exe in path if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Trying to find nuget.exe in PATH..." + $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } + $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 + if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { + Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." + $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName + } +} + +# Try download NuGet.exe if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Downloading NuGet.exe..." + try { + (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) + } catch { + Throw "Could not download NuGet.exe." + } +} + +# Save nuget.exe path to environment to be available to child processed +$ENV:NUGET_EXE = $NUGET_EXE + +# Restore tools from NuGet? +if(-Not $SkipToolPackageRestore.IsPresent) { + Push-Location + Set-Location $TOOLS_DIR + + # Check for changes in packages.config and remove installed tools if true. + [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) + if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or + ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { + Write-Verbose -Message "Missing or changed package.config hash..." + Remove-Item * -Recurse -Exclude packages.config,nuget.exe + } + + Write-Verbose -Message "Restoring tools from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occured while restoring NuGet tools." + } + else + { + $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" + } + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore addins from NuGet +if (Test-Path $ADDINS_PACKAGES_CONFIG) { + Push-Location + Set-Location $ADDINS_DIR + + Write-Verbose -Message "Restoring addins from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occured while restoring NuGet addins." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore modules from NuGet +if (Test-Path $MODULES_PACKAGES_CONFIG) { + Push-Location + Set-Location $MODULES_DIR + + Write-Verbose -Message "Restoring modules from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occured while restoring NuGet modules." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Make sure that Cake has been installed. +if (!(Test-Path $CAKE_EXE)) { + Throw "Could not find Cake.exe at $CAKE_EXE" +} + +# Start Cake +Write-Host "Running build script..." +Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" +exit $LASTEXITCODE \ No newline at end of file diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 48bf9708..3313ed44 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -7,7 +7,8 @@ 0.16.0.0 0.16.0.0 Adam Hathcock - netstandard1.0;netstandard1.3 + net45;net35;netstandard1.0;netstandard1.3 + $(LibraryFrameworks) true true SharpCompress @@ -27,4 +28,8 @@ $(DefineConstants);NO_FILE;NO_CRYPTO;SILVERLIGHT + + $(DefineConstants);NO_FILE;NO_CRYPTO;SILVERLIGHT + + From 1c6c344b6b43f0f9bcd2252463c32d6e1f681ec7 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 15:45:29 +0100 Subject: [PATCH 30/49] Tests don't run on appveyor --- build.cake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.cake b/build.cake index 01247e9f..0621c813 100644 --- a/build.cake +++ b/build.cake @@ -41,12 +41,12 @@ Task("Pack") Task("Default") .IsDependentOn("Restore") .IsDependentOn("Build") - .IsDependentOn("Test") .IsDependentOn("Pack"); - Task("Rebuild") + Task("RunTests") .IsDependentOn("Restore") - .IsDependentOn("Build"); + .IsDependentOn("Build") + .IsDependentOn("Test"); RunTarget(target); \ No newline at end of file From f6db1148658649ced42222ccacd385065af9ef05 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 15:47:53 +0100 Subject: [PATCH 31/49] Remove console writelines --- tests/SharpCompress.Test/ArchiveTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 14eccee1..b6d63c9f 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -95,9 +95,9 @@ namespace SharpCompress.Test ResetScratch(); using (var archive = ArchiveFactory.Open(path)) { - archive.EntryExtractionBegin += archive_EntryExtractionBegin; - archive.FilePartExtractionBegin += archive_FilePartExtractionBegin; - archive.CompressedBytesRead += archive_CompressedBytesRead; + //archive.EntryExtractionBegin += archive_EntryExtractionBegin; + //archive.FilePartExtractionBegin += archive_FilePartExtractionBegin; + //archive.CompressedBytesRead += archive_CompressedBytesRead; foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) { @@ -157,9 +157,9 @@ namespace SharpCompress.Test using (var archive = ArchiveFactory.Open(path)) { totalSize = archive.TotalUncompressSize; - archive.EntryExtractionBegin += Archive_EntryExtractionBeginEx; - archive.EntryExtractionEnd += Archive_EntryExtractionEndEx; - archive.CompressedBytesRead += Archive_CompressedBytesReadEx; + //archive.EntryExtractionBegin += Archive_EntryExtractionBeginEx; + //archive.EntryExtractionEnd += Archive_EntryExtractionEndEx; + //archive.CompressedBytesRead += Archive_CompressedBytesReadEx; foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) { From 60370b85398552e427d5fa952cff8560cde70fc7 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 19 May 2017 15:51:06 +0100 Subject: [PATCH 32/49] don't run appveyor tests --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 88d8dfc0..ff3204f7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,5 +14,7 @@ nuget: build_script: - ps: .\build.ps1 +test: off + artifacts: - path: src\SharpCompress\bin\Release\*.nupkg \ No newline at end of file From 8d3fc3533bad74f3cf5bd87ae9b45b98bdf05554 Mon Sep 17 00:00:00 2001 From: Dan Baumberger Date: Fri, 19 May 2017 08:36:11 -0700 Subject: [PATCH 33/49] Issue #230: preserve the compression method when getting a compressed stream for encrypted ZIP archives. --- src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs index 2f1f80f2..64fc8427 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs @@ -14,7 +14,15 @@ namespace SharpCompress.Archives.Zip public virtual Stream OpenEntryStream() { - return Parts.Single().GetCompressedStream(); + var filePart = Parts.Single() as ZipFilePart; + var compressionMethod = filePart.Header.CompressionMethod; + var stream = filePart.GetCompressedStream(); + if (filePart.Header.CompressionMethod != compressionMethod) + { + filePart.Header.CompressionMethod = compressionMethod; + } + + return stream; } #region IArchiveEntry Members From 575f10f766756161157a2e1bcf3246371c1fe6f5 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 19 May 2017 16:37:20 -0700 Subject: [PATCH 34/49] Default zip ver to 20 (deflate/encyption), fixes #164 --- src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs index 3e29a0f5..fd8f4ba4 100644 --- a/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs +++ b/src/SharpCompress/Writers/Zip/ZipCentralDirectoryEntry.cs @@ -30,7 +30,7 @@ namespace SharpCompress.Writers.Zip var decompressedvalue = zip64 ? uint.MaxValue : (uint)Decompressed; var headeroffsetvalue = zip64 ? uint.MaxValue : (uint)HeaderOffset; var extralength = zip64 ? (2 + 2 + 8 + 8 + 8 + 4) : 0; - var version = (byte)(zip64 ? 45 : 10); + var version = (byte)(zip64 ? 45 : 20); // Version 20 required for deflate/encryption HeaderFlags flags = HeaderFlags.UTF8; if (!outputStream.CanSeek) From e53f2cac4acb25d66a95a54f5e39d6bcc986f2f8 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 22 May 2017 08:58:52 +0100 Subject: [PATCH 35/49] Mark for 0.16.0 --- README.md | 9 +++++++++ build.cake | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a8ad5858..797bb08c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,15 @@ I'm always looking for help or ideas. Please submit code or email with ideas. Un ## Version Log +### Version 0.16.0 + +* Breaking - [Progress Event Tracking rethink](https://github.com/adamhathcock/sharpcompress/pull/226) +* Update to VS2017 - [VS2017](https://github.com/adamhathcock/sharpcompress/pull/231) - Framework targets have been changed. +* New - [Add Zip64 writing](https://github.com/adamhathcock/sharpcompress/pull/211) +* [Fix invalid/mismatching Zip version flags.](https://github.com/adamhathcock/sharpcompress/issues/164) - This allows nuget/System.IO.Packaging to read zip files generated by SharpCompress +* [Fix 7Zip directory hiding](https://github.com/adamhathcock/sharpcompress/pull/215/files) +* [Verify RAR CRC headers](https://github.com/adamhathcock/sharpcompress/pull/220) + ### Version 0.15.2 * [Fix invalid headers](https://github.com/adamhathcock/sharpcompress/pull/210) - fixes an issue creating large-ish zip archives that was introduced with zip64 reading. diff --git a/build.cake b/build.cake index 0621c813..e501fbee 100644 --- a/build.cake +++ b/build.cake @@ -45,8 +45,7 @@ Task("Default") Task("RunTests") .IsDependentOn("Restore") - .IsDependentOn("Build") - .IsDependentOn("Test"); + .IsDependentOn("Build"); RunTarget(target); \ No newline at end of file From 63d5503e12e76090e1e1d5586dac1de7416113ee Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 22 May 2017 09:06:33 +0100 Subject: [PATCH 36/49] forgot to actually add tests to script --- build.cake | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/build.cake b/build.cake index e501fbee..50786fab 100644 --- a/build.cake +++ b/build.cake @@ -22,7 +22,12 @@ Task("Test") var files = GetFiles("tests/**/*.csproj"); foreach(var file in files) { - DotNetCoreTest(file.ToString()); + var settings = new DotNetCoreTestSettings + { + Configuration = "Release" + }; + + DotNetCoreTest(file.ToString(), settings); } }); @@ -41,11 +46,13 @@ Task("Pack") Task("Default") .IsDependentOn("Restore") .IsDependentOn("Build") + .IsDependentOn("Test") .IsDependentOn("Pack"); Task("RunTests") .IsDependentOn("Restore") - .IsDependentOn("Build"); + .IsDependentOn("Build") + .IsDependentOn("Test"); RunTarget(target); \ No newline at end of file From 0f2d325f20d448cfbcb9e011af6f41a7343b29be Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 22 May 2017 09:08:16 +0100 Subject: [PATCH 37/49] oh yeah, appveyor doesn't like the tests --- build.cake | 1 - 1 file changed, 1 deletion(-) diff --git a/build.cake b/build.cake index 50786fab..ec985ac9 100644 --- a/build.cake +++ b/build.cake @@ -46,7 +46,6 @@ Task("Pack") Task("Default") .IsDependentOn("Restore") .IsDependentOn("Build") - .IsDependentOn("Test") .IsDependentOn("Pack"); Task("RunTests") From bc97d325ca6edc2366f68236fd891bdb58c32b71 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 22 May 2017 10:55:15 +0100 Subject: [PATCH 38/49] Normalize Rar keys --- .../Common/Rar/Headers/FileHeader.cs | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/SharpCompress/Common/Rar/Headers/FileHeader.cs b/src/SharpCompress/Common/Rar/Headers/FileHeader.cs index b870ed84..f0359a24 100644 --- a/src/SharpCompress/Common/Rar/Headers/FileHeader.cs +++ b/src/SharpCompress/Common/Rar/Headers/FileHeader.cs @@ -165,25 +165,13 @@ namespace SharpCompress.Common.Rar.Headers #if NO_FILE return path.Replace('\\', '/'); #else - switch (os) + if (Path.DirectorySeparatorChar == '/') { - case HostOS.MacOS: - case HostOS.Unix: - { - if (Path.DirectorySeparatorChar == '\\') - { - return path.Replace('/', '\\'); - } - } - break; - default: - { - if (Path.DirectorySeparatorChar == '/') - { - return path.Replace('\\', '/'); - } - } - break; + return path.Replace('\\', '/'); + } + else if (Path.DirectorySeparatorChar == '\\') + { + return path.Replace('/', '\\'); } return path; #endif From 313c044c41b7509759267ee3a951eb40a5948edd Mon Sep 17 00:00:00 2001 From: Dan Baumberger Date: Tue, 23 May 2017 07:44:45 -0700 Subject: [PATCH 39/49] Added a unit test for the WinZipAes multiple OpenEntryStream() bug. --- .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 18 ++++++++++++++++++ .../Archives/Zip.deflate.WinzipAES2.zip | Bin 0 -> 60801 bytes 2 files changed, 18 insertions(+) create mode 100644 tests/TestArchives/Archives/Zip.deflate.WinzipAES2.zip diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 9ac4737f..ba045ec6 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -324,6 +324,24 @@ namespace SharpCompress.Test VerifyFiles(); } + [Fact] + public void Zip_Deflate_WinzipAES_MultiOpenEntryStream() + { + ResetScratch(); + using (var reader = ZipArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES2.zip"), new ReaderOptions() + { + Password = "test" + })) + { + foreach (var entry in reader.Entries.Where(x => !x.IsDirectory)) + { + var stream = entry.OpenEntryStream(); + Assert.NotNull(stream); + var ex = Record.Exception(() => stream = entry.OpenEntryStream()); + Assert.Null(ex); + } + } + } [Fact] public void Zip_BZip2_Pkware_Read() diff --git a/tests/TestArchives/Archives/Zip.deflate.WinzipAES2.zip b/tests/TestArchives/Archives/Zip.deflate.WinzipAES2.zip new file mode 100644 index 0000000000000000000000000000000000000000..523670fe38ea667ff8b7d128d54bbd9a0a03a293 GIT binary patch literal 60801 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

S*MB*2U)8X77FEI?;D;EnpVFmF{%jALAIn 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 z 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 literal 0 HcmV?d00001 From 9d9d4912454849ed8f32f2dc5d09265013b2f633 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 23 May 2017 16:10:15 +0100 Subject: [PATCH 40/49] Slightly better fix for https://github.com/adamhathcock/sharpcompress/pull/235 --- src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs | 10 +--------- .../Common/Zip/StreamingZipFilePart.cs | 2 +- src/SharpCompress/Common/Zip/ZipFilePart.cs | 13 ++++++------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs index 64fc8427..2f1f80f2 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchiveEntry.cs @@ -14,15 +14,7 @@ namespace SharpCompress.Archives.Zip public virtual Stream OpenEntryStream() { - var filePart = Parts.Single() as ZipFilePart; - var compressionMethod = filePart.Header.CompressionMethod; - var stream = filePart.GetCompressedStream(); - if (filePart.Header.CompressionMethod != compressionMethod) - { - filePart.Header.CompressionMethod = compressionMethod; - } - - return stream; + return Parts.Single().GetCompressedStream(); } #region IArchiveEntry Members diff --git a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs index 576b23d1..84c87700 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs @@ -25,7 +25,7 @@ namespace SharpCompress.Common.Zip { return Stream.Null; } - decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream())); + decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream()), Header.CompressionMethod); if (LeaveStreamOpen) { return new NonDisposingStream(decompressionStream); diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs index 7038876d..2e33b503 100644 --- a/src/SharpCompress/Common/Zip/ZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs @@ -32,7 +32,7 @@ namespace SharpCompress.Common.Zip { return Stream.Null; } - Stream decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream())); + Stream decompressionStream = CreateDecompressionStream(GetCryptoStream(CreateBaseStream()), Header.CompressionMethod); if (LeaveStreamOpen) { return new NonDisposingStream(decompressionStream); @@ -53,9 +53,9 @@ namespace SharpCompress.Common.Zip protected bool LeaveStreamOpen => FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor) || Header.IsZip64; - protected Stream CreateDecompressionStream(Stream stream) + protected Stream CreateDecompressionStream(Stream stream, ZipCompressionMethod method) { - switch (Header.CompressionMethod) + switch (method) { case ZipCompressionMethod.None: { @@ -102,9 +102,9 @@ namespace SharpCompress.Common.Zip { throw new InvalidFormatException("Winzip data length is not 7."); } - ushort method = DataConverter.LittleEndian.GetUInt16(data.DataBytes, 0); + ushort compressedMethod = DataConverter.LittleEndian.GetUInt16(data.DataBytes, 0); - if (method != 0x01 && method != 0x02) + if (compressedMethod != 0x01 && compressedMethod != 0x02) { throw new InvalidFormatException("Unexpected vendor version number for WinZip AES metadata"); } @@ -114,8 +114,7 @@ namespace SharpCompress.Common.Zip { throw new InvalidFormatException("Unexpected vendor ID for WinZip AES metadata"); } - Header.CompressionMethod = (ZipCompressionMethod)DataConverter.LittleEndian.GetUInt16(data.DataBytes, 5); - return CreateDecompressionStream(stream); + return CreateDecompressionStream(stream, (ZipCompressionMethod)DataConverter.LittleEndian.GetUInt16(data.DataBytes, 5)); } default: { From 41added690ba7a002aab6a88dcaa33fbad87b74c Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 23 May 2017 16:15:47 +0100 Subject: [PATCH 41/49] Private setter clean up --- src/SharpCompress/Common/ArchiveExtractionEventArgs.cs | 2 +- src/SharpCompress/Common/Rar/RarFilePart.cs | 4 ++-- src/SharpCompress/Common/ReaderExtractionEventArgs.cs | 4 ++-- src/SharpCompress/Common/Zip/Headers/ZipHeader.cs | 2 +- src/SharpCompress/Common/Zip/ZipFilePart.cs | 2 +- src/SharpCompress/Compressors/Rar/Decode/AudioVariables.cs | 2 +- src/SharpCompress/Compressors/Rar/Decode/Decode.cs | 6 +++--- src/SharpCompress/Compressors/Rar/VM/VMPreparedCommand.cs | 4 ++-- .../Compressors/Rar/VM/VMStandardFilterSignature.cs | 6 +++--- src/SharpCompress/Readers/ReaderProgress.cs | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/SharpCompress/Common/ArchiveExtractionEventArgs.cs b/src/SharpCompress/Common/ArchiveExtractionEventArgs.cs index 7295fdf4..b1c9fc75 100644 --- a/src/SharpCompress/Common/ArchiveExtractionEventArgs.cs +++ b/src/SharpCompress/Common/ArchiveExtractionEventArgs.cs @@ -9,6 +9,6 @@ namespace SharpCompress.Common Item = entry; } - public T Item { get; private set; } + public T Item { get; } } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Rar/RarFilePart.cs b/src/SharpCompress/Common/Rar/RarFilePart.cs index c9d00dc0..d52fedea 100644 --- a/src/SharpCompress/Common/Rar/RarFilePart.cs +++ b/src/SharpCompress/Common/Rar/RarFilePart.cs @@ -14,9 +14,9 @@ namespace SharpCompress.Common.Rar FileHeader = fh; } - internal MarkHeader MarkHeader { get; private set; } + internal MarkHeader MarkHeader { get; } - internal FileHeader FileHeader { get; private set; } + internal FileHeader FileHeader { get; } internal override Stream GetRawStream() { diff --git a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs index 3b9ac17f..aadc563c 100644 --- a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs +++ b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs @@ -11,7 +11,7 @@ namespace SharpCompress.Common ReaderProgress = readerProgress; } - public T Item { get; private set; } - public ReaderProgress ReaderProgress { get; private set; } + public T Item { get; } + public ReaderProgress ReaderProgress { get; } } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Zip/Headers/ZipHeader.cs b/src/SharpCompress/Common/Zip/Headers/ZipHeader.cs index ba71778b..3834d225 100644 --- a/src/SharpCompress/Common/Zip/Headers/ZipHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/ZipHeader.cs @@ -10,7 +10,7 @@ namespace SharpCompress.Common.Zip.Headers HasData = true; } - internal ZipHeaderType ZipHeaderType { get; private set; } + internal ZipHeaderType ZipHeaderType { get; } internal abstract void Read(BinaryReader reader); diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs index 2e33b503..8e09461e 100644 --- a/src/SharpCompress/Common/Zip/ZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs @@ -21,7 +21,7 @@ namespace SharpCompress.Common.Zip BaseStream = stream; } - internal Stream BaseStream { get; private set; } + internal Stream BaseStream { get; } internal ZipFileEntry Header { get; set; } internal override string FilePartName => Header.Name; diff --git a/src/SharpCompress/Compressors/Rar/Decode/AudioVariables.cs b/src/SharpCompress/Compressors/Rar/Decode/AudioVariables.cs index 0189009a..cb70b1fd 100644 --- a/src/SharpCompress/Compressors/Rar/Decode/AudioVariables.cs +++ b/src/SharpCompress/Compressors/Rar/Decode/AudioVariables.cs @@ -7,7 +7,7 @@ namespace SharpCompress.Compressors.Rar.Decode Dif = new int[11]; } - internal int[] Dif { get; private set; } + internal int[] Dif { get; } internal int ByteCount { get; set; } internal int D1 { get; set; } diff --git a/src/SharpCompress/Compressors/Rar/Decode/Decode.cs b/src/SharpCompress/Compressors/Rar/Decode/Decode.cs index 69039ffa..dc5dacee 100644 --- a/src/SharpCompress/Compressors/Rar/Decode/Decode.cs +++ b/src/SharpCompress/Compressors/Rar/Decode/Decode.cs @@ -17,17 +17,17 @@ namespace SharpCompress.Compressors.Rar.Decode ///

returns the decode Length array /// decodeLength /// - internal int[] DecodeLen { get; private set; } + internal int[] DecodeLen { get; } /// returns the decode num array /// decodeNum /// - internal int[] DecodeNum { get; private set; } + internal int[] DecodeNum { get; } /// returns the decodePos array /// decodePos /// - internal int[] DecodePos { get; private set; } + internal int[] DecodePos { get; } internal int MaxNum { get; set; } } diff --git a/src/SharpCompress/Compressors/Rar/VM/VMPreparedCommand.cs b/src/SharpCompress/Compressors/Rar/VM/VMPreparedCommand.cs index 0b985884..fc3238b5 100644 --- a/src/SharpCompress/Compressors/Rar/VM/VMPreparedCommand.cs +++ b/src/SharpCompress/Compressors/Rar/VM/VMPreparedCommand.cs @@ -10,8 +10,8 @@ namespace SharpCompress.Compressors.Rar.VM internal VMCommands OpCode { get; set; } internal bool IsByteMode { get; set; } - internal VMPreparedOperand Op1 { get; private set; } + internal VMPreparedOperand Op1 { get; } - internal VMPreparedOperand Op2 { get; private set; } + internal VMPreparedOperand Op2 { get; } } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/Rar/VM/VMStandardFilterSignature.cs b/src/SharpCompress/Compressors/Rar/VM/VMStandardFilterSignature.cs index 9a6cba31..a5812ed0 100644 --- a/src/SharpCompress/Compressors/Rar/VM/VMStandardFilterSignature.cs +++ b/src/SharpCompress/Compressors/Rar/VM/VMStandardFilterSignature.cs @@ -9,10 +9,10 @@ namespace SharpCompress.Compressors.Rar.VM Type = type; } - internal int Length { get; private set; } + internal int Length { get; } - internal uint CRC { get; private set; } + internal uint CRC { get; } - internal VMStandardFilters Type { get; private set; } + internal VMStandardFilters Type { get; } } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/ReaderProgress.cs b/src/SharpCompress/Readers/ReaderProgress.cs index 94feb74d..7b6f099d 100644 --- a/src/SharpCompress/Readers/ReaderProgress.cs +++ b/src/SharpCompress/Readers/ReaderProgress.cs @@ -8,8 +8,8 @@ namespace SharpCompress.Readers public class ReaderProgress { private readonly IEntry _entry; - public long BytesTransferred { get; private set; } - public int Iterations { get; private set; } + public long BytesTransferred { get; } + public int Iterations { get; } public int PercentageRead => (int)Math.Round(PercentageReadExact); public double PercentageReadExact => (float)BytesTransferred / _entry.Size * 100; From 6832918e71bb6e9ae85f631c36cb85ea5b134734 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 23 May 2017 16:21:07 +0100 Subject: [PATCH 42/49] Mark for 0.16.1 --- README.md | 5 +++++ src/SharpCompress/SharpCompress.csproj | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 797bb08c..ed11cef6 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,11 @@ I'm always looking for help or ideas. Please submit code or email with ideas. Un ## Version Log +### Version 0.16.1 + +* Fix [Preserve compression method when getting a compressed stream](https://github.com/adamhathcock/sharpcompress/pull/235) +* Fix [RAR entry key normalization fix](https://github.com/adamhathcock/sharpcompress/issues/201) + ### Version 0.16.0 * Breaking - [Progress Event Tracking rethink](https://github.com/adamhathcock/sharpcompress/pull/226) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 3313ed44..60c2e59a 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -3,9 +3,9 @@ SharpCompress - Pure C# Decompression/Compression en-US - 0.16.0 - 0.16.0.0 - 0.16.0.0 + 0.16.1 + 0.16.1.0 + 0.16.1.0 Adam Hathcock net45;net35;netstandard1.0;netstandard1.3 $(LibraryFrameworks) From be4a65e572da4be96cf3b18c4217ec25d80293a8 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Wed, 24 May 2017 08:52:12 +0100 Subject: [PATCH 43/49] update readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ed11cef6..742954e3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SharpCompress -SharpCompress is a compression library for .NET/Mono/Silverlight/WP7 that can unrar, un7zip, unzip, untar unbzip2 and ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip are implemented. +SharpCompress is a compression library in pure C# for .NET 3.5, 4.5, .NET Standard 1.0, 1.3 that can unrar, un7zip, unzip, untar unbzip2 and ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip are implemented. The major feature is support for non-seekable streams so large files can be processed on the fly (i.e. download stream). @@ -27,7 +27,6 @@ I'm always looking for help or ideas. Please submit code or email with ideas. Un * 7Zip writing * Zip64 (Need writing and extend Reading) * Multi-volume Zip support. -* RAR5 support ## Version Log From a193b2d3b1fc35f30a1e5421f6ba87ea0ed28809 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 29 May 2017 10:35:55 +0100 Subject: [PATCH 44/49] Add xplat build --- build.cake | 28 ++++++++++++++++++++++------ build.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100755 build.sh diff --git a/build.cake b/build.cake index ec985ac9..f205553d 100644 --- a/build.cake +++ b/build.cake @@ -17,17 +17,25 @@ Task("Build") }); Task("Test") + .IsDependentOn("Build") .Does(() => { - var files = GetFiles("tests/**/*.csproj"); - foreach(var file in files) + if (!bool.Parse(EnvironmentVariable("APPVEYOR") ?? "false")) { - var settings = new DotNetCoreTestSettings + var files = GetFiles("tests/**/*.csproj"); + foreach(var file in files) { - Configuration = "Release" - }; + var settings = new DotNetCoreTestSettings + { + Configuration = "Release" + }; - DotNetCoreTest(file.ToString(), settings); + DotNetCoreTest(file.ToString(), settings); + } + } + else + { + Information("Skipping tests as this is AppVeyor"); } }); @@ -35,17 +43,25 @@ Task("Pack") .IsDependentOn("Build") .Does(() => { + if (IsRunningOnWindows()) + { MSBuild("src/SharpCompress/SharpCompress.csproj", c => c .SetConfiguration("Release") .SetVerbosity(Verbosity.Minimal) .UseToolVersion(MSBuildToolVersion.VS2017) .WithProperty("NoBuild", "true") .WithTarget("Pack")); + } + else + { + Information("Skipping Pack as this is not Windows"); + } }); Task("Default") .IsDependentOn("Restore") .IsDependentOn("Build") + .IsDependentOn("Test") .IsDependentOn("Pack"); Task("RunTests") diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..9ed17711 --- /dev/null +++ b/build.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +########################################################################## +# This is the Cake bootstrapper script for Linux and OS X. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +# Define directories. +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +TOOLS_DIR=$SCRIPT_DIR/tools +CAKE_VERSION=0.19.1 +CAKE_DLL=$TOOLS_DIR/Cake.CoreCLR.$CAKE_VERSION/Cake.dll + +# Make sure the tools folder exist. +if [ ! -d "$TOOLS_DIR" ]; then + mkdir "$TOOLS_DIR" +fi + +########################################################################### +# INSTALL CAKE +########################################################################### + +if [ ! -f "$CAKE_DLL" ]; then + curl -Lsfo Cake.CoreCLR.zip "https://www.nuget.org/api/v2/package/Cake.CoreCLR/$CAKE_VERSION" && unzip -q Cake.CoreCLR.zip -d "$TOOLS_DIR/Cake.CoreCLR.$CAKE_VERSION" && rm -f Cake.CoreCLR.zip + if [ $? -ne 0 ]; then + echo "An error occured while installing Cake." + exit 1 + fi +fi + +# Make sure that Cake has been installed. +if [ ! -f "$CAKE_DLL" ]; then + echo "Could not find Cake.exe at '$CAKE_DLL'." + exit 1 +fi + +########################################################################### +# RUN BUILD SCRIPT +########################################################################### + +# Start Cake +exec dotnet "$CAKE_DLL" "$@" \ No newline at end of file From afa19f7ad8af54cb9ad9c0dbd6e214a3448d3faf Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 May 2017 12:35:12 +0100 Subject: [PATCH 45/49] Add xplat cake and travis build --- .travis.yml | 10 ++++++++++ build.cake | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..44d18bef --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +dist: trusty +language: csharp +solution: SharpCompress.sln +matrix: + include: + - dotnet: 1.0.4 + mono: none + env: DOTNETCORE=1 +script: + - ./build.sh \ No newline at end of file diff --git a/build.cake b/build.cake index f205553d..9bc24757 100644 --- a/build.cake +++ b/build.cake @@ -8,12 +8,44 @@ Task("Restore") }); Task("Build") + .IsDependentOn("Restore") .Does(() => { - MSBuild("./sharpcompress.sln", c => c - .SetConfiguration("Release") + if (IsRunningOnWindows()) + { + MSBuild("./sharpcompress.sln", c => + { + c.SetConfiguration("Release") .SetVerbosity(Verbosity.Minimal) - .UseToolVersion(MSBuildToolVersion.VS2017)); + .UseToolVersion(MSBuildToolVersion.VS2017); + }); + } + else + { + var settings = new DotNetCoreBuildSettings + { + Framework = "netstandard1.0", + Configuration = "Release" + }; + + DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings); + + settings = new DotNetCoreBuildSettings + { + Framework = "netstandard1.3", + Configuration = "Release" + }; + + DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings); + + settings = new DotNetCoreBuildSettings + { + Framework = "netcoreapp1.1", + Configuration = "Release" + }; + + DotNetCoreBuild("./tests/SharpCompress.Test/SharpCompress.Test.csproj", settings); + } }); Task("Test") From 296ebd942ae2f37f2f6180566ff56b2d37c76aff Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 May 2017 12:37:16 +0100 Subject: [PATCH 46/49] Shrink script a bit --- build.cake | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/build.cake b/build.cake index 9bc24757..58b05af5 100644 --- a/build.cake +++ b/build.cake @@ -29,21 +29,8 @@ Task("Build") }; DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings); - - settings = new DotNetCoreBuildSettings - { - Framework = "netstandard1.3", - Configuration = "Release" - }; - - DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings); - - settings = new DotNetCoreBuildSettings - { - Framework = "netcoreapp1.1", - Configuration = "Release" - }; + settings.Framework = "netcoreapp1.1"; DotNetCoreBuild("./tests/SharpCompress.Test/SharpCompress.Test.csproj", settings); } }); From c30bc6528193443cb1c56531ff10fc181e707541 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 May 2017 12:46:34 +0100 Subject: [PATCH 47/49] Don't run tests on travis either --- README.md | 4 ++++ build.cake | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 742954e3..9ff8f13e 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,12 @@ SharpCompress is a compression library in pure C# for .NET 3.5, 4.5, .NET Standa The major feature is support for non-seekable streams so large files can be processed on the fly (i.e. download stream). +AppVeyor Build - [![Build status](https://ci.appveyor.com/api/projects/status/voxg971oemmvxh1e/branch/master?svg=true)](https://ci.appveyor.com/project/adamhathcock/sharpcompress/branch/master) +Travis CI Build - +[![Build Status](https://travis-ci.org/adamhathcock/sharpcompress.svg?branch=master)](https://travis-ci.org/adamhathcock/sharpcompress) + ## Need Help? Post Issues on Github! diff --git a/build.cake b/build.cake index 58b05af5..3ef46189 100644 --- a/build.cake +++ b/build.cake @@ -39,7 +39,8 @@ Task("Test") .IsDependentOn("Build") .Does(() => { - if (!bool.Parse(EnvironmentVariable("APPVEYOR") ?? "false")) + if (!bool.Parse(EnvironmentVariable("APPVEYOR") ?? "false") + || !bool.Parse(EnvironmentVariable("TRAVIS") ?? "false")) { var files = GetFiles("tests/**/*.csproj"); foreach(var file in files) From 38766dac990c6a105559991c70711ce3b34b5ac1 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 May 2017 12:50:03 +0100 Subject: [PATCH 48/49] Wrong logic for skipping tests --- build.cake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.cake b/build.cake index 3ef46189..c1d19980 100644 --- a/build.cake +++ b/build.cake @@ -40,7 +40,7 @@ Task("Test") .Does(() => { if (!bool.Parse(EnvironmentVariable("APPVEYOR") ?? "false") - || !bool.Parse(EnvironmentVariable("TRAVIS") ?? "false")) + && !bool.Parse(EnvironmentVariable("TRAVIS") ?? "false")) { var files = GetFiles("tests/**/*.csproj"); foreach(var file in files) @@ -55,7 +55,7 @@ Task("Test") } else { - Information("Skipping tests as this is AppVeyor"); + Information("Skipping tests as this is AppVeyor or Travis CI"); } }); From a361d41e680923b9b3e74aee681d761f7617bb3d Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 May 2017 15:14:02 +0100 Subject: [PATCH 49/49] Fix test namespaces --- tests/SharpCompress.Test/GZip/GZipArchiveTests.cs | 2 +- tests/SharpCompress.Test/GZip/GZipWriterTests.cs | 2 +- tests/SharpCompress.Test/Rar/RarArchiveTests.cs | 2 +- tests/SharpCompress.Test/Rar/RarReaderTests.cs | 2 +- tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs | 5 ++--- tests/SharpCompress.Test/Tar/TarArchiveTests.cs | 5 ++--- tests/SharpCompress.Test/Tar/TarReaderTests.cs | 5 ++--- tests/SharpCompress.Test/Tar/TarWriterTests.cs | 2 +- tests/SharpCompress.Test/Zip/Zip64Tests.cs | 2 +- tests/SharpCompress.Test/Zip/ZipArchiveTests.cs | 5 ++--- tests/SharpCompress.Test/Zip/ZipReaderTests.cs | 2 +- tests/SharpCompress.Test/Zip/ZipWriterTests.cs | 2 +- 12 files changed, 16 insertions(+), 20 deletions(-) diff --git a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs index 7f6e43c6..ce8c98f9 100644 --- a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs +++ b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs @@ -5,7 +5,7 @@ using SharpCompress.Archives; using SharpCompress.Archives.GZip; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.GZip { public class GZipArchiveTests : ArchiveTests { diff --git a/tests/SharpCompress.Test/GZip/GZipWriterTests.cs b/tests/SharpCompress.Test/GZip/GZipWriterTests.cs index 368d8452..cbcf1d6a 100644 --- a/tests/SharpCompress.Test/GZip/GZipWriterTests.cs +++ b/tests/SharpCompress.Test/GZip/GZipWriterTests.cs @@ -4,7 +4,7 @@ using SharpCompress.Writers; using SharpCompress.Writers.GZip; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.GZip { public class GZipWriterTests : WriterTests { diff --git a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs index fa1c399f..87ac25b1 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs @@ -6,7 +6,7 @@ using SharpCompress.Common; using SharpCompress.Readers; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Rar { public class RarArchiveTests : ArchiveTests { diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index 53db8fd0..9dc0f24a 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -5,7 +5,7 @@ using SharpCompress.Readers; using SharpCompress.Readers.Rar; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Rar { public class RarReaderTests : ReaderTests { diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs index 59a8340d..4faf74af 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs @@ -1,9 +1,8 @@ - -using System; +using System; using SharpCompress.Common; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.SevenZip { public class SevenZipArchiveTests : ArchiveTests { diff --git a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs index cb34a873..e0cf73b4 100644 --- a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs +++ b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs @@ -1,5 +1,4 @@ - -using System.IO; +using System.IO; using System.Linq; using SharpCompress.Archives; using SharpCompress.Archives.Tar; @@ -7,7 +6,7 @@ using SharpCompress.Common; using SharpCompress.Writers; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Tar { public class TarArchiveTests : ArchiveTests { diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index 5529abfd..60b0171b 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; using System.IO; using SharpCompress.Common; -using Xunit; -using System.Linq; using SharpCompress.Readers; using SharpCompress.Readers.Tar; +using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Tar { public class TarReaderTests : ReaderTests { diff --git a/tests/SharpCompress.Test/Tar/TarWriterTests.cs b/tests/SharpCompress.Test/Tar/TarWriterTests.cs index c4f783bd..678829a8 100644 --- a/tests/SharpCompress.Test/Tar/TarWriterTests.cs +++ b/tests/SharpCompress.Test/Tar/TarWriterTests.cs @@ -1,7 +1,7 @@ using SharpCompress.Common; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Tar { public class TarWriterTests : WriterTests { diff --git a/tests/SharpCompress.Test/Zip/Zip64Tests.cs b/tests/SharpCompress.Test/Zip/Zip64Tests.cs index d1ce0545..07955304 100644 --- a/tests/SharpCompress.Test/Zip/Zip64Tests.cs +++ b/tests/SharpCompress.Test/Zip/Zip64Tests.cs @@ -9,7 +9,7 @@ using SharpCompress.Writers; using SharpCompress.Writers.Zip; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Zip { public class Zip64Tests : WriterTests { diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index ba045ec6..b0b26555 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.IO; using System.Linq; using System.Text; @@ -10,7 +9,7 @@ using SharpCompress.Readers; using SharpCompress.Writers; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Zip { public class ZipArchiveTests : ArchiveTests { diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs index 886e2c14..e766aa94 100644 --- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs @@ -6,7 +6,7 @@ using SharpCompress.Readers.Zip; using SharpCompress.Writers; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Zip { public class ZipReaderTests : ReaderTests { diff --git a/tests/SharpCompress.Test/Zip/ZipWriterTests.cs b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs index 413365a2..af29e5e5 100644 --- a/tests/SharpCompress.Test/Zip/ZipWriterTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipWriterTests.cs @@ -1,7 +1,7 @@ using SharpCompress.Common; using Xunit; -namespace SharpCompress.Test +namespace SharpCompress.Test.Zip { public class ZipWriterTests : WriterTests {